diff options
Diffstat (limited to 'Lib/distutils/command')
| -rw-r--r-- | Lib/distutils/command/bdist.py | 3 | ||||
| -rw-r--r-- | Lib/distutils/command/bdist_dumb.py | 3 | ||||
| -rw-r--r-- | Lib/distutils/command/bdist_wininst.py | 36 | ||||
| -rw-r--r-- | Lib/distutils/command/build.py | 9 | ||||
| -rw-r--r-- | Lib/distutils/command/build_ext.py | 107 | ||||
| -rw-r--r-- | Lib/distutils/command/build_py.py | 4 | ||||
| -rw-r--r-- | Lib/distutils/command/install.py | 2 | ||||
| -rw-r--r-- | Lib/distutils/command/install_lib.py | 16 | ||||
| -rw-r--r-- | Lib/distutils/command/upload.py | 40 | ||||
| -rw-r--r-- | Lib/distutils/command/wininst-14.0-amd64.exe | bin | 0 -> 84480 bytes | |||
| -rw-r--r-- | Lib/distutils/command/wininst-14.0.exe | bin | 0 -> 75264 bytes |
11 files changed, 131 insertions, 89 deletions
diff --git a/Lib/distutils/command/bdist.py b/Lib/distutils/command/bdist.py index 6814a1c..014871d 100644 --- a/Lib/distutils/command/bdist.py +++ b/Lib/distutils/command/bdist.py @@ -61,13 +61,14 @@ class bdist(Command): 'nt': 'zip'} # Establish the preferred order (for the --help-formats option). - format_commands = ['rpm', 'gztar', 'bztar', 'ztar', 'tar', + format_commands = ['rpm', 'gztar', 'bztar', 'xztar', 'ztar', 'tar', 'wininst', 'zip', 'msi'] # And the real information. format_command = {'rpm': ('bdist_rpm', "RPM distribution"), 'gztar': ('bdist_dumb', "gzip'ed tar file"), 'bztar': ('bdist_dumb', "bzip2'ed tar file"), + 'xztar': ('bdist_dumb', "xz'ed tar file"), 'ztar': ('bdist_dumb', "compressed tar file"), 'tar': ('bdist_dumb', "tar file"), 'wininst': ('bdist_wininst', diff --git a/Lib/distutils/command/bdist_dumb.py b/Lib/distutils/command/bdist_dumb.py index 4405d12..f1bfb24 100644 --- a/Lib/distutils/command/bdist_dumb.py +++ b/Lib/distutils/command/bdist_dumb.py @@ -22,7 +22,8 @@ class bdist_dumb(Command): "platform name to embed in generated filenames " "(default: %s)" % get_platform()), ('format=', 'f', - "archive format to create (tar, ztar, gztar, zip)"), + "archive format to create (tar, gztar, bztar, xztar, " + "ztar, zip)"), ('keep-temp', 'k', "keep the pseudo-installation tree around after " + "creating the distribution archive"), diff --git a/Lib/distutils/command/bdist_wininst.py b/Lib/distutils/command/bdist_wininst.py index 959a8bf..0c0e2c1 100644 --- a/Lib/distutils/command/bdist_wininst.py +++ b/Lib/distutils/command/bdist_wininst.py @@ -303,7 +303,6 @@ class bdist_wininst(Command): return installer_name def get_exe_bytes(self): - from distutils.msvccompiler import get_build_version # If a target-version other than the current version has been # specified, then using the MSVC version from *this* build is no good. # Without actually finding and executing the target version and parsing @@ -313,20 +312,33 @@ class bdist_wininst(Command): # We can then execute this program to obtain any info we need, such # as the real sys.version string for the build. cur_version = get_python_version() - if self.target_version and self.target_version != cur_version: - # If the target version is *later* than us, then we assume they - # use what we use - # string compares seem wrong, but are what sysconfig.py itself uses - if self.target_version > cur_version: - bv = get_build_version() + + # If the target version is *later* than us, then we assume they + # use what we use + # string compares seem wrong, but are what sysconfig.py itself uses + if self.target_version and self.target_version < cur_version: + if self.target_version < "2.4": + bv = 6.0 + elif self.target_version == "2.4": + bv = 7.1 + elif self.target_version == "2.5": + bv = 8.0 + elif self.target_version <= "3.2": + bv = 9.0 + elif self.target_version <= "3.4": + bv = 10.0 else: - if self.target_version < "2.4": - bv = 6.0 - else: - bv = 7.1 + bv = 14.0 else: # for current version - use authoritative check. - bv = get_build_version() + try: + from msvcrt import CRT_ASSEMBLY_VERSION + except ImportError: + # cross-building, so assume the latest version + bv = 14.0 + else: + bv = float('.'.join(CRT_ASSEMBLY_VERSION.split('.', 2)[:2])) + # wininst-x.y.exe is in the same directory as this file directory = os.path.dirname(__file__) diff --git a/Lib/distutils/command/build.py b/Lib/distutils/command/build.py index cfc15cf..337dd0b 100644 --- a/Lib/distutils/command/build.py +++ b/Lib/distutils/command/build.py @@ -36,6 +36,8 @@ class build(Command): "(default: %s)" % get_platform()), ('compiler=', 'c', "specify the compiler type"), + ('parallel=', 'j', + "number of parallel build jobs"), ('debug', 'g', "compile extensions and libraries with debugging information"), ('force', 'f', @@ -65,6 +67,7 @@ class build(Command): self.debug = None self.force = 0 self.executable = None + self.parallel = None def finalize_options(self): if self.plat_name is None: @@ -116,6 +119,12 @@ class build(Command): if self.executable is None: self.executable = os.path.normpath(sys.executable) + if isinstance(self.parallel, str): + try: + self.parallel = int(self.parallel) + except ValueError: + raise DistutilsOptionError("parallel should be an integer") + def run(self): # Run all relevant sub-commands. This will be some subset of: # - build_py - pure Python modules diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index acbe648..d4cb11e 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -4,7 +4,10 @@ Implements the Distutils 'build_ext' command, for building extension modules (currently limited to C extensions, should accommodate C++ extensions ASAP).""" -import sys, os, re +import contextlib +import os +import re +import sys from distutils.core import Command from distutils.errors import * from distutils.sysconfig import customize_compiler, get_python_version @@ -16,10 +19,6 @@ from distutils import log from site import USER_BASE -if os.name == 'nt': - from distutils.msvccompiler import get_build_version - MSVC_VERSION = int(get_build_version()) - # An extension name is just a dot-separated list of Python NAMEs (ie. # the same as a fully-qualified module name). extension_name_re = re.compile \ @@ -85,6 +84,8 @@ class build_ext(Command): "forcibly build everything (ignore file timestamps)"), ('compiler=', 'c', "specify the compiler type"), + ('parallel=', 'j', + "number of parallel build jobs"), ('swig-cpp', None, "make SWIG create C++ files (default is C)"), ('swig-opts=', None, @@ -124,6 +125,7 @@ class build_ext(Command): self.swig_cpp = None self.swig_opts = None self.user = None + self.parallel = None def finalize_options(self): from distutils import sysconfig @@ -134,6 +136,7 @@ class build_ext(Command): ('compiler', 'compiler'), ('debug', 'debug'), ('force', 'force'), + ('parallel', 'parallel'), ('plat_name', 'plat_name'), ) @@ -199,27 +202,17 @@ class build_ext(Command): _sys_home = getattr(sys, '_home', None) if _sys_home: self.library_dirs.append(_sys_home) - if MSVC_VERSION >= 9: - # Use the .lib files for the correct architecture - if self.plat_name == 'win32': - suffix = '' - else: - # win-amd64 or win-ia64 - suffix = self.plat_name[4:] - new_lib = os.path.join(sys.exec_prefix, 'PCbuild') - if suffix: - new_lib = os.path.join(new_lib, suffix) - self.library_dirs.append(new_lib) - - elif MSVC_VERSION == 8: - self.library_dirs.append(os.path.join(sys.exec_prefix, - 'PC', 'VS8.0')) - elif MSVC_VERSION == 7: - self.library_dirs.append(os.path.join(sys.exec_prefix, - 'PC', 'VS7.1')) + + # Use the .lib files for the correct architecture + if self.plat_name == 'win32': + suffix = 'win32' else: - self.library_dirs.append(os.path.join(sys.exec_prefix, - 'PC', 'VC6')) + # win-amd64 or win-ia64 + suffix = self.plat_name[4:] + new_lib = os.path.join(sys.exec_prefix, 'PCbuild') + if suffix: + new_lib = os.path.join(new_lib, suffix) + self.library_dirs.append(new_lib) # for extensions under Cygwin and AtheOS Python's library directory must be # appended to library_dirs @@ -274,6 +267,12 @@ class build_ext(Command): self.library_dirs.append(user_lib) self.rpath.append(user_lib) + if isinstance(self.parallel, str): + try: + self.parallel = int(self.parallel) + except ValueError: + raise DistutilsOptionError("parallel should be an integer") + def run(self): from distutils.ccompiler import new_compiler @@ -442,15 +441,45 @@ class build_ext(Command): def build_extensions(self): # First, sanity-check the 'extensions' list self.check_extensions_list(self.extensions) + if self.parallel: + self._build_extensions_parallel() + else: + self._build_extensions_serial() + + def _build_extensions_parallel(self): + workers = self.parallel + if self.parallel is True: + workers = os.cpu_count() # may return None + try: + from concurrent.futures import ThreadPoolExecutor + except ImportError: + workers = None + + if workers is None: + self._build_extensions_serial() + return + + with ThreadPoolExecutor(max_workers=workers) as executor: + futures = [executor.submit(self.build_extension, ext) + for ext in self.extensions] + for ext, fut in zip(self.extensions, futures): + with self._filter_build_errors(ext): + fut.result() + def _build_extensions_serial(self): for ext in self.extensions: - try: + with self._filter_build_errors(ext): self.build_extension(ext) - except (CCompilerError, DistutilsError, CompileError) as e: - if not ext.optional: - raise - self.warn('building extension "%s" failed: %s' % - (ext.name, e)) + + @contextlib.contextmanager + def _filter_build_errors(self, ext): + try: + yield + except (CCompilerError, DistutilsError, CompileError) as e: + if not ext.optional: + raise + self.warn('building extension "%s" failed: %s' % + (ext.name, e)) def build_extension(self, ext): sources = ext.sources @@ -502,15 +531,8 @@ class build_ext(Command): extra_postargs=extra_args, depends=ext.depends) - # XXX -- this is a Vile HACK! - # - # The setup.py script for Python on Unix needs to be able to - # get this list so it can perform all the clean up needed to - # avoid keeping object files around when cleaning out a failed - # build of an extension module. Since Distutils does not - # track dependencies, we have to get rid of intermediates to - # ensure all the intermediates will be properly re-built. - # + # XXX outdated variable, kept here in case third-part code + # needs it. self._built_objects = objects[:] # Now link the object files together into a "shared object" -- @@ -655,10 +677,7 @@ class build_ext(Command): """ from distutils.sysconfig import get_config_var ext_path = ext_name.split('.') - # extensions in debug_mode are named 'module_d.pyd' under windows ext_suffix = get_config_var('EXT_SUFFIX') - if os.name == 'nt' and self.debug: - return os.path.join(*ext_path) + '_d' + ext_suffix return os.path.join(*ext_path) + ext_suffix def get_export_symbols(self, ext): @@ -683,7 +702,7 @@ class build_ext(Command): # to need it mentioned explicitly, though, so that's what we do. # Append '_d' to the python import library on debug builds. if sys.platform == "win32": - from distutils.msvccompiler import MSVCCompiler + from distutils._msvccompiler import MSVCCompiler if not isinstance(self.compiler, MSVCCompiler): template = "python%d%d" if self.debug: diff --git a/Lib/distutils/command/build_py.py b/Lib/distutils/command/build_py.py index 9100b96..cf0ca57 100644 --- a/Lib/distutils/command/build_py.py +++ b/Lib/distutils/command/build_py.py @@ -314,10 +314,10 @@ class build_py (Command): if include_bytecode: if self.compile: outputs.append(importlib.util.cache_from_source( - filename, debug_override=True)) + filename, optimization='')) if self.optimize > 0: outputs.append(importlib.util.cache_from_source( - filename, debug_override=False)) + filename, optimization=self.optimize)) outputs += [ os.path.join(build_dir, filename) diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py index d768dc5..67db007 100644 --- a/Lib/distutils/command/install.py +++ b/Lib/distutils/command/install.py @@ -51,7 +51,7 @@ if HAS_USER_SITE: 'purelib': '$usersite', 'platlib': '$usersite', 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name', - 'scripts': '$userbase/Scripts', + 'scripts': '$userbase/Python$py_version_nodot/Scripts', 'data' : '$userbase', } diff --git a/Lib/distutils/command/install_lib.py b/Lib/distutils/command/install_lib.py index 215813b..6154cf0 100644 --- a/Lib/distutils/command/install_lib.py +++ b/Lib/distutils/command/install_lib.py @@ -22,15 +22,15 @@ class install_lib(Command): # possible scenarios: # 1) no compilation at all (--no-compile --no-optimize) # 2) compile .pyc only (--compile --no-optimize; default) - # 3) compile .pyc and "level 1" .pyo (--compile --optimize) - # 4) compile "level 1" .pyo only (--no-compile --optimize) - # 5) compile .pyc and "level 2" .pyo (--compile --optimize-more) - # 6) compile "level 2" .pyo only (--no-compile --optimize-more) + # 3) compile .pyc and "opt-1" .pyc (--compile --optimize) + # 4) compile "opt-1" .pyc only (--no-compile --optimize) + # 5) compile .pyc and "opt-2" .pyc (--compile --optimize-more) + # 6) compile "opt-2" .pyc only (--no-compile --optimize-more) # - # The UI for this is two option, 'compile' and 'optimize'. + # The UI for this is two options, 'compile' and 'optimize'. # 'compile' is strictly boolean, and only decides whether to # generate .pyc files. 'optimize' is three-way (0, 1, or 2), and - # decides both whether to generate .pyo files and what level of + # decides both whether to generate .pyc files and what level of # optimization to use. user_options = [ @@ -166,10 +166,10 @@ class install_lib(Command): continue if self.compile: bytecode_files.append(importlib.util.cache_from_source( - py_file, debug_override=True)) + py_file, optimization='')) if self.optimize > 0: bytecode_files.append(importlib.util.cache_from_source( - py_file, debug_override=False)) + py_file, optimization=self.optimize)) return bytecode_files diff --git a/Lib/distutils/command/upload.py b/Lib/distutils/command/upload.py index 1a96e22..1c4fc48 100644 --- a/Lib/distutils/command/upload.py +++ b/Lib/distutils/command/upload.py @@ -1,11 +1,14 @@ -"""distutils.command.upload +""" +distutils.command.upload -Implements the Distutils 'upload' subcommand (upload package to PyPI).""" +Implements the Distutils 'upload' subcommand (upload package to a package +index). +""" -import sys -import os, io -import socket +import os +import io import platform +import hashlib from base64 import standard_b64encode from urllib.request import urlopen, Request, HTTPError from urllib.parse import urlparse @@ -14,12 +17,6 @@ from distutils.core import PyPIRCCommand from distutils.spawn import spawn from distutils import log -# this keeps compatibility for 2.3 and 2.4 -if sys.version < "2.5": - from md5 import md5 -else: - from hashlib import md5 - class upload(PyPIRCCommand): description = "upload binary package to PyPI" @@ -60,7 +57,8 @@ class upload(PyPIRCCommand): def run(self): if not self.distribution.dist_files: - raise DistutilsOptionError("No dist file created in earlier command") + msg = "No dist file created in earlier command" + raise DistutilsOptionError(msg) for command, pyversion, filename in self.distribution.dist_files: self.upload_file(command, pyversion, filename) @@ -103,10 +101,10 @@ class upload(PyPIRCCommand): 'content': (os.path.basename(filename),content), 'filetype': command, 'pyversion': pyversion, - 'md5_digest': md5(content).hexdigest(), + 'md5_digest': hashlib.md5(content).hexdigest(), # additional meta-data - 'metadata_version' : '1.0', + 'metadata_version': '1.0', 'summary': meta.get_description(), 'home_page': meta.get_url(), 'author': meta.get_contact(), @@ -149,7 +147,7 @@ class upload(PyPIRCCommand): for key, value in data.items(): title = '\r\nContent-Disposition: form-data; name="%s"' % key # handle multiple entries for the same name - if type(value) != type([]): + if not isinstance(value, list): value = [value] for value in value: if type(value) is tuple: @@ -166,13 +164,15 @@ class upload(PyPIRCCommand): body.write(end_boundary) body = body.getvalue() - self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO) + msg = "Submitting %s to %s" % (filename, self.repository) + self.announce(msg, log.INFO) # build the Request - headers = {'Content-type': - 'multipart/form-data; boundary=%s' % boundary, - 'Content-length': str(len(body)), - 'Authorization': auth} + headers = { + 'Content-type': 'multipart/form-data; boundary=%s' % boundary, + 'Content-length': str(len(body)), + 'Authorization': auth, + } request = Request(self.repository, data=body, headers=headers) diff --git a/Lib/distutils/command/wininst-14.0-amd64.exe b/Lib/distutils/command/wininst-14.0-amd64.exe Binary files differnew file mode 100644 index 0000000..43b85b6 --- /dev/null +++ b/Lib/distutils/command/wininst-14.0-amd64.exe diff --git a/Lib/distutils/command/wininst-14.0.exe b/Lib/distutils/command/wininst-14.0.exe Binary files differnew file mode 100644 index 0000000..764524d --- /dev/null +++ b/Lib/distutils/command/wininst-14.0.exe |
