88import copy
99from fnmatch import fnmatch
1010import functools
11+ import importlib .metadata
12+ import importlib .util
1113import logging
1214import operator
1315import os
1416import os .path
1517from pathlib import Path
18+ import packaging .requirements
1619import re
1720import shlex
1821import shutil
1922import subprocess
2023import sys
2124import tempfile
22- from typing import List
2325import urllib .request
2426import venv
2527
26-
2728THIS_SCRIPT_DIR = Path (__file__ ).resolve ().parent
2829DEFAULT_RE_EXTRACT_VERSION = "([0-9]+\\ .[0-9]+(\\ .[0-9]+)?[ab]?)"
2930
@@ -36,22 +37,31 @@ def forget_python_pkg(package):
3637 Args:
3738 package: name of the Python package to exclude
3839 """
39- import pkg_resources
40-
41- try :
42- dist = pkg_resources .get_distribution (package )
43- except pkg_resources .DistributionNotFound :
44- return
40+ dist_location = None
41+ dist = importlib .metadata .distribution (package )
42+ if dist .files :
43+ # Get the parent directory of the first file in the distribution
44+ first_file = next (iter (dist .files ))
45+ dist_location = str (first_file .locate ().parent .parent )
46+ else :
47+ # Fallback: try to get location from sys.path and package name
48+ try :
49+ spec = importlib .util .find_spec (package )
50+ if spec and spec .origin :
51+ # Get the parent directory containing the package
52+ dist_location = Path (spec .origin ).parent .parent
53+ except AttributeError :
54+ pass
4555 PYTHONPATH = os .environ .get ("PYTHONPATH" )
46- if PYTHONPATH is not None and dist . location in PYTHONPATH :
56+ if PYTHONPATH is not None and dist_location in PYTHONPATH :
4757 logging .debug (
4858 "Remove incompatible version of %s in PYTHONPATH: %s" ,
4959 package ,
50- dist . location ,
60+ dist_location ,
5161 )
52- os .environ ["PYTHONPATH" ] = PYTHONPATH .replace (dist . location , "" )
62+ os .environ ["PYTHONPATH" ] = PYTHONPATH .replace (dist_location , "" )
5363 try :
54- sys .path .remove (dist . location )
64+ sys .path .remove (dist_location )
5565 except ValueError :
5666 pass
5767
@@ -300,7 +310,7 @@ def interpreter(self) -> str:
300310 """
301311 return self .bin_dir .joinpath ("python" )
302312
303- def pip_cmd (self , * args ) -> List [str ]:
313+ def pip_cmd (self , * args ) -> list [str ]:
304314 """
305315 Execute a pip command
306316
@@ -393,16 +403,22 @@ def is_requirement_met(self, requirement) -> bool:
393403 False otherwise
394404 """
395405 try :
396- import pkg_resources
406+ # Parse the requirement string
407+ req = packaging .requirements .Requirement (str (requirement ))
408+
409+ # Check if the package is installed
410+ try :
411+ dist = importlib .metadata .distribution (req .name )
412+ except importlib .metadata .PackageNotFoundError :
413+ return False
414+
415+ # Check if the version satisfies the requirement
416+ if req .specifier and not req .specifier .contains (dist .version ):
417+ return False
397418
398- pkg_resources .require (str (requirement ))
399419 return True
400- except ImportError :
401- self ._install_requirement ("setuptools" , restart = True )
402- except pkg_resources .ContextualVersionConflict as conflict :
403- forget_python_pkg (conflict .req .name )
404- return False
405- except (pkg_resources .VersionConflict , pkg_resources .DistributionNotFound ):
420+ except Exception :
421+ # Handle any parsing or version checking errors
406422 return False
407423
408424 def ensure_requirement (self , requirement , restart = True ):
@@ -542,9 +558,8 @@ def requirement(self):
542558 name = pip_pkg
543559 else :
544560 name = self .name
545- import pkg_resources
546561
547- return pkg_resources . Requirement . parse (f"{ name } { self .user_config ['version' ]} " )
562+ return packaging . requirements . Requirement (f"{ name } { self .user_config ['version' ]} " )
548563
549564 @abc .abstractmethod
550565 def configure (self ):
@@ -813,9 +828,8 @@ def find_version(self, path: str) -> str:
813828 pkg_name = self .name
814829 if isinstance (self .config ["capabilities" ].pip_pkg , str ):
815830 pkg_name = self .config ["capabilities" ].pip_pkg
816- import pkg_resources
817831
818- return pkg_resources . get_distribution (pkg_name ). version
832+ return importlib . metadata . version (pkg_name )
819833
820834 cmd = [path ] + self ._config ["version_opt" ]
821835 log_command (cmd )
0 commit comments