更改enroll命名,添加了注释,向get_error_msg中添加了一些错误代码
This commit is contained in:
@@ -1,56 +0,0 @@
|
||||
import collections
|
||||
import itertools
|
||||
|
||||
|
||||
# from jaraco.collections 3.5.1
|
||||
class DictStack(list, collections.abc.Mapping):
|
||||
"""
|
||||
A stack of dictionaries that behaves as a view on those dictionaries,
|
||||
giving preference to the last.
|
||||
|
||||
>>> stack = DictStack([dict(a=1, c=2), dict(b=2, a=2)])
|
||||
>>> stack['a']
|
||||
2
|
||||
>>> stack['b']
|
||||
2
|
||||
>>> stack['c']
|
||||
2
|
||||
>>> len(stack)
|
||||
3
|
||||
>>> stack.push(dict(a=3))
|
||||
>>> stack['a']
|
||||
3
|
||||
>>> set(stack.keys()) == set(['a', 'b', 'c'])
|
||||
True
|
||||
>>> set(stack.items()) == set([('a', 3), ('b', 2), ('c', 2)])
|
||||
True
|
||||
>>> dict(**stack) == dict(stack) == dict(a=3, c=2, b=2)
|
||||
True
|
||||
>>> d = stack.pop()
|
||||
>>> stack['a']
|
||||
2
|
||||
>>> d = stack.pop()
|
||||
>>> stack['a']
|
||||
1
|
||||
>>> stack.get('b', None)
|
||||
>>> 'c' in stack
|
||||
True
|
||||
"""
|
||||
|
||||
def __iter__(self):
|
||||
dicts = list.__iter__(self)
|
||||
return iter(set(itertools.chain.from_iterable(c.keys() for c in dicts)))
|
||||
|
||||
def __getitem__(self, key):
|
||||
for scope in reversed(tuple(list.__iter__(self))):
|
||||
if key in scope:
|
||||
return scope[key]
|
||||
raise KeyError(key)
|
||||
|
||||
push = list.append
|
||||
|
||||
def __contains__(self, other):
|
||||
return collections.abc.Mapping.__contains__(self, other)
|
||||
|
||||
def __len__(self):
|
||||
return len(list(iter(self)))
|
||||
@@ -1,12 +0,0 @@
|
||||
import sys
|
||||
import importlib
|
||||
|
||||
|
||||
def bypass_compiler_fixup(cmd, args):
|
||||
return cmd
|
||||
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
compiler_fixup = importlib.import_module('_osx_support').compiler_fixup
|
||||
else:
|
||||
compiler_fixup = bypass_compiler_fixup
|
||||
@@ -203,7 +203,7 @@ class MSVCCompiler(CCompiler) :
|
||||
|
||||
|
||||
def __init__(self, verbose=0, dry_run=0, force=0):
|
||||
super().__init__(verbose, dry_run, force)
|
||||
CCompiler.__init__ (self, verbose, dry_run, force)
|
||||
# target platform (.plat_name is consistent with 'bdist')
|
||||
self.plat_name = None
|
||||
self.initialized = False
|
||||
|
||||
@@ -55,7 +55,7 @@ class BCPPCompiler(CCompiler) :
|
||||
dry_run=0,
|
||||
force=0):
|
||||
|
||||
super().__init__(verbose, dry_run, force)
|
||||
CCompiler.__init__ (self, verbose, dry_run, force)
|
||||
|
||||
# These executables are assumed to all be in the path.
|
||||
# Borland doesn't seem to use any special registry settings to
|
||||
|
||||
@@ -27,7 +27,7 @@ class PyDialog(Dialog):
|
||||
def __init__(self, *args, **kw):
|
||||
"""Dialog(database, name, x, y, w, h, attributes, title, first,
|
||||
default, cancel, bitmap=true)"""
|
||||
super().__init__(*args)
|
||||
Dialog.__init__(self, *args)
|
||||
ruler = self.h - 36
|
||||
bmwidth = 152*ruler/328
|
||||
#if kw.get("bitmap", True):
|
||||
|
||||
@@ -81,8 +81,7 @@ class build(Command):
|
||||
"--plat-name only supported on Windows (try "
|
||||
"using './configure --help' on your platform)")
|
||||
|
||||
plat_specifier = ".%s-%s" % (self.plat_name,
|
||||
sys.implementation.cache_tag)
|
||||
plat_specifier = ".%s-%d.%d" % (self.plat_name, *sys.version_info[:2])
|
||||
|
||||
# Make it so Python 2.x and Python 2.x with --with-pydebug don't
|
||||
# share the same build directories. Doing so confuses the build
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
Implements the Distutils 'build_scripts' command."""
|
||||
|
||||
import os
|
||||
import re
|
||||
import os, re
|
||||
from stat import ST_MODE
|
||||
from distutils import sysconfig
|
||||
from distutils.core import Command
|
||||
@@ -12,14 +11,8 @@ from distutils.util import convert_path
|
||||
from distutils import log
|
||||
import tokenize
|
||||
|
||||
shebang_pattern = re.compile('^#!.*python[0-9.]*([ \t].*)?$')
|
||||
"""
|
||||
Pattern matching a Python interpreter indicated in first line of a script.
|
||||
"""
|
||||
|
||||
# for Setuptools compatibility
|
||||
first_line_re = shebang_pattern
|
||||
|
||||
# check if Python is called on the first line with this expression
|
||||
first_line_re = re.compile(b'^#!.*python[0-9.]*([ \t].*)?$')
|
||||
|
||||
class build_scripts(Command):
|
||||
|
||||
@@ -33,11 +26,13 @@ class build_scripts(Command):
|
||||
|
||||
boolean_options = ['force']
|
||||
|
||||
|
||||
def initialize_options(self):
|
||||
self.build_dir = None
|
||||
self.scripts = None
|
||||
self.force = None
|
||||
self.executable = None
|
||||
self.outfiles = None
|
||||
|
||||
def finalize_options(self):
|
||||
self.set_undefined_options('build',
|
||||
@@ -54,117 +49,104 @@ class build_scripts(Command):
|
||||
return
|
||||
self.copy_scripts()
|
||||
|
||||
def copy_scripts(self):
|
||||
"""
|
||||
Copy each script listed in ``self.scripts``.
|
||||
|
||||
If a script is marked as a Python script (first line matches
|
||||
'shebang_pattern', i.e. starts with ``#!`` and contains
|
||||
"python"), then adjust in the copy the first line to refer to
|
||||
the current Python interpreter.
|
||||
def copy_scripts(self):
|
||||
r"""Copy each script listed in 'self.scripts'; if it's marked as a
|
||||
Python script in the Unix way (first line matches 'first_line_re',
|
||||
ie. starts with "\#!" and contains "python"), then adjust the first
|
||||
line to refer to the current Python interpreter as we copy.
|
||||
"""
|
||||
self.mkpath(self.build_dir)
|
||||
outfiles = []
|
||||
updated_files = []
|
||||
for script in self.scripts:
|
||||
self._copy_script(script, outfiles, updated_files)
|
||||
adjust = False
|
||||
script = convert_path(script)
|
||||
outfile = os.path.join(self.build_dir, os.path.basename(script))
|
||||
outfiles.append(outfile)
|
||||
|
||||
self._change_modes(outfiles)
|
||||
if not self.force and not newer(script, outfile):
|
||||
log.debug("not copying %s (up-to-date)", script)
|
||||
continue
|
||||
|
||||
return outfiles, updated_files
|
||||
# Always open the file, but ignore failures in dry-run mode --
|
||||
# that way, we'll get accurate feedback if we can read the
|
||||
# script.
|
||||
try:
|
||||
f = open(script, "rb")
|
||||
except OSError:
|
||||
if not self.dry_run:
|
||||
raise
|
||||
f = None
|
||||
else:
|
||||
encoding, lines = tokenize.detect_encoding(f.readline)
|
||||
f.seek(0)
|
||||
first_line = f.readline()
|
||||
if not first_line:
|
||||
self.warn("%s is an empty file (skipping)" % script)
|
||||
continue
|
||||
|
||||
def _copy_script(self, script, outfiles, updated_files):
|
||||
shebang_match = None
|
||||
script = convert_path(script)
|
||||
outfile = os.path.join(self.build_dir, os.path.basename(script))
|
||||
outfiles.append(outfile)
|
||||
match = first_line_re.match(first_line)
|
||||
if match:
|
||||
adjust = True
|
||||
post_interp = match.group(1) or b''
|
||||
|
||||
if not self.force and not newer(script, outfile):
|
||||
log.debug("not copying %s (up-to-date)", script)
|
||||
return
|
||||
if adjust:
|
||||
log.info("copying and adjusting %s -> %s", script,
|
||||
self.build_dir)
|
||||
updated_files.append(outfile)
|
||||
if not self.dry_run:
|
||||
if not sysconfig.python_build:
|
||||
executable = self.executable
|
||||
else:
|
||||
executable = os.path.join(
|
||||
sysconfig.get_config_var("BINDIR"),
|
||||
"python%s%s" % (sysconfig.get_config_var("VERSION"),
|
||||
sysconfig.get_config_var("EXE")))
|
||||
executable = os.fsencode(executable)
|
||||
shebang = b"#!" + executable + post_interp + b"\n"
|
||||
# Python parser starts to read a script using UTF-8 until
|
||||
# it gets a #coding:xxx cookie. The shebang has to be the
|
||||
# first line of a file, the #coding:xxx cookie cannot be
|
||||
# written before. So the shebang has to be decodable from
|
||||
# UTF-8.
|
||||
try:
|
||||
shebang.decode('utf-8')
|
||||
except UnicodeDecodeError:
|
||||
raise ValueError(
|
||||
"The shebang ({!r}) is not decodable "
|
||||
"from utf-8".format(shebang))
|
||||
# If the script is encoded to a custom encoding (use a
|
||||
# #coding:xxx cookie), the shebang has to be decodable from
|
||||
# the script encoding too.
|
||||
try:
|
||||
shebang.decode(encoding)
|
||||
except UnicodeDecodeError:
|
||||
raise ValueError(
|
||||
"The shebang ({!r}) is not decodable "
|
||||
"from the script encoding ({})"
|
||||
.format(shebang, encoding))
|
||||
with open(outfile, "wb") as outf:
|
||||
outf.write(shebang)
|
||||
outf.writelines(f.readlines())
|
||||
if f:
|
||||
f.close()
|
||||
else:
|
||||
if f:
|
||||
f.close()
|
||||
updated_files.append(outfile)
|
||||
self.copy_file(script, outfile)
|
||||
|
||||
# Always open the file, but ignore failures in dry-run mode
|
||||
# in order to attempt to copy directly.
|
||||
try:
|
||||
f = tokenize.open(script)
|
||||
except OSError:
|
||||
if not self.dry_run:
|
||||
raise
|
||||
f = None
|
||||
else:
|
||||
first_line = f.readline()
|
||||
if not first_line:
|
||||
self.warn("%s is an empty file (skipping)" % script)
|
||||
return
|
||||
|
||||
shebang_match = shebang_pattern.match(first_line)
|
||||
|
||||
updated_files.append(outfile)
|
||||
if shebang_match:
|
||||
log.info("copying and adjusting %s -> %s", script,
|
||||
self.build_dir)
|
||||
if not self.dry_run:
|
||||
if not sysconfig.python_build:
|
||||
executable = self.executable
|
||||
if os.name == 'posix':
|
||||
for file in outfiles:
|
||||
if self.dry_run:
|
||||
log.info("changing mode of %s", file)
|
||||
else:
|
||||
executable = os.path.join(
|
||||
sysconfig.get_config_var("BINDIR"),
|
||||
"python%s%s" % (
|
||||
sysconfig.get_config_var("VERSION"),
|
||||
sysconfig.get_config_var("EXE")))
|
||||
post_interp = shebang_match.group(1) or ''
|
||||
shebang = "#!" + executable + post_interp + "\n"
|
||||
self._validate_shebang(shebang, f.encoding)
|
||||
with open(outfile, "w", encoding=f.encoding) as outf:
|
||||
outf.write(shebang)
|
||||
outf.writelines(f.readlines())
|
||||
if f:
|
||||
f.close()
|
||||
else:
|
||||
if f:
|
||||
f.close()
|
||||
self.copy_file(script, outfile)
|
||||
|
||||
def _change_modes(self, outfiles):
|
||||
if os.name != 'posix':
|
||||
return
|
||||
|
||||
for file in outfiles:
|
||||
self._change_mode(file)
|
||||
|
||||
def _change_mode(self, file):
|
||||
if self.dry_run:
|
||||
log.info("changing mode of %s", file)
|
||||
return
|
||||
|
||||
oldmode = os.stat(file)[ST_MODE] & 0o7777
|
||||
newmode = (oldmode | 0o555) & 0o7777
|
||||
if newmode != oldmode:
|
||||
log.info("changing mode of %s from %o to %o",
|
||||
file, oldmode, newmode)
|
||||
os.chmod(file, newmode)
|
||||
|
||||
@staticmethod
|
||||
def _validate_shebang(shebang, encoding):
|
||||
# Python parser starts to read a script using UTF-8 until
|
||||
# it gets a #coding:xxx cookie. The shebang has to be the
|
||||
# first line of a file, the #coding:xxx cookie cannot be
|
||||
# written before. So the shebang has to be encodable to
|
||||
# UTF-8.
|
||||
try:
|
||||
shebang.encode('utf-8')
|
||||
except UnicodeEncodeError:
|
||||
raise ValueError(
|
||||
"The shebang ({!r}) is not encodable "
|
||||
"to utf-8".format(shebang))
|
||||
|
||||
# If the script is encoded to a custom encoding (use a
|
||||
# #coding:xxx cookie), the shebang has to be encodable to
|
||||
# the script encoding too.
|
||||
try:
|
||||
shebang.encode(encoding)
|
||||
except UnicodeEncodeError:
|
||||
raise ValueError(
|
||||
"The shebang ({!r}) is not encodable "
|
||||
"to the script encoding ({})"
|
||||
.format(shebang, encoding))
|
||||
oldmode = os.stat(file)[ST_MODE] & 0o7777
|
||||
newmode = (oldmode | 0o555) & 0o7777
|
||||
if newmode != oldmode:
|
||||
log.info("changing mode of %s from %o to %o",
|
||||
file, oldmode, newmode)
|
||||
os.chmod(file, newmode)
|
||||
# XXX should we modify self.outfiles?
|
||||
return outfiles, updated_files
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
Implements the Distutils 'check' command.
|
||||
"""
|
||||
from email.utils import getaddresses
|
||||
|
||||
from distutils.core import Command
|
||||
from distutils.errors import DistutilsSetupError
|
||||
|
||||
@@ -19,7 +17,7 @@ try:
|
||||
def __init__(self, source, report_level, halt_level, stream=None,
|
||||
debug=0, encoding='ascii', error_handler='replace'):
|
||||
self.messages = []
|
||||
super().__init__(source, report_level, halt_level, stream,
|
||||
Reporter.__init__(self, source, report_level, halt_level, stream,
|
||||
debug, encoding, error_handler)
|
||||
|
||||
def system_message(self, level, message, *children, **kwargs):
|
||||
@@ -98,39 +96,19 @@ class check(Command):
|
||||
|
||||
if missing:
|
||||
self.warn("missing required meta-data: %s" % ', '.join(missing))
|
||||
if not (
|
||||
self._check_contact("author", metadata) or
|
||||
self._check_contact("maintainer", metadata)
|
||||
):
|
||||
if metadata.author:
|
||||
if not metadata.author_email:
|
||||
self.warn("missing meta-data: if 'author' supplied, " +
|
||||
"'author_email' should be supplied too")
|
||||
elif metadata.maintainer:
|
||||
if not metadata.maintainer_email:
|
||||
self.warn("missing meta-data: if 'maintainer' supplied, " +
|
||||
"'maintainer_email' should be supplied too")
|
||||
else:
|
||||
self.warn("missing meta-data: either (author and author_email) " +
|
||||
"or (maintainer and maintainer_email) " +
|
||||
"should be supplied")
|
||||
|
||||
def _check_contact(self, kind, metadata):
|
||||
"""
|
||||
Returns True if the contact's name is specified and False otherwise.
|
||||
This function will warn if the contact's email is not specified.
|
||||
"""
|
||||
name = getattr(metadata, kind) or ''
|
||||
email = getattr(metadata, kind + '_email') or ''
|
||||
|
||||
msg = ("missing meta-data: if '{}' supplied, " +
|
||||
"'{}' should be supplied too")
|
||||
|
||||
if name and email:
|
||||
return True
|
||||
|
||||
if name:
|
||||
self.warn(msg.format(kind, kind + '_email'))
|
||||
return True
|
||||
|
||||
addresses = [(alias, addr) for alias, addr in getaddresses([email])]
|
||||
if any(alias and addr for alias, addr in addresses):
|
||||
# The contact's name can be encoded in the email: `Name <email>`
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def check_restructuredtext(self):
|
||||
"""Checks if the long string fields are reST-compliant."""
|
||||
data = self.distribution.get_long_description()
|
||||
|
||||
@@ -17,7 +17,6 @@ from distutils.file_util import write_file
|
||||
from distutils.util import convert_path, subst_vars, change_root
|
||||
from distutils.util import get_platform
|
||||
from distutils.errors import DistutilsOptionError
|
||||
from .. import _collections
|
||||
|
||||
from site import USER_BASE
|
||||
from site import USER_SITE
|
||||
@@ -68,8 +67,8 @@ if HAS_USER_SITE:
|
||||
INSTALL_SCHEMES['nt_user'] = {
|
||||
'purelib': '{usersite}',
|
||||
'platlib': '{usersite}',
|
||||
'headers': '{userbase}/{implementation}{py_version_nodot_plat}/Include/{dist_name}',
|
||||
'scripts': '{userbase}/{implementation}{py_version_nodot_plat}/Scripts',
|
||||
'headers': '{userbase}/{implementation}{py_version_nodot}/Include/{dist_name}',
|
||||
'scripts': '{userbase}/{implementation}{py_version_nodot}/Scripts',
|
||||
'data' : '{userbase}',
|
||||
}
|
||||
|
||||
@@ -395,35 +394,26 @@ class install(Command):
|
||||
except AttributeError:
|
||||
# sys.abiflags may not be defined on all platforms.
|
||||
abiflags = ''
|
||||
local_vars = {
|
||||
'dist_name': self.distribution.get_name(),
|
||||
'dist_version': self.distribution.get_version(),
|
||||
'dist_fullname': self.distribution.get_fullname(),
|
||||
'py_version': py_version,
|
||||
'py_version_short': '%d.%d' % sys.version_info[:2],
|
||||
'py_version_nodot': '%d%d' % sys.version_info[:2],
|
||||
'sys_prefix': prefix,
|
||||
'prefix': prefix,
|
||||
'sys_exec_prefix': exec_prefix,
|
||||
'exec_prefix': exec_prefix,
|
||||
'abiflags': abiflags,
|
||||
'platlibdir': getattr(sys, 'platlibdir', 'lib'),
|
||||
'implementation_lower': _get_implementation().lower(),
|
||||
'implementation': _get_implementation(),
|
||||
}
|
||||
|
||||
# vars for compatibility on older Pythons
|
||||
compat_vars = dict(
|
||||
# Python 3.9 and earlier
|
||||
py_version_nodot_plat=getattr(sys, 'winver', '').replace('.', ''),
|
||||
)
|
||||
self.config_vars = {'dist_name': self.distribution.get_name(),
|
||||
'dist_version': self.distribution.get_version(),
|
||||
'dist_fullname': self.distribution.get_fullname(),
|
||||
'py_version': py_version,
|
||||
'py_version_short': '%d.%d' % sys.version_info[:2],
|
||||
'py_version_nodot': '%d%d' % sys.version_info[:2],
|
||||
'sys_prefix': prefix,
|
||||
'prefix': prefix,
|
||||
'sys_exec_prefix': exec_prefix,
|
||||
'exec_prefix': exec_prefix,
|
||||
'abiflags': abiflags,
|
||||
'platlibdir': getattr(sys, 'platlibdir', 'lib'),
|
||||
'implementation_lower': _get_implementation().lower(),
|
||||
'implementation': _get_implementation(),
|
||||
'platsubdir': sysconfig.get_config_var('platsubdir'),
|
||||
}
|
||||
|
||||
if HAS_USER_SITE:
|
||||
local_vars['userbase'] = self.install_userbase
|
||||
local_vars['usersite'] = self.install_usersite
|
||||
|
||||
self.config_vars = _collections.DictStack(
|
||||
[compat_vars, sysconfig.get_config_vars(), local_vars])
|
||||
self.config_vars['userbase'] = self.install_userbase
|
||||
self.config_vars['usersite'] = self.install_usersite
|
||||
|
||||
self.expand_basedirs()
|
||||
|
||||
@@ -431,13 +421,15 @@ class install(Command):
|
||||
|
||||
# Now define config vars for the base directories so we can expand
|
||||
# everything else.
|
||||
local_vars['base'] = self.install_base
|
||||
local_vars['platbase'] = self.install_platbase
|
||||
self.config_vars['base'] = self.install_base
|
||||
self.config_vars['platbase'] = self.install_platbase
|
||||
self.config_vars['installed_base'] = (
|
||||
sysconfig.get_config_vars()['installed_base'])
|
||||
|
||||
if DEBUG:
|
||||
from pprint import pprint
|
||||
print("config vars:")
|
||||
pprint(dict(self.config_vars))
|
||||
pprint(self.config_vars)
|
||||
|
||||
# Expand "~" and configuration variables in the installation
|
||||
# directories.
|
||||
|
||||
@@ -108,7 +108,7 @@ class CygwinCCompiler(UnixCCompiler):
|
||||
|
||||
def __init__(self, verbose=0, dry_run=0, force=0):
|
||||
|
||||
super().__init__(verbose, dry_run, force)
|
||||
UnixCCompiler.__init__(self, verbose, dry_run, force)
|
||||
|
||||
status, details = check_config_h()
|
||||
self.debug_print("Python's GCC status: %s (details: %s)" %
|
||||
@@ -268,7 +268,7 @@ class Mingw32CCompiler(CygwinCCompiler):
|
||||
|
||||
def __init__(self, verbose=0, dry_run=0, force=0):
|
||||
|
||||
super().__init__ (verbose, dry_run, force)
|
||||
CygwinCCompiler.__init__ (self, verbose, dry_run, force)
|
||||
|
||||
shared_option = "-shared"
|
||||
|
||||
|
||||
@@ -324,7 +324,7 @@ class MSVCCompiler(CCompiler) :
|
||||
exe_extension = '.exe'
|
||||
|
||||
def __init__(self, verbose=0, dry_run=0, force=0):
|
||||
super().__init__(verbose, dry_run, force)
|
||||
CCompiler.__init__ (self, verbose, dry_run, force)
|
||||
self.__version = VERSION
|
||||
self.__root = r"Software\Microsoft\VisualStudio"
|
||||
# self.__macros = MACROS
|
||||
|
||||
@@ -228,7 +228,7 @@ class MSVCCompiler(CCompiler) :
|
||||
exe_extension = '.exe'
|
||||
|
||||
def __init__(self, verbose=0, dry_run=0, force=0):
|
||||
super().__init__(verbose, dry_run, force)
|
||||
CCompiler.__init__ (self, verbose, dry_run, force)
|
||||
self.__version = get_build_version()
|
||||
self.__arch = get_build_architecture()
|
||||
if self.__arch == "Intel":
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import sys
|
||||
import platform
|
||||
|
||||
|
||||
def add_ext_suffix_39(vars):
|
||||
"""
|
||||
Ensure vars contains 'EXT_SUFFIX'. pypa/distutils#130
|
||||
"""
|
||||
import _imp
|
||||
ext_suffix = _imp.extension_suffixes()[0]
|
||||
vars.update(
|
||||
EXT_SUFFIX=ext_suffix,
|
||||
# sysconfig sets SO to match EXT_SUFFIX, so maintain
|
||||
# that expectation.
|
||||
# https://github.com/python/cpython/blob/785cc6770588de087d09e89a69110af2542be208/Lib/sysconfig.py#L671-L673
|
||||
SO=ext_suffix,
|
||||
)
|
||||
|
||||
|
||||
needs_ext_suffix = sys.version_info < (3, 10) and platform.system() == 'Windows'
|
||||
add_ext_suffix = add_ext_suffix_39 if needs_ext_suffix else lambda vars: None
|
||||
@@ -10,7 +10,7 @@ import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from distutils.errors import DistutilsExecError
|
||||
from distutils.errors import DistutilsPlatformError, DistutilsExecError
|
||||
from distutils.debug import DEBUG
|
||||
from distutils import log
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ Written by: Fred L. Drake, Jr.
|
||||
Email: <fdrake@acm.org>
|
||||
"""
|
||||
|
||||
import _imp
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import sysconfig
|
||||
|
||||
from .errors import DistutilsPlatformError
|
||||
from . import py39compat
|
||||
|
||||
IS_PYPY = '__pypy__' in sys.builtin_module_names
|
||||
|
||||
@@ -48,7 +48,6 @@ def _is_python_source_dir(d):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
_sys_home = getattr(sys, '_home', None)
|
||||
|
||||
if os.name == 'nt':
|
||||
@@ -60,13 +59,11 @@ if os.name == 'nt':
|
||||
project_base = _fix_pcbuild(project_base)
|
||||
_sys_home = _fix_pcbuild(_sys_home)
|
||||
|
||||
|
||||
def _python_build():
|
||||
if _sys_home:
|
||||
return _is_python_source_dir(_sys_home)
|
||||
return _is_python_source_dir(project_base)
|
||||
|
||||
|
||||
python_build = _python_build()
|
||||
|
||||
|
||||
@@ -82,7 +79,6 @@ except AttributeError:
|
||||
# this attribute, which is fine.
|
||||
pass
|
||||
|
||||
|
||||
def get_python_version():
|
||||
"""Return a string containing the major and minor Python version,
|
||||
leaving off the patchlevel. Sample return values could be '1.5'
|
||||
@@ -196,6 +192,7 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
|
||||
"on platform '%s'" % os.name)
|
||||
|
||||
|
||||
|
||||
def customize_compiler(compiler):
|
||||
"""Do any platform-specific customization of a CCompiler instance.
|
||||
|
||||
@@ -220,9 +217,8 @@ def customize_compiler(compiler):
|
||||
_config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True'
|
||||
|
||||
(cc, cxx, cflags, ccshared, ldshared, shlib_suffix, ar, ar_flags) = \
|
||||
get_config_vars(
|
||||
'CC', 'CXX', 'CFLAGS',
|
||||
'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS')
|
||||
get_config_vars('CC', 'CXX', 'CFLAGS',
|
||||
'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS')
|
||||
|
||||
if 'CC' in os.environ:
|
||||
newcc = os.environ['CC']
|
||||
@@ -284,6 +280,7 @@ def get_config_h_filename():
|
||||
return sysconfig.get_config_h_filename()
|
||||
|
||||
|
||||
|
||||
def get_makefile_filename():
|
||||
"""Return full pathname of installed Makefile from the Python build."""
|
||||
return sysconfig.get_makefile_filename()
|
||||
@@ -305,7 +302,6 @@ _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
|
||||
_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
|
||||
_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
|
||||
|
||||
|
||||
def parse_makefile(fn, g=None):
|
||||
"""Parse a Makefile-style file.
|
||||
|
||||
@@ -314,9 +310,7 @@ def parse_makefile(fn, g=None):
|
||||
used instead of a new dictionary.
|
||||
"""
|
||||
from distutils.text_file import TextFile
|
||||
fp = TextFile(
|
||||
fn, strip_comments=1, skip_blanks=1, join_lines=1,
|
||||
errors="surrogateescape")
|
||||
fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1, errors="surrogateescape")
|
||||
|
||||
if g is None:
|
||||
g = {}
|
||||
@@ -325,7 +319,7 @@ def parse_makefile(fn, g=None):
|
||||
|
||||
while True:
|
||||
line = fp.readline()
|
||||
if line is None: # eof
|
||||
if line is None: # eof
|
||||
break
|
||||
m = _variable_rx.match(line)
|
||||
if m:
|
||||
@@ -369,8 +363,7 @@ def parse_makefile(fn, g=None):
|
||||
item = os.environ[n]
|
||||
|
||||
elif n in renamed_variables:
|
||||
if name.startswith('PY_') and \
|
||||
name[3:] in renamed_variables:
|
||||
if name.startswith('PY_') and name[3:] in renamed_variables:
|
||||
item = ""
|
||||
|
||||
elif 'PY_' + n in notdone:
|
||||
@@ -386,8 +379,7 @@ def parse_makefile(fn, g=None):
|
||||
if "$" in after:
|
||||
notdone[name] = value
|
||||
else:
|
||||
try:
|
||||
value = int(value)
|
||||
try: value = int(value)
|
||||
except ValueError:
|
||||
done[name] = value.strip()
|
||||
else:
|
||||
@@ -395,7 +387,7 @@ def parse_makefile(fn, g=None):
|
||||
del notdone[name]
|
||||
|
||||
if name.startswith('PY_') \
|
||||
and name[3:] in renamed_variables:
|
||||
and name[3:] in renamed_variables:
|
||||
|
||||
name = name[3:]
|
||||
if name not in done:
|
||||
@@ -444,6 +436,51 @@ def expand_makefile_vars(s, vars):
|
||||
_config_vars = None
|
||||
|
||||
|
||||
_sysconfig_name_tmpl = '_sysconfigdata_{abi}_{platform}_{multiarch}'
|
||||
|
||||
|
||||
def _init_posix():
|
||||
"""Initialize the module as appropriate for POSIX systems."""
|
||||
# _sysconfigdata is generated at build time, see the sysconfig module
|
||||
name = os.environ.get(
|
||||
'_PYTHON_SYSCONFIGDATA_NAME',
|
||||
_sysconfig_name_tmpl.format(
|
||||
abi=sys.abiflags,
|
||||
platform=sys.platform,
|
||||
multiarch=getattr(sys.implementation, '_multiarch', ''),
|
||||
),
|
||||
)
|
||||
try:
|
||||
_temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
|
||||
except ImportError:
|
||||
# Python 3.5 and pypy 7.3.1
|
||||
_temp = __import__(
|
||||
'_sysconfigdata', globals(), locals(), ['build_time_vars'], 0)
|
||||
build_time_vars = _temp.build_time_vars
|
||||
global _config_vars
|
||||
_config_vars = {}
|
||||
_config_vars.update(build_time_vars)
|
||||
|
||||
|
||||
def _init_nt():
|
||||
"""Initialize the module as appropriate for NT"""
|
||||
g = {}
|
||||
# set basic install directories
|
||||
g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
|
||||
g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
|
||||
|
||||
# XXX hmmm.. a normal install puts include files here
|
||||
g['INCLUDEPY'] = get_python_inc(plat_specific=0)
|
||||
|
||||
g['EXT_SUFFIX'] = _imp.extension_suffixes()[0]
|
||||
g['EXE'] = ".exe"
|
||||
g['VERSION'] = get_python_version().replace(".", "")
|
||||
g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable))
|
||||
|
||||
global _config_vars
|
||||
_config_vars = g
|
||||
|
||||
|
||||
def get_config_vars(*args):
|
||||
"""With no arguments, return a dictionary of all configuration
|
||||
variables relevant for the current platform. Generally this includes
|
||||
@@ -456,8 +493,60 @@ def get_config_vars(*args):
|
||||
"""
|
||||
global _config_vars
|
||||
if _config_vars is None:
|
||||
_config_vars = sysconfig.get_config_vars().copy()
|
||||
py39compat.add_ext_suffix(_config_vars)
|
||||
func = globals().get("_init_" + os.name)
|
||||
if func:
|
||||
func()
|
||||
else:
|
||||
_config_vars = {}
|
||||
|
||||
# Normalized versions of prefix and exec_prefix are handy to have;
|
||||
# in fact, these are the standard versions used most places in the
|
||||
# Distutils.
|
||||
_config_vars['prefix'] = PREFIX
|
||||
_config_vars['exec_prefix'] = EXEC_PREFIX
|
||||
|
||||
if not IS_PYPY:
|
||||
# For backward compatibility, see issue19555
|
||||
SO = _config_vars.get('EXT_SUFFIX')
|
||||
if SO is not None:
|
||||
_config_vars['SO'] = SO
|
||||
|
||||
# Always convert srcdir to an absolute path
|
||||
srcdir = _config_vars.get('srcdir', project_base)
|
||||
if os.name == 'posix':
|
||||
if python_build:
|
||||
# If srcdir is a relative path (typically '.' or '..')
|
||||
# then it should be interpreted relative to the directory
|
||||
# containing Makefile.
|
||||
base = os.path.dirname(get_makefile_filename())
|
||||
srcdir = os.path.join(base, srcdir)
|
||||
else:
|
||||
# srcdir is not meaningful since the installation is
|
||||
# spread about the filesystem. We choose the
|
||||
# directory containing the Makefile since we know it
|
||||
# exists.
|
||||
srcdir = os.path.dirname(get_makefile_filename())
|
||||
_config_vars['srcdir'] = os.path.abspath(os.path.normpath(srcdir))
|
||||
|
||||
# Convert srcdir into an absolute path if it appears necessary.
|
||||
# Normally it is relative to the build directory. However, during
|
||||
# testing, for example, we might be running a non-installed python
|
||||
# from a different directory.
|
||||
if python_build and os.name == "posix":
|
||||
base = project_base
|
||||
if (not os.path.isabs(_config_vars['srcdir']) and
|
||||
base != os.getcwd()):
|
||||
# srcdir is relative and we are not in the same directory
|
||||
# as the executable. Assume executable is in the build
|
||||
# directory and make srcdir absolute.
|
||||
srcdir = os.path.join(base, _config_vars['srcdir'])
|
||||
_config_vars['srcdir'] = os.path.normpath(srcdir)
|
||||
|
||||
# OS X platforms require special customization to handle
|
||||
# multi-architecture, multi-os-version installers
|
||||
if sys.platform == 'darwin':
|
||||
import _osx_support
|
||||
_osx_support.customize_config_vars(_config_vars)
|
||||
|
||||
if args:
|
||||
vals = []
|
||||
@@ -467,7 +556,6 @@ def get_config_vars(*args):
|
||||
else:
|
||||
return _config_vars
|
||||
|
||||
|
||||
def get_config_var(name):
|
||||
"""Return the value of a single variable using the dictionary
|
||||
returned by 'get_config_vars()'. Equivalent to
|
||||
@@ -475,6 +563,5 @@ def get_config_var(name):
|
||||
"""
|
||||
if name == 'SO':
|
||||
import warnings
|
||||
warnings.warn(
|
||||
'SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2)
|
||||
warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2)
|
||||
return get_config_vars().get(name)
|
||||
|
||||
@@ -22,7 +22,9 @@ from distutils.ccompiler import \
|
||||
from distutils.errors import \
|
||||
DistutilsExecError, CompileError, LibError, LinkError
|
||||
from distutils import log
|
||||
from ._macos_compat import compiler_fixup
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
import _osx_support
|
||||
|
||||
# XXX Things not currently handled:
|
||||
# * optimization/debug/warning flags; we just use whatever's in Python's
|
||||
@@ -40,66 +42,6 @@ from ._macos_compat import compiler_fixup
|
||||
# options and carry on.
|
||||
|
||||
|
||||
def _split_env(cmd):
|
||||
"""
|
||||
For macOS, split command into 'env' portion (if any)
|
||||
and the rest of the linker command.
|
||||
|
||||
>>> _split_env(['a', 'b', 'c'])
|
||||
([], ['a', 'b', 'c'])
|
||||
>>> _split_env(['/usr/bin/env', 'A=3', 'gcc'])
|
||||
(['/usr/bin/env', 'A=3'], ['gcc'])
|
||||
"""
|
||||
pivot = 0
|
||||
if os.path.basename(cmd[0]) == "env":
|
||||
pivot = 1
|
||||
while '=' in cmd[pivot]:
|
||||
pivot += 1
|
||||
return cmd[:pivot], cmd[pivot:]
|
||||
|
||||
|
||||
def _split_aix(cmd):
|
||||
"""
|
||||
AIX platforms prefix the compiler with the ld_so_aix
|
||||
script, so split that from the linker command.
|
||||
|
||||
>>> _split_aix(['a', 'b', 'c'])
|
||||
([], ['a', 'b', 'c'])
|
||||
>>> _split_aix(['/bin/foo/ld_so_aix', 'gcc'])
|
||||
(['/bin/foo/ld_so_aix'], ['gcc'])
|
||||
"""
|
||||
pivot = os.path.basename(cmd[0]) == 'ld_so_aix'
|
||||
return cmd[:pivot], cmd[pivot:]
|
||||
|
||||
|
||||
def _linker_params(linker_cmd, compiler_cmd):
|
||||
"""
|
||||
The linker command usually begins with the compiler
|
||||
command (possibly multiple elements), followed by zero or more
|
||||
params for shared library building.
|
||||
|
||||
If the LDSHARED env variable overrides the linker command,
|
||||
however, the commands may not match.
|
||||
|
||||
Return the best guess of the linker parameters by stripping
|
||||
the linker command. If the compiler command does not
|
||||
match the linker command, assume the linker command is
|
||||
just the first element.
|
||||
|
||||
>>> _linker_params('gcc foo bar'.split(), ['gcc'])
|
||||
['foo', 'bar']
|
||||
>>> _linker_params('gcc foo bar'.split(), ['other'])
|
||||
['foo', 'bar']
|
||||
>>> _linker_params('ccache gcc foo bar'.split(), 'ccache gcc'.split())
|
||||
['foo', 'bar']
|
||||
>>> _linker_params(['gcc'], ['gcc'])
|
||||
[]
|
||||
"""
|
||||
c_len = len(compiler_cmd)
|
||||
pivot = c_len if linker_cmd[:c_len] == compiler_cmd else 1
|
||||
return linker_cmd[pivot:]
|
||||
|
||||
|
||||
class UnixCCompiler(CCompiler):
|
||||
|
||||
compiler_type = 'unix'
|
||||
@@ -167,8 +109,10 @@ class UnixCCompiler(CCompiler):
|
||||
raise CompileError(msg)
|
||||
|
||||
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
|
||||
compiler_so = compiler_fixup(
|
||||
self.compiler_so, cc_args + extra_postargs)
|
||||
compiler_so = self.compiler_so
|
||||
if sys.platform == 'darwin':
|
||||
compiler_so = _osx_support.compiler_fixup(compiler_so,
|
||||
cc_args + extra_postargs)
|
||||
try:
|
||||
self.spawn(compiler_so + cc_args + [src, '-o', obj] +
|
||||
extra_postargs)
|
||||
@@ -229,22 +173,33 @@ class UnixCCompiler(CCompiler):
|
||||
ld_args.extend(extra_postargs)
|
||||
self.mkpath(os.path.dirname(output_filename))
|
||||
try:
|
||||
# Select a linker based on context: linker_exe when
|
||||
# building an executable or linker_so (with shared options)
|
||||
# when building a shared library.
|
||||
building_exe = target_desc == CCompiler.EXECUTABLE
|
||||
linker = (self.linker_exe if building_exe else self.linker_so)[:]
|
||||
|
||||
if target_desc == CCompiler.EXECUTABLE:
|
||||
linker = self.linker_exe[:]
|
||||
else:
|
||||
linker = self.linker_so[:]
|
||||
if target_lang == "c++" and self.compiler_cxx:
|
||||
env, linker_ne = _split_env(linker)
|
||||
aix, linker_na = _split_aix(linker_ne)
|
||||
_, compiler_cxx_ne = _split_env(self.compiler_cxx)
|
||||
_, linker_exe_ne = _split_env(self.linker_exe)
|
||||
# skip over environment variable settings if /usr/bin/env
|
||||
# is used to set up the linker's environment.
|
||||
# This is needed on OSX. Note: this assumes that the
|
||||
# normal and C++ compiler have the same environment
|
||||
# settings.
|
||||
i = 0
|
||||
if os.path.basename(linker[0]) == "env":
|
||||
i = 1
|
||||
while '=' in linker[i]:
|
||||
i += 1
|
||||
|
||||
params = _linker_params(linker_na, linker_exe_ne)
|
||||
linker = env + aix + compiler_cxx_ne + params
|
||||
if os.path.basename(linker[i]) == 'ld_so_aix':
|
||||
# AIX platforms prefix the compiler with the ld_so_aix
|
||||
# script, so we need to adjust our linker index
|
||||
offset = 1
|
||||
else:
|
||||
offset = 0
|
||||
|
||||
linker = compiler_fixup(linker, ld_args)
|
||||
linker[i+offset] = self.compiler_cxx[i]
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
linker = _osx_support.compiler_fixup(linker, ld_args)
|
||||
|
||||
self.spawn(linker + ld_args)
|
||||
except DistutilsExecError as msg:
|
||||
|
||||
@@ -9,7 +9,6 @@ import re
|
||||
import importlib.util
|
||||
import string
|
||||
import sys
|
||||
import sysconfig
|
||||
from distutils.errors import DistutilsPlatformError
|
||||
from distutils.dep_util import newer
|
||||
from distutils.spawn import spawn
|
||||
@@ -21,29 +20,82 @@ from .py35compat import _optim_args_from_interpreter_flags
|
||||
def get_host_platform():
|
||||
"""Return a string that identifies the current platform. This is used mainly to
|
||||
distinguish platform-specific build directories and platform-specific built
|
||||
distributions.
|
||||
distributions. Typically includes the OS name and version and the
|
||||
architecture (as supplied by 'os.uname()'), although the exact information
|
||||
included depends on the OS; eg. on Linux, the kernel version isn't
|
||||
particularly important.
|
||||
|
||||
Examples of returned values:
|
||||
linux-i586
|
||||
linux-alpha (?)
|
||||
solaris-2.6-sun4u
|
||||
|
||||
Windows will return one of:
|
||||
win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
|
||||
win32 (all others - specifically, sys.platform is returned)
|
||||
|
||||
For other non-POSIX platforms, currently just returns 'sys.platform'.
|
||||
|
||||
"""
|
||||
if os.name == 'nt':
|
||||
if 'amd64' in sys.version.lower():
|
||||
return 'win-amd64'
|
||||
if '(arm)' in sys.version.lower():
|
||||
return 'win-arm32'
|
||||
if '(arm64)' in sys.version.lower():
|
||||
return 'win-arm64'
|
||||
return sys.platform
|
||||
|
||||
# We initially exposed platforms as defined in Python 3.9
|
||||
# even with older Python versions when distutils was split out.
|
||||
# Now that we delegate to stdlib sysconfig we need to restore this
|
||||
# in case anyone has started to depend on it.
|
||||
# Set for cross builds explicitly
|
||||
if "_PYTHON_HOST_PLATFORM" in os.environ:
|
||||
return os.environ["_PYTHON_HOST_PLATFORM"]
|
||||
|
||||
if sys.version_info < (3, 8):
|
||||
if os.name == 'nt':
|
||||
if '(arm)' in sys.version.lower():
|
||||
return 'win-arm32'
|
||||
if '(arm64)' in sys.version.lower():
|
||||
return 'win-arm64'
|
||||
if os.name != "posix" or not hasattr(os, 'uname'):
|
||||
# XXX what about the architecture? NT is Intel or Alpha,
|
||||
# Mac OS is M68k or PPC, etc.
|
||||
return sys.platform
|
||||
|
||||
if sys.version_info < (3, 9):
|
||||
if os.name == "posix" and hasattr(os, 'uname'):
|
||||
osname, host, release, version, machine = os.uname()
|
||||
if osname[:3] == "aix":
|
||||
from .py38compat import aix_platform
|
||||
return aix_platform(osname, version, release)
|
||||
# Try to distinguish various flavours of Unix
|
||||
|
||||
return sysconfig.get_platform()
|
||||
(osname, host, release, version, machine) = os.uname()
|
||||
|
||||
# Convert the OS name to lowercase, remove '/' characters, and translate
|
||||
# spaces (for "Power Macintosh")
|
||||
osname = osname.lower().replace('/', '')
|
||||
machine = machine.replace(' ', '_')
|
||||
machine = machine.replace('/', '-')
|
||||
|
||||
if osname[:5] == "linux":
|
||||
# At least on Linux/Intel, 'machine' is the processor --
|
||||
# i386, etc.
|
||||
# XXX what about Alpha, SPARC, etc?
|
||||
return "%s-%s" % (osname, machine)
|
||||
elif osname[:5] == "sunos":
|
||||
if release[0] >= "5": # SunOS 5 == Solaris 2
|
||||
osname = "solaris"
|
||||
release = "%d.%s" % (int(release[0]) - 3, release[2:])
|
||||
# We can't use "platform.architecture()[0]" because a
|
||||
# bootstrap problem. We use a dict to get an error
|
||||
# if some suspicious happens.
|
||||
bitness = {2147483647:"32bit", 9223372036854775807:"64bit"}
|
||||
machine += ".%s" % bitness[sys.maxsize]
|
||||
# fall through to standard osname-release-machine representation
|
||||
elif osname[:3] == "aix":
|
||||
from .py38compat import aix_platform
|
||||
return aix_platform(osname, version, release)
|
||||
elif osname[:6] == "cygwin":
|
||||
osname = "cygwin"
|
||||
rel_re = re.compile (r'[\d.]+', re.ASCII)
|
||||
m = rel_re.match(release)
|
||||
if m:
|
||||
release = m.group()
|
||||
elif osname[:6] == "darwin":
|
||||
import _osx_support, distutils.sysconfig
|
||||
osname, release, machine = _osx_support.get_platform_osx(
|
||||
distutils.sysconfig.get_config_vars(),
|
||||
osname, release, machine)
|
||||
|
||||
return "%s-%s-%s" % (osname, release, machine)
|
||||
|
||||
def get_platform():
|
||||
if os.name == 'nt':
|
||||
|
||||
@@ -50,14 +50,14 @@ class Version:
|
||||
"""
|
||||
|
||||
def __init__ (self, vstring=None):
|
||||
if vstring:
|
||||
self.parse(vstring)
|
||||
warnings.warn(
|
||||
"distutils Version classes are deprecated. "
|
||||
"Use packaging.version instead.",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
if vstring:
|
||||
self.parse(vstring)
|
||||
|
||||
def __repr__ (self):
|
||||
return "%s ('%s')" % (self.__class__.__name__, str(self))
|
||||
|
||||
Reference in New Issue
Block a user