1919from collections import defaultdict
2020from email import message_from_file
2121
22- from distutils .errors import (
23- DistutilsOptionError , DistutilsPlatformError , DistutilsSetupError ,
24- )
22+ from distutils .errors import DistutilsOptionError , DistutilsSetupError
2523from distutils .util import rfc822_escape
2624from distutils .version import StrictVersion
2725
3230
3331from . import SetuptoolsDeprecationWarning
3432
35- from setuptools .depends import Require
3633from setuptools import windows_support
3734from setuptools .monkey import get_unpatched
3835from setuptools .config import parse_configuration
@@ -338,7 +335,7 @@ def check_packages(dist, attr, value):
338335
339336
340337class Distribution (_Distribution ):
341- """Distribution with support for features, tests, and package data
338+ """Distribution with support for tests and package data
342339
343340 This is an enhanced version of 'distutils.dist.Distribution' that
344341 effectively adds the following new optional keyword arguments to 'setup()':
@@ -365,21 +362,6 @@ class Distribution(_Distribution):
365362 EasyInstall and requests one of your extras, the corresponding
366363 additional requirements will be installed if needed.
367364
368- 'features' **deprecated** -- a dictionary mapping option names to
369- 'setuptools.Feature'
370- objects. Features are a portion of the distribution that can be
371- included or excluded based on user options, inter-feature dependencies,
372- and availability on the current system. Excluded features are omitted
373- from all setup commands, including source and binary distributions, so
374- you can create multiple distributions from the same source tree.
375- Feature names should be valid Python identifiers, except that they may
376- contain the '-' (minus) sign. Features can be included or excluded
377- via the command line options '--with-X' and '--without-X', where 'X' is
378- the name of the feature. Whether a feature is included by default, and
379- whether you are allowed to control this from the command line, is
380- determined by the Feature object. See the 'Feature' class for more
381- information.
382-
383365 'test_suite' -- the name of a test suite to run for the 'test' command.
384366 If the user runs 'python setup.py test', the package will be installed,
385367 and the named test suite will be run. The format is the same as
@@ -401,8 +383,7 @@ class Distribution(_Distribution):
401383 for manipulating the distribution's contents. For example, the 'include()'
402384 and 'exclude()' methods can be thought of as in-place add and subtract
403385 commands that add or remove packages, modules, extensions, and so on from
404- the distribution. They are used by the feature subsystem to configure the
405- distribution for the included and excluded features.
386+ the distribution.
406387 """
407388
408389 _DISTUTILS_UNSUPPORTED_METADATA = {
@@ -432,10 +413,6 @@ def __init__(self, attrs=None):
432413 if not have_package_data :
433414 self .package_data = {}
434415 attrs = attrs or {}
435- if 'features' in attrs or 'require_features' in attrs :
436- Feature .warn_deprecated ()
437- self .require_features = []
438- self .features = {}
439416 self .dist_files = []
440417 # Filter-out setuptools' specific options.
441418 self .src_root = attrs .pop ("src_root" , None )
@@ -702,17 +679,6 @@ def parse_config_files(self, filenames=None, ignore_option_errors=False):
702679 ignore_option_errors = ignore_option_errors )
703680 self ._finalize_requires ()
704681
705- def parse_command_line (self ):
706- """Process features after parsing command line options"""
707- result = _Distribution .parse_command_line (self )
708- if self .features :
709- self ._finalize_features ()
710- return result
711-
712- def _feature_attrname (self , name ):
713- """Convert feature name to corresponding option attribute name"""
714- return 'with_' + name .replace ('-' , '_' )
715-
716682 def fetch_build_eggs (self , requires ):
717683 """Resolve pre-setup requirements"""
718684 resolved_dists = pkg_resources .working_set .resolve (
@@ -776,53 +742,6 @@ def fetch_build_egg(self, req):
776742 from setuptools .installer import fetch_build_egg
777743 return fetch_build_egg (self , req )
778744
779- def _finalize_feature_opts (self ):
780- """Add --with-X/--without-X options based on optional features"""
781-
782- if not self .features :
783- return
784-
785- go = []
786- no = self .negative_opt .copy ()
787-
788- for name , feature in self .features .items ():
789- self ._set_feature (name , None )
790- feature .validate (self )
791-
792- if feature .optional :
793- descr = feature .description
794- incdef = ' (default)'
795- excdef = ''
796- if not feature .include_by_default ():
797- excdef , incdef = incdef , excdef
798-
799- new = (
800- ('with-' + name , None , 'include ' + descr + incdef ),
801- ('without-' + name , None , 'exclude ' + descr + excdef ),
802- )
803- go .extend (new )
804- no ['without-' + name ] = 'with-' + name
805-
806- self .global_options = self .feature_options = go + self .global_options
807- self .negative_opt = self .feature_negopt = no
808-
809- def _finalize_features (self ):
810- """Add/remove features and resolve dependencies between them"""
811-
812- # First, flag all the enabled items (and thus their dependencies)
813- for name , feature in self .features .items ():
814- enabled = self .feature_is_included (name )
815- if enabled or (enabled is None and feature .include_by_default ()):
816- feature .include_in (self )
817- self ._set_feature (name , 1 )
818-
819- # Then disable the rest, so that off-by-default features don't
820- # get flagged as errors when they're required by an enabled feature
821- for name , feature in self .features .items ():
822- if not self .feature_is_included (name ):
823- feature .exclude_from (self )
824- self ._set_feature (name , 0 )
825-
826745 def get_command_class (self , command ):
827746 """Pluggable version of get_command_class()"""
828747 if command in self .cmdclass :
@@ -852,25 +771,6 @@ def get_command_list(self):
852771 self .cmdclass [ep .name ] = cmdclass
853772 return _Distribution .get_command_list (self )
854773
855- def _set_feature (self , name , status ):
856- """Set feature's inclusion status"""
857- setattr (self , self ._feature_attrname (name ), status )
858-
859- def feature_is_included (self , name ):
860- """Return 1 if feature is included, 0 if excluded, 'None' if unknown"""
861- return getattr (self , self ._feature_attrname (name ))
862-
863- def include_feature (self , name ):
864- """Request inclusion of feature named 'name'"""
865-
866- if self .feature_is_included (name ) == 0 :
867- descr = self .features [name ].description
868- raise DistutilsOptionError (
869- descr + " is required, but was excluded or is not available"
870- )
871- self .features [name ].include_in (self )
872- self ._set_feature (name , 1 )
873-
874774 def include (self , ** attrs ):
875775 """Add items to distribution that are named in keyword arguments
876776
@@ -1115,160 +1015,6 @@ def handle_display_options(self, option_order):
11151015 sys .stdout .detach (), encoding , errors , newline , line_buffering )
11161016
11171017
1118- class Feature :
1119- """
1120- **deprecated** -- The `Feature` facility was never completely implemented
1121- or supported, `has reported issues
1122- <https://github.com/pypa/setuptools/issues/58>`_ and will be removed in
1123- a future version.
1124-
1125- A subset of the distribution that can be excluded if unneeded/wanted
1126-
1127- Features are created using these keyword arguments:
1128-
1129- 'description' -- a short, human readable description of the feature, to
1130- be used in error messages, and option help messages.
1131-
1132- 'standard' -- if true, the feature is included by default if it is
1133- available on the current system. Otherwise, the feature is only
1134- included if requested via a command line '--with-X' option, or if
1135- another included feature requires it. The default setting is 'False'.
1136-
1137- 'available' -- if true, the feature is available for installation on the
1138- current system. The default setting is 'True'.
1139-
1140- 'optional' -- if true, the feature's inclusion can be controlled from the
1141- command line, using the '--with-X' or '--without-X' options. If
1142- false, the feature's inclusion status is determined automatically,
1143- based on 'availabile', 'standard', and whether any other feature
1144- requires it. The default setting is 'True'.
1145-
1146- 'require_features' -- a string or sequence of strings naming features
1147- that should also be included if this feature is included. Defaults to
1148- empty list. May also contain 'Require' objects that should be
1149- added/removed from the distribution.
1150-
1151- 'remove' -- a string or list of strings naming packages to be removed
1152- from the distribution if this feature is *not* included. If the
1153- feature *is* included, this argument is ignored. This argument exists
1154- to support removing features that "crosscut" a distribution, such as
1155- defining a 'tests' feature that removes all the 'tests' subpackages
1156- provided by other features. The default for this argument is an empty
1157- list. (Note: the named package(s) or modules must exist in the base
1158- distribution when the 'setup()' function is initially called.)
1159-
1160- other keywords -- any other keyword arguments are saved, and passed to
1161- the distribution's 'include()' and 'exclude()' methods when the
1162- feature is included or excluded, respectively. So, for example, you
1163- could pass 'packages=["a","b"]' to cause packages 'a' and 'b' to be
1164- added or removed from the distribution as appropriate.
1165-
1166- A feature must include at least one 'requires', 'remove', or other
1167- keyword argument. Otherwise, it can't affect the distribution in any way.
1168- Note also that you can subclass 'Feature' to create your own specialized
1169- feature types that modify the distribution in other ways when included or
1170- excluded. See the docstrings for the various methods here for more detail.
1171- Aside from the methods, the only feature attributes that distributions look
1172- at are 'description' and 'optional'.
1173- """
1174-
1175- @staticmethod
1176- def warn_deprecated ():
1177- msg = (
1178- "Features are deprecated and will be removed in a future "
1179- "version. See https://github.com/pypa/setuptools/issues/65."
1180- )
1181- warnings .warn (msg , DistDeprecationWarning , stacklevel = 3 )
1182-
1183- def __init__ (
1184- self , description , standard = False , available = True ,
1185- optional = True , require_features = (), remove = (), ** extras ):
1186- self .warn_deprecated ()
1187-
1188- self .description = description
1189- self .standard = standard
1190- self .available = available
1191- self .optional = optional
1192- if isinstance (require_features , (str , Require )):
1193- require_features = require_features ,
1194-
1195- self .require_features = [
1196- r for r in require_features if isinstance (r , str )
1197- ]
1198- er = [r for r in require_features if not isinstance (r , str )]
1199- if er :
1200- extras ['require_features' ] = er
1201-
1202- if isinstance (remove , str ):
1203- remove = remove ,
1204- self .remove = remove
1205- self .extras = extras
1206-
1207- if not remove and not require_features and not extras :
1208- raise DistutilsSetupError (
1209- "Feature %s: must define 'require_features', 'remove', or "
1210- "at least one of 'packages', 'py_modules', etc."
1211- )
1212-
1213- def include_by_default (self ):
1214- """Should this feature be included by default?"""
1215- return self .available and self .standard
1216-
1217- def include_in (self , dist ):
1218- """Ensure feature and its requirements are included in distribution
1219-
1220- You may override this in a subclass to perform additional operations on
1221- the distribution. Note that this method may be called more than once
1222- per feature, and so should be idempotent.
1223-
1224- """
1225-
1226- if not self .available :
1227- raise DistutilsPlatformError (
1228- self .description + " is required, "
1229- "but is not available on this platform"
1230- )
1231-
1232- dist .include (** self .extras )
1233-
1234- for f in self .require_features :
1235- dist .include_feature (f )
1236-
1237- def exclude_from (self , dist ):
1238- """Ensure feature is excluded from distribution
1239-
1240- You may override this in a subclass to perform additional operations on
1241- the distribution. This method will be called at most once per
1242- feature, and only after all included features have been asked to
1243- include themselves.
1244- """
1245-
1246- dist .exclude (** self .extras )
1247-
1248- if self .remove :
1249- for item in self .remove :
1250- dist .exclude_package (item )
1251-
1252- def validate (self , dist ):
1253- """Verify that feature makes sense in context of distribution
1254-
1255- This method is called by the distribution just before it parses its
1256- command line. It checks to ensure that the 'remove' attribute, if any,
1257- contains only valid package/module names that are present in the base
1258- distribution when 'setup()' is called. You may override it in a
1259- subclass to perform any other required validation of the feature
1260- against a target distribution.
1261- """
1262-
1263- for item in self .remove :
1264- if not dist .has_contents_for (item ):
1265- raise DistutilsSetupError (
1266- "%s wants to be able to remove %s, but the distribution"
1267- " doesn't contain any packages or modules under %s"
1268- % (self .description , item , item )
1269- )
1270-
1271-
12721018class DistDeprecationWarning (SetuptoolsDeprecationWarning ):
12731019 """Class for warning about deprecations in dist in
12741020 setuptools. Not ignored by default, unlike DeprecationWarning."""
0 commit comments