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

@@ -7,6 +7,8 @@ being built/installed/distributed.
import sys
import os
import re
import pathlib
import contextlib
from email import message_from_file
try:
@@ -14,7 +16,12 @@ try:
except ImportError:
warnings = None
from distutils.errors import *
from distutils.errors import (
DistutilsOptionError,
DistutilsModuleError,
DistutilsArgError,
DistutilsClassError,
)
from distutils.fancy_getopt import FancyGetopt, translate_longopt
from distutils.util import check_environ, strtobool, rfc822_escape
from distutils import log
@@ -69,8 +76,7 @@ class Distribution:
('quiet', 'q', "run quietly (turns verbosity off)"),
('dry-run', 'n', "don't actually do anything"),
('help', 'h', "show detailed help message"),
('no-user-cfg', None,
'ignore pydistutils.cfg in your home directory'),
('no-user-cfg', None, 'ignore pydistutils.cfg in your home directory'),
]
# 'common_usage' is a short (2-3 line) string describing the common
@@ -84,49 +90,32 @@ Common commands: (see '--help-commands' for more)
# options that are not propagated to the commands
display_options = [
('help-commands', None,
"list all available commands"),
('name', None,
"print package name"),
('version', 'V',
"print package version"),
('fullname', None,
"print <package name>-<version>"),
('author', None,
"print the author's name"),
('author-email', None,
"print the author's email address"),
('maintainer', None,
"print the maintainer's name"),
('maintainer-email', None,
"print the maintainer's email address"),
('contact', None,
"print the maintainer's name if known, else the author's"),
('contact-email', None,
"print the maintainer's email address if known, else the author's"),
('url', None,
"print the URL for this package"),
('license', None,
"print the license of the package"),
('licence', None,
"alias for --license"),
('description', None,
"print the package description"),
('long-description', None,
"print the long package description"),
('platforms', None,
"print the list of platforms"),
('classifiers', None,
"print the list of classifiers"),
('keywords', None,
"print the list of keywords"),
('provides', None,
"print the list of packages/modules provided"),
('requires', None,
"print the list of packages/modules required"),
('obsoletes', None,
"print the list of packages/modules made obsolete")
]
('help-commands', None, "list all available commands"),
('name', None, "print package name"),
('version', 'V', "print package version"),
('fullname', None, "print <package name>-<version>"),
('author', None, "print the author's name"),
('author-email', None, "print the author's email address"),
('maintainer', None, "print the maintainer's name"),
('maintainer-email', None, "print the maintainer's email address"),
('contact', None, "print the maintainer's name if known, else the author's"),
(
'contact-email',
None,
"print the maintainer's email address if known, else the author's",
),
('url', None, "print the URL for this package"),
('license', None, "print the license of the package"),
('licence', None, "alias for --license"),
('description', None, "print the package description"),
('long-description', None, "print the long package description"),
('platforms', None, "print the list of platforms"),
('classifiers', None, "print the list of classifiers"),
('keywords', None, "print the list of keywords"),
('provides', None, "print the list of packages/modules provided"),
('requires', None, "print the list of packages/modules required"),
('obsoletes', None, "print the list of packages/modules made obsolete"),
]
display_option_names = [translate_longopt(x[0]) for x in display_options]
# negative options are options that exclude other options
@@ -134,7 +123,7 @@ Common commands: (see '--help-commands' for more)
# -- Creation/initialization methods -------------------------------
def __init__(self, attrs=None):
def __init__(self, attrs=None): # noqa: C901
"""Construct a new Distribution instance: initialize all the
attributes of a Distribution, and then use 'attrs' (a dictionary
mapping attribute names to values) to assign some of those
@@ -306,7 +295,7 @@ Common commands: (see '--help-commands' for more)
def dump_option_dicts(self, header=None, commands=None, indent=""):
from pprint import pformat
if commands is None: # dump all command option dicts
if commands is None: # dump all command option dicts
commands = sorted(self.command_options.keys())
if header is not None:
@@ -320,11 +309,9 @@ Common commands: (see '--help-commands' for more)
for cmd_name in commands:
opt_dict = self.command_options.get(cmd_name)
if opt_dict is None:
self.announce(indent +
"no option dict for '%s' command" % cmd_name)
self.announce(indent + "no option dict for '%s' command" % cmd_name)
else:
self.announce(indent +
"option dict for '%s' command:" % cmd_name)
self.announce(indent + "option dict for '%s' command:" % cmd_name)
out = pformat(opt_dict)
for line in out.split('\n'):
self.announce(indent + " " + line)
@@ -337,58 +324,61 @@ Common commands: (see '--help-commands' for more)
should be parsed. The filenames returned are guaranteed to exist
(modulo nasty race conditions).
There are three possible config files: distutils.cfg in the
Distutils installation directory (ie. where the top-level
Distutils __inst__.py file lives), a file in the user's home
directory named .pydistutils.cfg on Unix and pydistutils.cfg
on Windows/Mac; and setup.cfg in the current directory.
The file in the user's home directory can be disabled with the
--no-user-cfg option.
There are multiple possible config files:
- distutils.cfg in the Distutils installation directory (i.e.
where the top-level Distutils __inst__.py file lives)
- a file in the user's home directory named .pydistutils.cfg
on Unix and pydistutils.cfg on Windows/Mac; may be disabled
with the ``--no-user-cfg`` option
- setup.cfg in the current directory
- a file named by an environment variable
"""
files = []
check_environ()
# Where to look for the system-wide Distutils config file
sys_dir = os.path.dirname(sys.modules['distutils'].__file__)
# Look for the system config file
sys_file = os.path.join(sys_dir, "distutils.cfg")
if os.path.isfile(sys_file):
files.append(sys_file)
# What to call the per-user config file
if os.name == 'posix':
user_filename = ".pydistutils.cfg"
else:
user_filename = "pydistutils.cfg"
# And look for the user config file
if self.want_user_cfg:
user_file = os.path.join(os.path.expanduser('~'), user_filename)
if os.path.isfile(user_file):
files.append(user_file)
# All platforms support local setup.cfg
local_file = "setup.cfg"
if os.path.isfile(local_file):
files.append(local_file)
files = [str(path) for path in self._gen_paths() if os.path.isfile(path)]
if DEBUG:
self.announce("using config files: %s" % ', '.join(files))
return files
def parse_config_files(self, filenames=None):
def _gen_paths(self):
# The system-wide Distutils config file
sys_dir = pathlib.Path(sys.modules['distutils'].__file__).parent
yield sys_dir / "distutils.cfg"
# The per-user config file
prefix = '.' * (os.name == 'posix')
filename = prefix + 'pydistutils.cfg'
if self.want_user_cfg:
yield pathlib.Path('~').expanduser() / filename
# All platforms support local setup.cfg
yield pathlib.Path('setup.cfg')
# Additional config indicated in the environment
with contextlib.suppress(TypeError):
yield pathlib.Path(os.getenv("DIST_EXTRA_CONFIG"))
def parse_config_files(self, filenames=None): # noqa: C901
from configparser import ConfigParser
# Ignore install directory options if we have a venv
if sys.prefix != sys.base_prefix:
ignore_options = [
'install-base', 'install-platbase', 'install-lib',
'install-platlib', 'install-purelib', 'install-headers',
'install-scripts', 'install-data', 'prefix', 'exec-prefix',
'home', 'user', 'root']
'install-base',
'install-platbase',
'install-lib',
'install-platlib',
'install-purelib',
'install-headers',
'install-scripts',
'install-data',
'prefix',
'exec-prefix',
'home',
'user',
'root',
]
else:
ignore_options = []
@@ -411,7 +401,7 @@ Common commands: (see '--help-commands' for more)
for opt in options:
if opt != '__name__' and opt not in ignore_options:
val = parser.get(section,opt)
val = parser.get(section, opt)
opt = opt.replace('-', '_')
opt_dict[opt] = (filename, val)
@@ -428,7 +418,7 @@ Common commands: (see '--help-commands' for more)
try:
if alias:
setattr(self, alias, not strtobool(val))
elif opt in ('verbose', 'dry_run'): # ugh!
elif opt in ('verbose', 'dry_run'): # ugh!
setattr(self, opt, strtobool(val))
else:
setattr(self, opt, val)
@@ -482,7 +472,7 @@ Common commands: (see '--help-commands' for more)
return
while args:
args = self._parse_command_opts(parser, args)
if args is None: # user asked for help (and got it)
if args is None: # user asked for help (and got it)
return
# Handle the cases of --help as a "global" option, ie.
@@ -492,9 +482,9 @@ Common commands: (see '--help-commands' for more)
# latter, we omit the display-only options and show help for
# each command listed on the command line.
if self.help:
self._show_help(parser,
display_options=len(self.commands) == 0,
commands=self.commands)
self._show_help(
parser, display_options=len(self.commands) == 0, commands=self.commands
)
return
# Oops, no commands found -- an end-user error
@@ -511,11 +501,14 @@ Common commands: (see '--help-commands' for more)
level as well as options recognized for commands.
"""
return self.global_options + [
("command-packages=", None,
"list of packages that provide distutils commands"),
]
(
"command-packages=",
None,
"list of packages that provide distutils commands",
),
]
def _parse_command_opts(self, parser, args):
def _parse_command_opts(self, parser, args): # noqa: C901
"""Parse the command-line options for a single command.
'parser' must be a FancyGetopt instance; 'args' must be the list
of arguments, starting with the current command (whose options
@@ -545,14 +538,19 @@ Common commands: (see '--help-commands' for more)
# to be sure that the basic "command" interface is implemented.
if not issubclass(cmd_class, Command):
raise DistutilsClassError(
"command class %s must subclass Command" % cmd_class)
"command class %s must subclass Command" % cmd_class
)
# Also make sure that the command object provides a list of its
# known options.
if not (hasattr(cmd_class, 'user_options') and
isinstance(cmd_class.user_options, list)):
msg = ("command class %s must provide "
"'user_options' attribute (a list of tuples)")
if not (
hasattr(cmd_class, 'user_options')
and isinstance(cmd_class.user_options, list)
):
msg = (
"command class %s must provide "
"'user_options' attribute (a list of tuples)"
)
raise DistutilsClassError(msg % cmd_class)
# If the command class has a list of negative alias options,
@@ -564,36 +562,39 @@ Common commands: (see '--help-commands' for more)
# Check for help_options in command class. They have a different
# format (tuple of four) so we need to preprocess them here.
if (hasattr(cmd_class, 'help_options') and
isinstance(cmd_class.help_options, list)):
if hasattr(cmd_class, 'help_options') and isinstance(
cmd_class.help_options, list
):
help_options = fix_help_options(cmd_class.help_options)
else:
help_options = []
# All commands support the global options too, just by adding
# in 'global_options'.
parser.set_option_table(self.global_options +
cmd_class.user_options +
help_options)
parser.set_option_table(
self.global_options + cmd_class.user_options + help_options
)
parser.set_negative_aliases(negative_opt)
(args, opts) = parser.getopt(args[1:])
if hasattr(opts, 'help') and opts.help:
self._show_help(parser, display_options=0, commands=[cmd_class])
return
if (hasattr(cmd_class, 'help_options') and
isinstance(cmd_class.help_options, list)):
help_option_found=0
if hasattr(cmd_class, 'help_options') and isinstance(
cmd_class.help_options, list
):
help_option_found = 0
for (help_option, short, desc, func) in cmd_class.help_options:
if hasattr(opts, parser.get_attr_name(help_option)):
help_option_found=1
help_option_found = 1
if callable(func):
func()
else:
raise DistutilsClassError(
"invalid help function %r for help option '%s': "
"must be a callable object (function, etc.)"
% (func, help_option))
% (func, help_option)
)
if help_option_found:
return
@@ -619,8 +620,7 @@ Common commands: (see '--help-commands' for more)
value = [elm.strip() for elm in value.split(',')]
setattr(self.metadata, attr, value)
def _show_help(self, parser, global_options=1, display_options=1,
commands=[]):
def _show_help(self, parser, global_options=1, display_options=1, commands=[]):
"""Show help for the setup script command-line in the form of
several lists of command-line options. 'parser' should be a
FancyGetopt instance; do not expect it to be returned in the
@@ -649,8 +649,9 @@ Common commands: (see '--help-commands' for more)
if display_options:
parser.set_option_table(self.display_options)
parser.print_help(
"Information display options (just display " +
"information, ignore any commands)")
"Information display options (just display "
+ "information, ignore any commands)"
)
print('')
for command in self.commands:
@@ -658,10 +659,10 @@ Common commands: (see '--help-commands' for more)
klass = command
else:
klass = self.get_command_class(command)
if (hasattr(klass, 'help_options') and
isinstance(klass.help_options, list)):
parser.set_option_table(klass.user_options +
fix_help_options(klass.help_options))
if hasattr(klass, 'help_options') and isinstance(klass.help_options, list):
parser.set_option_table(
klass.user_options + fix_help_options(klass.help_options)
)
else:
parser.set_option_table(klass.user_options)
parser.print_help("Options for '%s' command:" % klass.__name__)
@@ -697,11 +698,10 @@ Common commands: (see '--help-commands' for more)
for (opt, val) in option_order:
if val and is_display_option.get(opt):
opt = translate_longopt(opt)
value = getattr(self.metadata, "get_"+opt)()
value = getattr(self.metadata, "get_" + opt)()
if opt in ['keywords', 'platforms']:
print(','.join(value))
elif opt in ('classifiers', 'provides', 'requires',
'obsoletes'):
elif opt in ('classifiers', 'provides', 'requires', 'obsoletes'):
print('\n'.join(value))
else:
print(value)
@@ -735,6 +735,7 @@ Common commands: (see '--help-commands' for more)
'description'.
"""
import distutils.command
std_commands = distutils.command.__all__
is_std = {}
for cmd in std_commands:
@@ -746,18 +747,14 @@ Common commands: (see '--help-commands' for more)
extra_commands.append(cmd)
max_length = 0
for cmd in (std_commands + extra_commands):
for cmd in std_commands + extra_commands:
if len(cmd) > max_length:
max_length = len(cmd)
self.print_command_list(std_commands,
"Standard commands",
max_length)
self.print_command_list(std_commands, "Standard commands", max_length)
if extra_commands:
print()
self.print_command_list(extra_commands,
"Extra commands",
max_length)
self.print_command_list(extra_commands, "Extra commands", max_length)
def get_command_list(self):
"""Get a list of (command, description) tuples.
@@ -769,6 +766,7 @@ Common commands: (see '--help-commands' for more)
# Currently this is only used on Mac OS, for the Mac-only GUI
# Distutils interface (by Jack Jansen)
import distutils.command
std_commands = distutils.command.__all__
is_std = {}
for cmd in std_commands:
@@ -780,7 +778,7 @@ Common commands: (see '--help-commands' for more)
extra_commands.append(cmd)
rv = []
for cmd in (std_commands + extra_commands):
for cmd in std_commands + extra_commands:
klass = self.cmdclass.get(cmd)
if not klass:
klass = self.get_command_class(cmd)
@@ -822,7 +820,7 @@ Common commands: (see '--help-commands' for more)
return klass
for pkgname in self.get_command_packages():
module_name = "%s.%s" % (pkgname, command)
module_name = "{}.{}".format(pkgname, command)
klass_name = command
try:
@@ -836,7 +834,8 @@ Common commands: (see '--help-commands' for more)
except AttributeError:
raise DistutilsModuleError(
"invalid command '%s' (no class '%s' in module '%s')"
% (command, klass_name, module_name))
% (command, klass_name, module_name)
)
self.cmdclass[command] = klass
return klass
@@ -852,8 +851,10 @@ Common commands: (see '--help-commands' for more)
cmd_obj = self.command_obj.get(command)
if not cmd_obj and create:
if DEBUG:
self.announce("Distribution.get_command_obj(): "
"creating '%s' command object" % command)
self.announce(
"Distribution.get_command_obj(): "
"creating '%s' command object" % command
)
klass = self.get_command_class(command)
cmd_obj = self.command_obj[command] = klass(self)
@@ -870,7 +871,7 @@ Common commands: (see '--help-commands' for more)
return cmd_obj
def _set_command_options(self, command_obj, option_dict=None):
def _set_command_options(self, command_obj, option_dict=None): # noqa: C901
"""Set the options for 'command_obj' from 'option_dict'. Basically
this means copying elements of a dictionary ('option_dict') to
attributes of an instance ('command').
@@ -887,11 +888,9 @@ Common commands: (see '--help-commands' for more)
self.announce(" setting options for '%s' command:" % command_name)
for (option, (source, value)) in option_dict.items():
if DEBUG:
self.announce(" %s = %s (from %s)" % (option, value,
source))
self.announce(" {} = {} (from {})".format(option, value, source))
try:
bool_opts = [translate_longopt(o)
for o in command_obj.boolean_options]
bool_opts = [translate_longopt(o) for o in command_obj.boolean_options]
except AttributeError:
bool_opts = []
try:
@@ -910,7 +909,8 @@ Common commands: (see '--help-commands' for more)
else:
raise DistutilsOptionError(
"error in %s: command '%s' has no such option '%s'"
% (source, command_name, option))
% (source, command_name, option)
)
except ValueError as msg:
raise DistutilsOptionError(msg)
@@ -934,6 +934,7 @@ Common commands: (see '--help-commands' for more)
Returns the reinitialized command object.
"""
from distutils.cmd import Command
if not isinstance(command, Command):
command_name = command
command = self.get_command_obj(command_name)
@@ -1010,9 +1011,11 @@ Common commands: (see '--help-commands' for more)
return self.data_files and len(self.data_files) > 0
def is_pure(self):
return (self.has_pure_modules() and
not self.has_ext_modules() and
not self.has_c_libraries())
return (
self.has_pure_modules()
and not self.has_ext_modules()
and not self.has_c_libraries()
)
# -- Metadata query methods ----------------------------------------
@@ -1021,19 +1024,35 @@ Common commands: (see '--help-commands' for more)
# to self.metadata.get_XXX. The actual code is in the
# DistributionMetadata class, below.
class DistributionMetadata:
"""Dummy class to hold the distribution meta-data: name, version,
author, and so forth.
"""
_METHOD_BASENAMES = ("name", "version", "author", "author_email",
"maintainer", "maintainer_email", "url",
"license", "description", "long_description",
"keywords", "platforms", "fullname", "contact",
"contact_email", "classifiers", "download_url",
# PEP 314
"provides", "requires", "obsoletes",
)
_METHOD_BASENAMES = (
"name",
"version",
"author",
"author_email",
"maintainer",
"maintainer_email",
"url",
"license",
"description",
"long_description",
"keywords",
"platforms",
"fullname",
"contact",
"contact_email",
"classifiers",
"download_url",
# PEP 314
"provides",
"requires",
"obsoletes",
)
def __init__(self, path=None):
if path is not None:
@@ -1064,9 +1083,8 @@ class DistributionMetadata:
def _read_field(name):
value = msg[name]
if value == 'UNKNOWN':
return None
return value
if value and value != "UNKNOWN":
return value
def _read_list(name):
values = msg.get_all(name, None)
@@ -1111,37 +1129,42 @@ class DistributionMetadata:
self.obsoletes = None
def write_pkg_info(self, base_dir):
"""Write the PKG-INFO file into the release tree.
"""
with open(os.path.join(base_dir, 'PKG-INFO'), 'w',
encoding='UTF-8') as pkg_info:
"""Write the PKG-INFO file into the release tree."""
with open(
os.path.join(base_dir, 'PKG-INFO'), 'w', encoding='UTF-8'
) as pkg_info:
self.write_pkg_file(pkg_info)
def write_pkg_file(self, file):
"""Write the PKG-INFO format data to a file object.
"""
"""Write the PKG-INFO format data to a file object."""
version = '1.0'
if (self.provides or self.requires or self.obsoletes or
self.classifiers or self.download_url):
if (
self.provides
or self.requires
or self.obsoletes
or self.classifiers
or self.download_url
):
version = '1.1'
# required fields
file.write('Metadata-Version: %s\n' % version)
file.write('Name: %s\n' % self.get_name())
file.write('Version: %s\n' % self.get_version())
file.write('Summary: %s\n' % self.get_description())
file.write('Home-page: %s\n' % self.get_url())
file.write('Author: %s\n' % self.get_contact())
file.write('Author-email: %s\n' % self.get_contact_email())
file.write('License: %s\n' % self.get_license())
if self.download_url:
file.write('Download-URL: %s\n' % self.download_url)
long_desc = rfc822_escape(self.get_long_description())
file.write('Description: %s\n' % long_desc)
def maybe_write(header, val):
if val:
file.write(f"{header}: {val}\n")
keywords = ','.join(self.get_keywords())
if keywords:
file.write('Keywords: %s\n' % keywords)
# optional fields
maybe_write("Summary", self.get_description())
maybe_write("Home-page", self.get_url())
maybe_write("Author", self.get_contact())
maybe_write("Author-email", self.get_contact_email())
maybe_write("License", self.get_license())
maybe_write("Download-URL", self.download_url)
maybe_write("Description", rfc822_escape(self.get_long_description() or ""))
maybe_write("Keywords", ",".join(self.get_keywords()))
self._write_list(file, 'Platform', self.get_platforms())
self._write_list(file, 'Classifier', self.get_classifiers())
@@ -1152,8 +1175,9 @@ class DistributionMetadata:
self._write_list(file, 'Obsoletes', self.get_obsoletes())
def _write_list(self, file, name, values):
values = values or []
for value in values:
file.write('%s: %s\n' % (name, value))
file.write('{}: {}\n'.format(name, value))
# -- Metadata query methods ----------------------------------------
@@ -1164,38 +1188,39 @@ class DistributionMetadata:
return self.version or "0.0.0"
def get_fullname(self):
return "%s-%s" % (self.get_name(), self.get_version())
return "{}-{}".format(self.get_name(), self.get_version())
def get_author(self):
return self.author or "UNKNOWN"
return self.author
def get_author_email(self):
return self.author_email or "UNKNOWN"
return self.author_email
def get_maintainer(self):
return self.maintainer or "UNKNOWN"
return self.maintainer
def get_maintainer_email(self):
return self.maintainer_email or "UNKNOWN"
return self.maintainer_email
def get_contact(self):
return self.maintainer or self.author or "UNKNOWN"
return self.maintainer or self.author
def get_contact_email(self):
return self.maintainer_email or self.author_email or "UNKNOWN"
return self.maintainer_email or self.author_email
def get_url(self):
return self.url or "UNKNOWN"
return self.url
def get_license(self):
return self.license or "UNKNOWN"
return self.license
get_licence = get_license
def get_description(self):
return self.description or "UNKNOWN"
return self.description
def get_long_description(self):
return self.long_description or "UNKNOWN"
return self.long_description
def get_keywords(self):
return self.keywords or []
@@ -1204,7 +1229,7 @@ class DistributionMetadata:
self.keywords = _ensure_list(value, 'keywords')
def get_platforms(self):
return self.platforms or ["UNKNOWN"]
return self.platforms
def set_platforms(self, value):
self.platforms = _ensure_list(value, 'platforms')
@@ -1216,7 +1241,7 @@ class DistributionMetadata:
self.classifiers = _ensure_list(value, 'classifiers')
def get_download_url(self):
return self.download_url or "UNKNOWN"
return self.download_url
# PEP 314
def get_requires(self):
@@ -1224,6 +1249,7 @@ class DistributionMetadata:
def set_requires(self, value):
import distutils.versionpredicate
for v in value:
distutils.versionpredicate.VersionPredicate(v)
self.requires = list(value)
@@ -1235,6 +1261,7 @@ class DistributionMetadata:
value = [v.strip() for v in value]
for v in value:
import distutils.versionpredicate
distutils.versionpredicate.split_provision(v)
self.provides = value
@@ -1243,10 +1270,12 @@ class DistributionMetadata:
def set_obsoletes(self, value):
import distutils.versionpredicate
for v in value:
distutils.versionpredicate.VersionPredicate(v)
self.obsoletes = list(value)
def fix_help_options(options):
"""Convert a 4-tuple 'help_options' list as found in various command
classes to the 3-tuple form required by FancyGetopt.