28
28
29
29
from setuptools .extern import packaging
30
30
from setuptools .extern import ordered_set
31
- from setuptools .extern .more_itertools import unique_everseen
31
+ from setuptools .extern .more_itertools import unique_everseen , always_iterable
32
+
33
+ from ._importlib import metadata
32
34
33
35
from . import SetuptoolsDeprecationWarning
34
36
38
40
from setuptools .monkey import get_unpatched
39
41
from setuptools .config import parse_configuration
40
42
import pkg_resources
41
- from setuptools .extern .packaging import version
43
+ from setuptools .extern .packaging import version , requirements
42
44
from . import _reqs
43
45
44
46
if TYPE_CHECKING :
@@ -450,7 +452,7 @@ def __init__(self, attrs=None):
450
452
self .patch_missing_pkg_info (attrs )
451
453
self .dependency_links = attrs .pop ('dependency_links' , [])
452
454
self .setup_requires = attrs .pop ('setup_requires' , [])
453
- for ep in pkg_resources . iter_entry_points ( 'distutils.setup_keywords' ):
455
+ for ep in metadata . entry_points ( group = 'distutils.setup_keywords' ):
454
456
vars (self ).setdefault (ep .name , None )
455
457
_Distribution .__init__ (
456
458
self ,
@@ -720,7 +722,10 @@ def warn_dash_deprecation(self, opt, section):
720
722
return opt
721
723
722
724
underscore_opt = opt .replace ('-' , '_' )
723
- commands = distutils .command .__all__ + self ._setuptools_commands ()
725
+ commands = list (itertools .chain (
726
+ distutils .command .__all__ ,
727
+ self ._setuptools_commands (),
728
+ ))
724
729
if (
725
730
not section .startswith ('options' )
726
731
and section != 'metadata'
@@ -738,9 +743,8 @@ def warn_dash_deprecation(self, opt, section):
738
743
739
744
def _setuptools_commands (self ):
740
745
try :
741
- dist = pkg_resources .get_distribution ('setuptools' )
742
- return list (dist .get_entry_map ('distutils.commands' ))
743
- except pkg_resources .DistributionNotFound :
746
+ return metadata .distribution ('setuptools' ).entry_points .names
747
+ except metadata .PackageNotFoundError :
744
748
# during bootstrapping, distribution doesn't exist
745
749
return []
746
750
@@ -839,7 +843,7 @@ def finalize_options(self):
839
843
def by_order (hook ):
840
844
return getattr (hook , 'order' , 0 )
841
845
842
- defined = pkg_resources . iter_entry_points ( group )
846
+ defined = metadata . entry_points ( group = group )
843
847
filtered = itertools .filterfalse (self ._removed , defined )
844
848
loaded = map (lambda e : e .load (), filtered )
845
849
for ep in sorted (loaded , key = by_order ):
@@ -860,12 +864,36 @@ def _removed(ep):
860
864
return ep .name in removed
861
865
862
866
def _finalize_setup_keywords (self ):
863
- for ep in pkg_resources . iter_entry_points ( 'distutils.setup_keywords' ):
867
+ for ep in metadata . entry_points ( group = 'distutils.setup_keywords' ):
864
868
value = getattr (self , ep .name , None )
865
869
if value is not None :
866
- ep . require ( installer = self .fetch_build_egg )
870
+ self ._install_dependencies ( ep )
867
871
ep .load ()(self , ep .name , value )
868
872
873
+ def _install_dependencies (self , ep ):
874
+ """
875
+ Given an entry point, ensure that any declared extras for
876
+ its distribution are installed.
877
+ """
878
+ reqs = {
879
+ req
880
+ for req in map (requirements .Requirement , always_iterable (ep .dist .requires ))
881
+ for extra in ep .extras
882
+ if extra in req .extras
883
+ }
884
+ missing = itertools .filterfalse (self ._is_installed , reqs )
885
+ for req in missing :
886
+ # fetch_build_egg expects pkg_resources.Requirement
887
+ self .fetch_build_egg (pkg_resources .Requirement (str (req )))
888
+
889
+ def _is_installed (self , req ):
890
+ try :
891
+ dist = metadata .distribution (req .name )
892
+ except metadata .PackageNotFoundError :
893
+ return False
894
+ found_ver = packaging .version .Version (dist .version ())
895
+ return found_ver in req .specifier
896
+
869
897
def get_egg_cache_dir (self ):
870
898
egg_cache_dir = os .path .join (os .curdir , '.eggs' )
871
899
if not os .path .exists (egg_cache_dir ):
@@ -896,27 +924,25 @@ def get_command_class(self, command):
896
924
if command in self .cmdclass :
897
925
return self .cmdclass [command ]
898
926
899
- eps = pkg_resources . iter_entry_points ( 'distutils.commands' , command )
927
+ eps = metadata . entry_points ( group = 'distutils.commands' , name = command )
900
928
for ep in eps :
901
- ep . require ( installer = self .fetch_build_egg )
929
+ self ._install_dependencies ( ep )
902
930
self .cmdclass [command ] = cmdclass = ep .load ()
903
931
return cmdclass
904
932
else :
905
933
return _Distribution .get_command_class (self , command )
906
934
907
935
def print_commands (self ):
908
- for ep in pkg_resources . iter_entry_points ( 'distutils.commands' ):
936
+ for ep in metadata . entry_points ( group = 'distutils.commands' ):
909
937
if ep .name not in self .cmdclass :
910
- # don't require extras as the commands won't be invoked
911
- cmdclass = ep .resolve ()
938
+ cmdclass = ep .load ()
912
939
self .cmdclass [ep .name ] = cmdclass
913
940
return _Distribution .print_commands (self )
914
941
915
942
def get_command_list (self ):
916
- for ep in pkg_resources . iter_entry_points ( 'distutils.commands' ):
943
+ for ep in metadata . entry_points ( group = 'distutils.commands' ):
917
944
if ep .name not in self .cmdclass :
918
- # don't require extras as the commands won't be invoked
919
- cmdclass = ep .resolve ()
945
+ cmdclass = ep .load ()
920
946
self .cmdclass [ep .name ] = cmdclass
921
947
return _Distribution .get_command_list (self )
922
948
0 commit comments