Change venv

This commit is contained in:
Ambulance Clerc
2023-05-31 08:31:22 +02:00
parent fb6f579089
commit fdbb52c96f
466 changed files with 25899 additions and 64721 deletions

View File

@@ -19,17 +19,19 @@ from glob import iglob
import itertools
import textwrap
from typing import List, Optional, TYPE_CHECKING
from pathlib import Path
from collections import defaultdict
from email import message_from_file
from distutils.errors import DistutilsOptionError, DistutilsSetupError
from distutils.util import rfc822_escape
from distutils.version import StrictVersion
from setuptools.extern import packaging
from setuptools.extern import ordered_set
from setuptools.extern.more_itertools import unique_everseen
from setuptools.extern.more_itertools import unique_everseen, partition
from ._importlib import metadata
from . import SetuptoolsDeprecationWarning
@@ -37,8 +39,13 @@ import setuptools
import setuptools.command
from setuptools import windows_support
from setuptools.monkey import get_unpatched
from setuptools.config import parse_configuration
from setuptools.config import setupcfg, pyprojecttoml
from setuptools.discovery import ConfigDiscovery
import pkg_resources
from setuptools.extern.packaging import version
from . import _reqs
from . import _entry_points
if TYPE_CHECKING:
from email.message import Message
@@ -55,7 +62,7 @@ def _get_unpatched(cls):
def get_metadata_version(self):
mv = getattr(self, 'metadata_version', None)
if mv is None:
mv = StrictVersion('2.1')
mv = version.Version('2.1')
self.metadata_version = mv
return mv
@@ -94,7 +101,7 @@ def _read_list_from_msg(msg: "Message", field: str) -> Optional[List[str]]:
def _read_payload_from_msg(msg: "Message") -> Optional[str]:
value = msg.get_payload().strip()
if value == 'UNKNOWN':
if value == 'UNKNOWN' or not value:
return None
return value
@@ -103,7 +110,7 @@ def read_pkg_file(self, file):
"""Reads the metadata values from a file object."""
msg = message_from_file(file)
self.metadata_version = StrictVersion(msg['metadata-version'])
self.metadata_version = version.Version(msg['metadata-version'])
self.name = _read_field_from_msg(msg, 'name')
self.version = _read_field_from_msg(msg, 'version')
self.description = _read_field_from_msg(msg, 'summary')
@@ -113,15 +120,14 @@ def read_pkg_file(self, file):
self.author_email = _read_field_from_msg(msg, 'author-email')
self.maintainer_email = None
self.url = _read_field_from_msg(msg, 'home-page')
self.download_url = _read_field_from_msg(msg, 'download-url')
self.license = _read_field_unescaped_from_msg(msg, 'license')
if 'download-url' in msg:
self.download_url = _read_field_from_msg(msg, 'download-url')
else:
self.download_url = None
self.long_description = _read_field_unescaped_from_msg(msg, 'description')
if self.long_description is None and self.metadata_version >= StrictVersion('2.1'):
if (
self.long_description is None and
self.metadata_version >= version.Version('2.1')
):
self.long_description = _read_payload_from_msg(msg)
self.description = _read_field_from_msg(msg, 'summary')
@@ -132,7 +138,7 @@ def read_pkg_file(self, file):
self.classifiers = _read_list_from_msg(msg, 'classifier')
# PEP 314 - these fields only exist in 1.1
if self.metadata_version == StrictVersion('1.1'):
if self.metadata_version == version.Version('1.1'):
self.requires = _read_list_from_msg(msg, 'requires')
self.provides = _read_list_from_msg(msg, 'provides')
self.obsoletes = _read_list_from_msg(msg, 'obsoletes')
@@ -145,11 +151,14 @@ def read_pkg_file(self, file):
def single_line(val):
# quick and dirty validation for description pypa/setuptools#1390
"""
Quick and dirty validation for Summary pypa/setuptools#1390.
"""
if '\n' in val:
# TODO after 2021-07-31: Replace with `raise ValueError("newlines not allowed")`
# TODO: Replace with `raise ValueError("newlines not allowed")`
# after reviewing #2893.
warnings.warn("newlines not allowed and will break in the future")
val = val.replace('\n', ' ')
val = val.strip().split('\n')[0]
return val
@@ -164,10 +173,14 @@ def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME
write_field('Metadata-Version', str(version))
write_field('Name', self.get_name())
write_field('Version', self.get_version())
write_field('Summary', single_line(self.get_description()))
write_field('Home-page', self.get_url())
summary = self.get_description()
if summary:
write_field('Summary', single_line(summary))
optional_fields = (
('Home-page', 'url'),
('Download-URL', 'download_url'),
('Author', 'author'),
('Author-email', 'author_email'),
('Maintainer', 'maintainer'),
@@ -179,10 +192,10 @@ def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME
if attr_val is not None:
write_field(field, attr_val)
license = rfc822_escape(self.get_license())
write_field('License', license)
if self.download_url:
write_field('Download-URL', self.download_url)
license = self.get_license()
if license:
write_field('License', rfc822_escape(license))
for project_url in self.project_urls.items():
write_field('Project-URL', '%s, %s' % project_url)
@@ -190,7 +203,8 @@ def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME
if keywords:
write_field('Keywords', keywords)
for platform in self.get_platforms():
platforms = self.get_platforms() or []
for platform in platforms:
write_field('Platform', platform)
self._write_list(file, 'Classifier', self.get_classifiers())
@@ -213,7 +227,11 @@ def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME
self._write_list(file, 'License-File', self.license_files or [])
file.write("\n%s\n\n" % self.get_long_description())
long_description = self.get_long_description()
if long_description:
file.write("\n%s" % long_description)
if not long_description.endswith("\n"):
file.write("\n")
sequence = tuple, list
@@ -221,7 +239,7 @@ sequence = tuple, list
def check_importable(dist, attr, value):
try:
ep = pkg_resources.EntryPoint.parse('x=' + value)
ep = metadata.EntryPoint(value=value, name=None, group=None)
assert not ep.extras
except (TypeError, ValueError, AttributeError, AssertionError) as e:
raise DistutilsSetupError(
@@ -261,6 +279,11 @@ def check_nsp(dist, attr, value):
nsp,
parent,
)
msg = (
"The namespace_packages parameter is deprecated, "
"consider using implicit namespaces instead (PEP 420)."
)
warnings.warn(msg, SetuptoolsDeprecationWarning)
def check_extras(dist, attr, value):
@@ -279,7 +302,7 @@ def _check_extra(extra, reqs):
name, sep, marker = extra.partition(':')
if marker and pkg_resources.invalid_marker(marker):
raise DistutilsSetupError("Invalid environment marker: " + marker)
list(pkg_resources.parse_requirements(reqs))
list(_reqs.parse(reqs))
def assert_bool(dist, attr, value):
@@ -299,7 +322,7 @@ def invalid_unless_false(dist, attr, value):
def check_requirements(dist, attr, value):
"""Verify that install_requires is a valid requirements list"""
try:
list(pkg_resources.parse_requirements(value))
list(_reqs.parse(value))
if isinstance(value, (dict, set)):
raise TypeError("Unordered types are not allowed")
except (TypeError, ValueError) as error:
@@ -324,8 +347,8 @@ def check_specifier(dist, attr, value):
def check_entry_points(dist, attr, value):
"""Verify that entry_points map is parseable"""
try:
pkg_resources.EntryPoint.parse_map(value)
except ValueError as e:
_entry_points.load(value)
except Exception as e:
raise DistutilsSetupError(e) from e
@@ -448,7 +471,7 @@ class Distribution(_Distribution):
self.patch_missing_pkg_info(attrs)
self.dependency_links = attrs.pop('dependency_links', [])
self.setup_requires = attrs.pop('setup_requires', [])
for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):
for ep in metadata.entry_points(group='distutils.setup_keywords'):
vars(self).setdefault(ep.name, None)
_Distribution.__init__(
self,
@@ -459,6 +482,13 @@ class Distribution(_Distribution):
},
)
# Save the original dependencies before they are processed into the egg format
self._orig_extras_require = {}
self._orig_install_requires = []
self._tmp_extras_require = defaultdict(ordered_set.OrderedSet)
self.set_defaults = ConfigDiscovery(self)
self._set_metadata_defaults(attrs)
self.metadata.version = self._normalize_version(
@@ -466,6 +496,19 @@ class Distribution(_Distribution):
)
self._finalize_requires()
def _validate_metadata(self):
required = {"name"}
provided = {
key
for key in vars(self.metadata)
if getattr(self.metadata, key, None) is not None
}
missing = required - provided
if missing:
msg = f"Required package metadata is missing: {missing}"
raise DistutilsSetupError(msg)
def _set_metadata_defaults(self, attrs):
"""
Fill-in missing metadata fields not supported by distutils.
@@ -516,6 +559,8 @@ class Distribution(_Distribution):
self.metadata.python_requires = self.python_requires
if getattr(self, 'extras_require', None):
# Save original before it is messed by _convert_extras_requirements
self._orig_extras_require = self._orig_extras_require or self.extras_require
for extra in self.extras_require.keys():
# Since this gets called multiple times at points where the
# keys have become 'converted' extras, ensure that we are only
@@ -524,6 +569,10 @@ class Distribution(_Distribution):
if extra:
self.metadata.provides_extras.add(extra)
if getattr(self, 'install_requires', None) and not self._orig_install_requires:
# Save original before it is messed by _move_install_requirements_markers
self._orig_install_requires = self.install_requires
self._convert_extras_requirements()
self._move_install_requirements_markers()
@@ -534,11 +583,12 @@ class Distribution(_Distribution):
`"extra:{marker}": ["barbazquux"]`.
"""
spec_ext_reqs = getattr(self, 'extras_require', None) or {}
self._tmp_extras_require = defaultdict(list)
tmp = defaultdict(ordered_set.OrderedSet)
self._tmp_extras_require = getattr(self, '_tmp_extras_require', tmp)
for section, v in spec_ext_reqs.items():
# Do not strip empty sections.
self._tmp_extras_require[section]
for r in pkg_resources.parse_requirements(v):
for r in _reqs.parse(v):
suffix = self._suffix_for(r)
self._tmp_extras_require[section + suffix].append(r)
@@ -564,7 +614,7 @@ class Distribution(_Distribution):
return not req.marker
spec_inst_reqs = getattr(self, 'install_requires', None) or ()
inst_reqs = list(pkg_resources.parse_requirements(spec_inst_reqs))
inst_reqs = list(_reqs.parse(spec_inst_reqs))
simple_reqs = filter(is_simple_req, inst_reqs)
complex_reqs = itertools.filterfalse(is_simple_req, inst_reqs)
self.install_requires = list(map(str, simple_reqs))
@@ -572,7 +622,8 @@ class Distribution(_Distribution):
for r in complex_reqs:
self._tmp_extras_require[':' + str(r.marker)].append(r)
self.extras_require = dict(
(k, [str(r) for r in map(self._clean_req, v)])
# list(dict.fromkeys(...)) ensures a list of unique strings
(k, list(dict.fromkeys(str(r) for r in map(self._clean_req, v))))
for k, v in self._tmp_extras_require.items()
)
@@ -705,7 +756,10 @@ class Distribution(_Distribution):
return opt
underscore_opt = opt.replace('-', '_')
commands = distutils.command.__all__ + self._setuptools_commands()
commands = list(itertools.chain(
distutils.command.__all__,
self._setuptools_commands(),
))
if (
not section.startswith('options')
and section != 'metadata'
@@ -723,9 +777,8 @@ class Distribution(_Distribution):
def _setuptools_commands(self):
try:
dist = pkg_resources.get_distribution('setuptools')
return list(dist.get_entry_map('distutils.commands'))
except pkg_resources.DistributionNotFound:
return metadata.distribution('setuptools').entry_points.names
except metadata.PackageNotFoundError:
# during bootstrapping, distribution doesn't exist
return []
@@ -788,23 +841,39 @@ class Distribution(_Distribution):
except ValueError as e:
raise DistutilsOptionError(e) from e
def _get_project_config_files(self, filenames):
"""Add default file and split between INI and TOML"""
tomlfiles = []
standard_project_metadata = Path(self.src_root or os.curdir, "pyproject.toml")
if filenames is not None:
parts = partition(lambda f: Path(f).suffix == ".toml", filenames)
filenames = list(parts[0]) # 1st element => predicate is False
tomlfiles = list(parts[1]) # 2nd element => predicate is True
elif standard_project_metadata.exists():
tomlfiles = [standard_project_metadata]
return filenames, tomlfiles
def parse_config_files(self, filenames=None, ignore_option_errors=False):
"""Parses configuration files from various levels
and loads configuration.
"""
self._parse_config_files(filenames=filenames)
inifiles, tomlfiles = self._get_project_config_files(filenames)
parse_configuration(
self._parse_config_files(filenames=inifiles)
setupcfg.parse_configuration(
self, self.command_options, ignore_option_errors=ignore_option_errors
)
for filename in tomlfiles:
pyprojecttoml.apply_configuration(self, filename, ignore_option_errors)
self._finalize_requires()
self._finalize_license_files()
def fetch_build_eggs(self, requires):
"""Resolve pre-setup requirements"""
resolved_dists = pkg_resources.working_set.resolve(
pkg_resources.parse_requirements(requires),
_reqs.parse(requires),
installer=self.fetch_build_egg,
replace_conflicting=True,
)
@@ -824,7 +893,7 @@ class Distribution(_Distribution):
def by_order(hook):
return getattr(hook, 'order', 0)
defined = pkg_resources.iter_entry_points(group)
defined = metadata.entry_points(group=group)
filtered = itertools.filterfalse(self._removed, defined)
loaded = map(lambda e: e.load(), filtered)
for ep in sorted(loaded, key=by_order):
@@ -845,10 +914,9 @@ class Distribution(_Distribution):
return ep.name in removed
def _finalize_setup_keywords(self):
for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):
for ep in metadata.entry_points(group='distutils.setup_keywords'):
value = getattr(self, ep.name, None)
if value is not None:
ep.require(installer=self.fetch_build_egg)
ep.load()(self, ep.name, value)
def get_egg_cache_dir(self):
@@ -881,27 +949,24 @@ class Distribution(_Distribution):
if command in self.cmdclass:
return self.cmdclass[command]
eps = pkg_resources.iter_entry_points('distutils.commands', command)
eps = metadata.entry_points(group='distutils.commands', name=command)
for ep in eps:
ep.require(installer=self.fetch_build_egg)
self.cmdclass[command] = cmdclass = ep.load()
return cmdclass
else:
return _Distribution.get_command_class(self, command)
def print_commands(self):
for ep in pkg_resources.iter_entry_points('distutils.commands'):
for ep in metadata.entry_points(group='distutils.commands'):
if ep.name not in self.cmdclass:
# don't require extras as the commands won't be invoked
cmdclass = ep.resolve()
cmdclass = ep.load()
self.cmdclass[ep.name] = cmdclass
return _Distribution.print_commands(self)
def get_command_list(self):
for ep in pkg_resources.iter_entry_points('distutils.commands'):
for ep in metadata.entry_points(group='distutils.commands'):
if ep.name not in self.cmdclass:
# don't require extras as the commands won't be invoked
cmdclass = ep.resolve()
cmdclass = ep.load()
self.cmdclass[ep.name] = cmdclass
return _Distribution.get_command_list(self)
@@ -1144,6 +1209,13 @@ class Distribution(_Distribution):
sys.stdout.detach(), encoding, errors, newline, line_buffering
)
def run_command(self, command):
self.set_defaults()
# Postpone defaults until all explicit configuration is considered
# (setup() args, config files, command line and plugins)
super().run_command(command)
class DistDeprecationWarning(SetuptoolsDeprecationWarning):
"""Class for warning about deprecations in dist in