Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/setuptools/dist.py
7763 views
# -*- coding: utf-8 -*-1__all__ = ['Distribution']23import io4import sys5import re6import os7import warnings8import numbers9import distutils.log10import distutils.core11import distutils.cmd12import distutils.dist13from distutils.util import strtobool14from distutils.debug import DEBUG15from distutils.fancy_getopt import translate_longopt16import itertools1718from collections import defaultdict19from email import message_from_file2021from distutils.errors import DistutilsOptionError, DistutilsSetupError22from distutils.util import rfc822_escape23from distutils.version import StrictVersion2425from setuptools.extern import six26from setuptools.extern import packaging27from setuptools.extern import ordered_set28from setuptools.extern.six.moves import map, filter, filterfalse2930from . import SetuptoolsDeprecationWarning3132import setuptools33from setuptools import windows_support34from setuptools.monkey import get_unpatched35from setuptools.config import parse_configuration36import pkg_resources3738__import__('setuptools.extern.packaging.specifiers')39__import__('setuptools.extern.packaging.version')404142def _get_unpatched(cls):43warnings.warn("Do not call this function", DistDeprecationWarning)44return get_unpatched(cls)454647def get_metadata_version(self):48mv = getattr(self, 'metadata_version', None)4950if mv is None:51if self.long_description_content_type or self.provides_extras:52mv = StrictVersion('2.1')53elif (self.maintainer is not None or54self.maintainer_email is not None or55getattr(self, 'python_requires', None) is not None or56self.project_urls):57mv = StrictVersion('1.2')58elif (self.provides or self.requires or self.obsoletes or59self.classifiers or self.download_url):60mv = StrictVersion('1.1')61else:62mv = StrictVersion('1.0')6364self.metadata_version = mv6566return mv676869def read_pkg_file(self, file):70"""Reads the metadata values from a file object."""71msg = message_from_file(file)7273def _read_field(name):74value = msg[name]75if value == 'UNKNOWN':76return None77return value7879def _read_list(name):80values = msg.get_all(name, None)81if values == []:82return None83return values8485self.metadata_version = StrictVersion(msg['metadata-version'])86self.name = _read_field('name')87self.version = _read_field('version')88self.description = _read_field('summary')89# we are filling author only.90self.author = _read_field('author')91self.maintainer = None92self.author_email = _read_field('author-email')93self.maintainer_email = None94self.url = _read_field('home-page')95self.license = _read_field('license')9697if 'download-url' in msg:98self.download_url = _read_field('download-url')99else:100self.download_url = None101102self.long_description = _read_field('description')103self.description = _read_field('summary')104105if 'keywords' in msg:106self.keywords = _read_field('keywords').split(',')107108self.platforms = _read_list('platform')109self.classifiers = _read_list('classifier')110111# PEP 314 - these fields only exist in 1.1112if self.metadata_version == StrictVersion('1.1'):113self.requires = _read_list('requires')114self.provides = _read_list('provides')115self.obsoletes = _read_list('obsoletes')116else:117self.requires = None118self.provides = None119self.obsoletes = None120121122# Based on Python 3.5 version123def write_pkg_file(self, file):124"""Write the PKG-INFO format data to a file object.125"""126version = self.get_metadata_version()127128if six.PY2:129def write_field(key, value):130file.write("%s: %s\n" % (key, self._encode_field(value)))131else:132def write_field(key, value):133file.write("%s: %s\n" % (key, value))134135write_field('Metadata-Version', str(version))136write_field('Name', self.get_name())137write_field('Version', self.get_version())138write_field('Summary', self.get_description())139write_field('Home-page', self.get_url())140141if version < StrictVersion('1.2'):142write_field('Author', self.get_contact())143write_field('Author-email', self.get_contact_email())144else:145optional_fields = (146('Author', 'author'),147('Author-email', 'author_email'),148('Maintainer', 'maintainer'),149('Maintainer-email', 'maintainer_email'),150)151152for field, attr in optional_fields:153attr_val = getattr(self, attr)154155if attr_val is not None:156write_field(field, attr_val)157158write_field('License', self.get_license())159if self.download_url:160write_field('Download-URL', self.download_url)161for project_url in self.project_urls.items():162write_field('Project-URL', '%s, %s' % project_url)163164long_desc = rfc822_escape(self.get_long_description())165write_field('Description', long_desc)166167keywords = ','.join(self.get_keywords())168if keywords:169write_field('Keywords', keywords)170171if version >= StrictVersion('1.2'):172for platform in self.get_platforms():173write_field('Platform', platform)174else:175self._write_list(file, 'Platform', self.get_platforms())176177self._write_list(file, 'Classifier', self.get_classifiers())178179# PEP 314180self._write_list(file, 'Requires', self.get_requires())181self._write_list(file, 'Provides', self.get_provides())182self._write_list(file, 'Obsoletes', self.get_obsoletes())183184# Setuptools specific for PEP 345185if hasattr(self, 'python_requires'):186write_field('Requires-Python', self.python_requires)187188# PEP 566189if self.long_description_content_type:190write_field(191'Description-Content-Type',192self.long_description_content_type193)194if self.provides_extras:195for extra in self.provides_extras:196write_field('Provides-Extra', extra)197198199sequence = tuple, list200201202def check_importable(dist, attr, value):203try:204ep = pkg_resources.EntryPoint.parse('x=' + value)205assert not ep.extras206except (TypeError, ValueError, AttributeError, AssertionError) as e:207raise DistutilsSetupError(208"%r must be importable 'module:attrs' string (got %r)"209% (attr, value)210) from e211212213def assert_string_list(dist, attr, value):214"""Verify that value is a string list"""215try:216# verify that value is a list or tuple to exclude unordered217# or single-use iterables218assert isinstance(value, (list, tuple))219# verify that elements of value are strings220assert ''.join(value) != value221except (TypeError, ValueError, AttributeError, AssertionError) as e:222raise DistutilsSetupError(223"%r must be a list of strings (got %r)" % (attr, value)224) from e225226227def check_nsp(dist, attr, value):228"""Verify that namespace packages are valid"""229ns_packages = value230assert_string_list(dist, attr, ns_packages)231for nsp in ns_packages:232if not dist.has_contents_for(nsp):233raise DistutilsSetupError(234"Distribution contains no modules or packages for " +235"namespace package %r" % nsp236)237parent, sep, child = nsp.rpartition('.')238if parent and parent not in ns_packages:239distutils.log.warn(240"WARNING: %r is declared as a package namespace, but %r"241" is not: please correct this in setup.py", nsp, parent242)243244245def check_extras(dist, attr, value):246"""Verify that extras_require mapping is valid"""247try:248list(itertools.starmap(_check_extra, value.items()))249except (TypeError, ValueError, AttributeError) as e:250raise DistutilsSetupError(251"'extras_require' must be a dictionary whose values are "252"strings or lists of strings containing valid project/version "253"requirement specifiers."254) from e255256257def _check_extra(extra, reqs):258name, sep, marker = extra.partition(':')259if marker and pkg_resources.invalid_marker(marker):260raise DistutilsSetupError("Invalid environment marker: " + marker)261list(pkg_resources.parse_requirements(reqs))262263264def assert_bool(dist, attr, value):265"""Verify that value is True, False, 0, or 1"""266if bool(value) != value:267tmpl = "{attr!r} must be a boolean value (got {value!r})"268raise DistutilsSetupError(tmpl.format(attr=attr, value=value))269270271def check_requirements(dist, attr, value):272"""Verify that install_requires is a valid requirements list"""273try:274list(pkg_resources.parse_requirements(value))275if isinstance(value, (dict, set)):276raise TypeError("Unordered types are not allowed")277except (TypeError, ValueError) as error:278tmpl = (279"{attr!r} must be a string or list of strings "280"containing valid project/version requirement specifiers; {error}"281)282raise DistutilsSetupError(283tmpl.format(attr=attr, error=error)284) from error285286287def check_specifier(dist, attr, value):288"""Verify that value is a valid version specifier"""289try:290packaging.specifiers.SpecifierSet(value)291except packaging.specifiers.InvalidSpecifier as error:292tmpl = (293"{attr!r} must be a string "294"containing valid version specifiers; {error}"295)296raise DistutilsSetupError(297tmpl.format(attr=attr, error=error)298) from error299300301def check_entry_points(dist, attr, value):302"""Verify that entry_points map is parseable"""303try:304pkg_resources.EntryPoint.parse_map(value)305except ValueError as e:306raise DistutilsSetupError(e) from e307308309def check_test_suite(dist, attr, value):310if not isinstance(value, six.string_types):311raise DistutilsSetupError("test_suite must be a string")312313314def check_package_data(dist, attr, value):315"""Verify that value is a dictionary of package names to glob lists"""316if not isinstance(value, dict):317raise DistutilsSetupError(318"{!r} must be a dictionary mapping package names to lists of "319"string wildcard patterns".format(attr))320for k, v in value.items():321if not isinstance(k, six.string_types):322raise DistutilsSetupError(323"keys of {!r} dict must be strings (got {!r})"324.format(attr, k)325)326assert_string_list(dist, 'values of {!r} dict'.format(attr), v)327328329def check_packages(dist, attr, value):330for pkgname in value:331if not re.match(r'\w+(\.\w+)*', pkgname):332distutils.log.warn(333"WARNING: %r not a valid package name; please use only "334".-separated package names in setup.py", pkgname335)336337338_Distribution = get_unpatched(distutils.core.Distribution)339340341class Distribution(_Distribution):342"""Distribution with support for tests and package data343344This is an enhanced version of 'distutils.dist.Distribution' that345effectively adds the following new optional keyword arguments to 'setup()':346347'install_requires' -- a string or sequence of strings specifying project348versions that the distribution requires when installed, in the format349used by 'pkg_resources.require()'. They will be installed350automatically when the package is installed. If you wish to use351packages that are not available in PyPI, or want to give your users an352alternate download location, you can add a 'find_links' option to the353'[easy_install]' section of your project's 'setup.cfg' file, and then354setuptools will scan the listed web pages for links that satisfy the355requirements.356357'extras_require' -- a dictionary mapping names of optional "extras" to the358additional requirement(s) that using those extras incurs. For example,359this::360361extras_require = dict(reST = ["docutils>=0.3", "reSTedit"])362363indicates that the distribution can optionally provide an extra364capability called "reST", but it can only be used if docutils and365reSTedit are installed. If the user installs your package using366EasyInstall and requests one of your extras, the corresponding367additional requirements will be installed if needed.368369'test_suite' -- the name of a test suite to run for the 'test' command.370If the user runs 'python setup.py test', the package will be installed,371and the named test suite will be run. The format is the same as372would be used on a 'unittest.py' command line. That is, it is the373dotted name of an object to import and call to generate a test suite.374375'package_data' -- a dictionary mapping package names to lists of filenames376or globs to use to find data files contained in the named packages.377If the dictionary has filenames or globs listed under '""' (the empty378string), those names will be searched for in every package, in addition379to any names for the specific package. Data files found using these380names/globs will be installed along with the package, in the same381location as the package. Note that globs are allowed to reference382the contents of non-package subdirectories, as long as you use '/' as383a path separator. (Globs are automatically converted to384platform-specific paths at runtime.)385386In addition to these new keywords, this class also has several new methods387for manipulating the distribution's contents. For example, the 'include()'388and 'exclude()' methods can be thought of as in-place add and subtract389commands that add or remove packages, modules, extensions, and so on from390the distribution.391"""392393_DISTUTILS_UNSUPPORTED_METADATA = {394'long_description_content_type': None,395'project_urls': dict,396'provides_extras': ordered_set.OrderedSet,397'license_files': ordered_set.OrderedSet,398}399400_patched_dist = None401402def patch_missing_pkg_info(self, attrs):403# Fake up a replacement for the data that would normally come from404# PKG-INFO, but which might not yet be built if this is a fresh405# checkout.406#407if not attrs or 'name' not in attrs or 'version' not in attrs:408return409key = pkg_resources.safe_name(str(attrs['name'])).lower()410dist = pkg_resources.working_set.by_key.get(key)411if dist is not None and not dist.has_metadata('PKG-INFO'):412dist._version = pkg_resources.safe_version(str(attrs['version']))413self._patched_dist = dist414415def __init__(self, attrs=None):416have_package_data = hasattr(self, "package_data")417if not have_package_data:418self.package_data = {}419attrs = attrs or {}420self.dist_files = []421# Filter-out setuptools' specific options.422self.src_root = attrs.pop("src_root", None)423self.patch_missing_pkg_info(attrs)424self.dependency_links = attrs.pop('dependency_links', [])425self.setup_requires = attrs.pop('setup_requires', [])426for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):427vars(self).setdefault(ep.name, None)428_Distribution.__init__(self, {429k: v for k, v in attrs.items()430if k not in self._DISTUTILS_UNSUPPORTED_METADATA431})432433# Fill-in missing metadata fields not supported by distutils.434# Note some fields may have been set by other tools (e.g. pbr)435# above; they are taken preferrentially to setup() arguments436for option, default in self._DISTUTILS_UNSUPPORTED_METADATA.items():437for source in self.metadata.__dict__, attrs:438if option in source:439value = source[option]440break441else:442value = default() if default else None443setattr(self.metadata, option, value)444445self.metadata.version = self._normalize_version(446self._validate_version(self.metadata.version))447self._finalize_requires()448449@staticmethod450def _normalize_version(version):451if isinstance(version, setuptools.sic) or version is None:452return version453454normalized = str(packaging.version.Version(version))455if version != normalized:456tmpl = "Normalizing '{version}' to '{normalized}'"457warnings.warn(tmpl.format(**locals()))458return normalized459return version460461@staticmethod462def _validate_version(version):463if isinstance(version, numbers.Number):464# Some people apparently take "version number" too literally :)465version = str(version)466467if version is not None:468try:469packaging.version.Version(version)470except (packaging.version.InvalidVersion, TypeError):471warnings.warn(472"The version specified (%r) is an invalid version, this "473"may not work as expected with newer versions of "474"setuptools, pip, and PyPI. Please see PEP 440 for more "475"details." % version476)477return setuptools.sic(version)478return version479480def _finalize_requires(self):481"""482Set `metadata.python_requires` and fix environment markers483in `install_requires` and `extras_require`.484"""485if getattr(self, 'python_requires', None):486self.metadata.python_requires = self.python_requires487488if getattr(self, 'extras_require', None):489for extra in self.extras_require.keys():490# Since this gets called multiple times at points where the491# keys have become 'converted' extras, ensure that we are only492# truly adding extras we haven't seen before here.493extra = extra.split(':')[0]494if extra:495self.metadata.provides_extras.add(extra)496497self._convert_extras_requirements()498self._move_install_requirements_markers()499500def _convert_extras_requirements(self):501"""502Convert requirements in `extras_require` of the form503`"extra": ["barbazquux; {marker}"]` to504`"extra:{marker}": ["barbazquux"]`.505"""506spec_ext_reqs = getattr(self, 'extras_require', None) or {}507self._tmp_extras_require = defaultdict(list)508for section, v in spec_ext_reqs.items():509# Do not strip empty sections.510self._tmp_extras_require[section]511for r in pkg_resources.parse_requirements(v):512suffix = self._suffix_for(r)513self._tmp_extras_require[section + suffix].append(r)514515@staticmethod516def _suffix_for(req):517"""518For a requirement, return the 'extras_require' suffix for519that requirement.520"""521return ':' + str(req.marker) if req.marker else ''522523def _move_install_requirements_markers(self):524"""525Move requirements in `install_requires` that are using environment526markers `extras_require`.527"""528529# divide the install_requires into two sets, simple ones still530# handled by install_requires and more complex ones handled531# by extras_require.532533def is_simple_req(req):534return not req.marker535536spec_inst_reqs = getattr(self, 'install_requires', None) or ()537inst_reqs = list(pkg_resources.parse_requirements(spec_inst_reqs))538simple_reqs = filter(is_simple_req, inst_reqs)539complex_reqs = filterfalse(is_simple_req, inst_reqs)540self.install_requires = list(map(str, simple_reqs))541542for r in complex_reqs:543self._tmp_extras_require[':' + str(r.marker)].append(r)544self.extras_require = dict(545(k, [str(r) for r in map(self._clean_req, v)])546for k, v in self._tmp_extras_require.items()547)548549def _clean_req(self, req):550"""551Given a Requirement, remove environment markers and return it.552"""553req.marker = None554return req555556def _parse_config_files(self, filenames=None):557"""558Adapted from distutils.dist.Distribution.parse_config_files,559this method provides the same functionality in subtly-improved560ways.561"""562from setuptools.extern.six.moves.configparser import ConfigParser563564# Ignore install directory options if we have a venv565if not six.PY2 and sys.prefix != sys.base_prefix:566ignore_options = [567'install-base', 'install-platbase', 'install-lib',568'install-platlib', 'install-purelib', 'install-headers',569'install-scripts', 'install-data', 'prefix', 'exec-prefix',570'home', 'user', 'root']571else:572ignore_options = []573574ignore_options = frozenset(ignore_options)575576if filenames is None:577filenames = self.find_config_files()578579if DEBUG:580self.announce("Distribution.parse_config_files():")581582parser = ConfigParser()583for filename in filenames:584with io.open(filename, encoding='utf-8') as reader:585if DEBUG:586self.announce(" reading {filename}".format(**locals()))587(parser.readfp if six.PY2 else parser.read_file)(reader)588for section in parser.sections():589options = parser.options(section)590opt_dict = self.get_option_dict(section)591592for opt in options:593if opt != '__name__' and opt not in ignore_options:594val = self._try_str(parser.get(section, opt))595opt = opt.replace('-', '_')596opt_dict[opt] = (filename, val)597598# Make the ConfigParser forget everything (so we retain599# the original filenames that options come from)600parser.__init__()601602# If there was a "global" section in the config file, use it603# to set Distribution options.604605if 'global' in self.command_options:606for (opt, (src, val)) in self.command_options['global'].items():607alias = self.negative_opt.get(opt)608try:609if alias:610setattr(self, alias, not strtobool(val))611elif opt in ('verbose', 'dry_run'): # ugh!612setattr(self, opt, strtobool(val))613else:614setattr(self, opt, val)615except ValueError as e:616raise DistutilsOptionError(e) from e617618@staticmethod619def _try_str(val):620"""621On Python 2, much of distutils relies on string values being of622type 'str' (bytes) and not unicode text. If the value can be safely623encoded to bytes using the default encoding, prefer that.624625Why the default encoding? Because that value can be implicitly626decoded back to text if needed.627628Ref #1653629"""630if not six.PY2:631return val632try:633return val.encode()634except UnicodeEncodeError:635pass636return val637638def _set_command_options(self, command_obj, option_dict=None):639"""640Set the options for 'command_obj' from 'option_dict'. Basically641this means copying elements of a dictionary ('option_dict') to642attributes of an instance ('command').643644'command_obj' must be a Command instance. If 'option_dict' is not645supplied, uses the standard option dictionary for this command646(from 'self.command_options').647648(Adopted from distutils.dist.Distribution._set_command_options)649"""650command_name = command_obj.get_command_name()651if option_dict is None:652option_dict = self.get_option_dict(command_name)653654if DEBUG:655self.announce(" setting options for '%s' command:" % command_name)656for (option, (source, value)) in option_dict.items():657if DEBUG:658self.announce(" %s = %s (from %s)" % (option, value,659source))660try:661bool_opts = [translate_longopt(o)662for o in command_obj.boolean_options]663except AttributeError:664bool_opts = []665try:666neg_opt = command_obj.negative_opt667except AttributeError:668neg_opt = {}669670try:671is_string = isinstance(value, six.string_types)672if option in neg_opt and is_string:673setattr(command_obj, neg_opt[option], not strtobool(value))674elif option in bool_opts and is_string:675setattr(command_obj, option, strtobool(value))676elif hasattr(command_obj, option):677setattr(command_obj, option, value)678else:679raise DistutilsOptionError(680"error in %s: command '%s' has no such option '%s'"681% (source, command_name, option))682except ValueError as e:683raise DistutilsOptionError(e) from e684685def parse_config_files(self, filenames=None, ignore_option_errors=False):686"""Parses configuration files from various levels687and loads configuration.688689"""690self._parse_config_files(filenames=filenames)691692parse_configuration(self, self.command_options,693ignore_option_errors=ignore_option_errors)694self._finalize_requires()695696def fetch_build_eggs(self, requires):697"""Resolve pre-setup requirements"""698resolved_dists = pkg_resources.working_set.resolve(699pkg_resources.parse_requirements(requires),700installer=self.fetch_build_egg,701replace_conflicting=True,702)703for dist in resolved_dists:704pkg_resources.working_set.add(dist, replace=True)705return resolved_dists706707def finalize_options(self):708"""709Allow plugins to apply arbitrary operations to the710distribution. Each hook may optionally define a 'order'711to influence the order of execution. Smaller numbers712go first and the default is 0.713"""714group = 'setuptools.finalize_distribution_options'715716def by_order(hook):717return getattr(hook, 'order', 0)718eps = map(lambda e: e.load(), pkg_resources.iter_entry_points(group))719for ep in sorted(eps, key=by_order):720ep(self)721722def _finalize_setup_keywords(self):723for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):724value = getattr(self, ep.name, None)725if value is not None:726ep.require(installer=self.fetch_build_egg)727ep.load()(self, ep.name, value)728729def _finalize_2to3_doctests(self):730if getattr(self, 'convert_2to3_doctests', None):731# XXX may convert to set here when we can rely on set being builtin732self.convert_2to3_doctests = [733os.path.abspath(p)734for p in self.convert_2to3_doctests735]736else:737self.convert_2to3_doctests = []738739def get_egg_cache_dir(self):740egg_cache_dir = os.path.join(os.curdir, '.eggs')741if not os.path.exists(egg_cache_dir):742os.mkdir(egg_cache_dir)743windows_support.hide_file(egg_cache_dir)744readme_txt_filename = os.path.join(egg_cache_dir, 'README.txt')745with open(readme_txt_filename, 'w') as f:746f.write('This directory contains eggs that were downloaded '747'by setuptools to build, test, and run plug-ins.\n\n')748f.write('This directory caches those eggs to prevent '749'repeated downloads.\n\n')750f.write('However, it is safe to delete this directory.\n\n')751752return egg_cache_dir753754def fetch_build_egg(self, req):755"""Fetch an egg needed for building"""756from setuptools.installer import fetch_build_egg757return fetch_build_egg(self, req)758759def get_command_class(self, command):760"""Pluggable version of get_command_class()"""761if command in self.cmdclass:762return self.cmdclass[command]763764eps = pkg_resources.iter_entry_points('distutils.commands', command)765for ep in eps:766ep.require(installer=self.fetch_build_egg)767self.cmdclass[command] = cmdclass = ep.load()768return cmdclass769else:770return _Distribution.get_command_class(self, command)771772def print_commands(self):773for ep in pkg_resources.iter_entry_points('distutils.commands'):774if ep.name not in self.cmdclass:775# don't require extras as the commands won't be invoked776cmdclass = ep.resolve()777self.cmdclass[ep.name] = cmdclass778return _Distribution.print_commands(self)779780def get_command_list(self):781for ep in pkg_resources.iter_entry_points('distutils.commands'):782if ep.name not in self.cmdclass:783# don't require extras as the commands won't be invoked784cmdclass = ep.resolve()785self.cmdclass[ep.name] = cmdclass786return _Distribution.get_command_list(self)787788def include(self, **attrs):789"""Add items to distribution that are named in keyword arguments790791For example, 'dist.include(py_modules=["x"])' would add 'x' to792the distribution's 'py_modules' attribute, if it was not already793there.794795Currently, this method only supports inclusion for attributes that are796lists or tuples. If you need to add support for adding to other797attributes in this or a subclass, you can add an '_include_X' method,798where 'X' is the name of the attribute. The method will be called with799the value passed to 'include()'. So, 'dist.include(foo={"bar":"baz"})'800will try to call 'dist._include_foo({"bar":"baz"})', which can then801handle whatever special inclusion logic is needed.802"""803for k, v in attrs.items():804include = getattr(self, '_include_' + k, None)805if include:806include(v)807else:808self._include_misc(k, v)809810def exclude_package(self, package):811"""Remove packages, modules, and extensions in named package"""812813pfx = package + '.'814if self.packages:815self.packages = [816p for p in self.packages817if p != package and not p.startswith(pfx)818]819820if self.py_modules:821self.py_modules = [822p for p in self.py_modules823if p != package and not p.startswith(pfx)824]825826if self.ext_modules:827self.ext_modules = [828p for p in self.ext_modules829if p.name != package and not p.name.startswith(pfx)830]831832def has_contents_for(self, package):833"""Return true if 'exclude_package(package)' would do something"""834835pfx = package + '.'836837for p in self.iter_distribution_names():838if p == package or p.startswith(pfx):839return True840841def _exclude_misc(self, name, value):842"""Handle 'exclude()' for list/tuple attrs without a special handler"""843if not isinstance(value, sequence):844raise DistutilsSetupError(845"%s: setting must be a list or tuple (%r)" % (name, value)846)847try:848old = getattr(self, name)849except AttributeError as e:850raise DistutilsSetupError(851"%s: No such distribution setting" % name852) from e853if old is not None and not isinstance(old, sequence):854raise DistutilsSetupError(855name + ": this setting cannot be changed via include/exclude"856)857elif old:858setattr(self, name, [item for item in old if item not in value])859860def _include_misc(self, name, value):861"""Handle 'include()' for list/tuple attrs without a special handler"""862863if not isinstance(value, sequence):864raise DistutilsSetupError(865"%s: setting must be a list (%r)" % (name, value)866)867try:868old = getattr(self, name)869except AttributeError as e:870raise DistutilsSetupError(871"%s: No such distribution setting" % name872) from e873if old is None:874setattr(self, name, value)875elif not isinstance(old, sequence):876raise DistutilsSetupError(877name + ": this setting cannot be changed via include/exclude"878)879else:880new = [item for item in value if item not in old]881setattr(self, name, old + new)882883def exclude(self, **attrs):884"""Remove items from distribution that are named in keyword arguments885886For example, 'dist.exclude(py_modules=["x"])' would remove 'x' from887the distribution's 'py_modules' attribute. Excluding packages uses888the 'exclude_package()' method, so all of the package's contained889packages, modules, and extensions are also excluded.890891Currently, this method only supports exclusion from attributes that are892lists or tuples. If you need to add support for excluding from other893attributes in this or a subclass, you can add an '_exclude_X' method,894where 'X' is the name of the attribute. The method will be called with895the value passed to 'exclude()'. So, 'dist.exclude(foo={"bar":"baz"})'896will try to call 'dist._exclude_foo({"bar":"baz"})', which can then897handle whatever special exclusion logic is needed.898"""899for k, v in attrs.items():900exclude = getattr(self, '_exclude_' + k, None)901if exclude:902exclude(v)903else:904self._exclude_misc(k, v)905906def _exclude_packages(self, packages):907if not isinstance(packages, sequence):908raise DistutilsSetupError(909"packages: setting must be a list or tuple (%r)" % (packages,)910)911list(map(self.exclude_package, packages))912913def _parse_command_opts(self, parser, args):914# Remove --with-X/--without-X options when processing command args915self.global_options = self.__class__.global_options916self.negative_opt = self.__class__.negative_opt917918# First, expand any aliases919command = args[0]920aliases = self.get_option_dict('aliases')921while command in aliases:922src, alias = aliases[command]923del aliases[command] # ensure each alias can expand only once!924import shlex925args[:1] = shlex.split(alias, True)926command = args[0]927928nargs = _Distribution._parse_command_opts(self, parser, args)929930# Handle commands that want to consume all remaining arguments931cmd_class = self.get_command_class(command)932if getattr(cmd_class, 'command_consumes_arguments', None):933self.get_option_dict(command)['args'] = ("command line", nargs)934if nargs is not None:935return []936937return nargs938939def get_cmdline_options(self):940"""Return a '{cmd: {opt:val}}' map of all command-line options941942Option names are all long, but do not include the leading '--', and943contain dashes rather than underscores. If the option doesn't take944an argument (e.g. '--quiet'), the 'val' is 'None'.945946Note that options provided by config files are intentionally excluded.947"""948949d = {}950951for cmd, opts in self.command_options.items():952953for opt, (src, val) in opts.items():954955if src != "command line":956continue957958opt = opt.replace('_', '-')959960if val == 0:961cmdobj = self.get_command_obj(cmd)962neg_opt = self.negative_opt.copy()963neg_opt.update(getattr(cmdobj, 'negative_opt', {}))964for neg, pos in neg_opt.items():965if pos == opt:966opt = neg967val = None968break969else:970raise AssertionError("Shouldn't be able to get here")971972elif val == 1:973val = None974975d.setdefault(cmd, {})[opt] = val976977return d978979def iter_distribution_names(self):980"""Yield all packages, modules, and extension names in distribution"""981982for pkg in self.packages or ():983yield pkg984985for module in self.py_modules or ():986yield module987988for ext in self.ext_modules or ():989if isinstance(ext, tuple):990name, buildinfo = ext991else:992name = ext.name993if name.endswith('module'):994name = name[:-6]995yield name996997def handle_display_options(self, option_order):998"""If there were any non-global "display-only" options999(--help-commands or the metadata display options) on the command1000line, display the requested info and return true; else return1001false.1002"""1003import sys10041005if six.PY2 or self.help_commands:1006return _Distribution.handle_display_options(self, option_order)10071008# Stdout may be StringIO (e.g. in tests)1009if not isinstance(sys.stdout, io.TextIOWrapper):1010return _Distribution.handle_display_options(self, option_order)10111012# Don't wrap stdout if utf-8 is already the encoding. Provides1013# workaround for #334.1014if sys.stdout.encoding.lower() in ('utf-8', 'utf8'):1015return _Distribution.handle_display_options(self, option_order)10161017# Print metadata in UTF-8 no matter the platform1018encoding = sys.stdout.encoding1019errors = sys.stdout.errors1020newline = sys.platform != 'win32' and '\n' or None1021line_buffering = sys.stdout.line_buffering10221023sys.stdout = io.TextIOWrapper(1024sys.stdout.detach(), 'utf-8', errors, newline, line_buffering)1025try:1026return _Distribution.handle_display_options(self, option_order)1027finally:1028sys.stdout = io.TextIOWrapper(1029sys.stdout.detach(), encoding, errors, newline, line_buffering)103010311032class DistDeprecationWarning(SetuptoolsDeprecationWarning):1033"""Class for warning about deprecations in dist in1034setuptools. Not ignored by default, unlike DeprecationWarning."""103510361037