summaryrefslogtreecommitdiff
path: root/Lib/distutils
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/distutils')
-rw-r--r--Lib/distutils/__init__.py2
-rw-r--r--Lib/distutils/command/build.py9
-rw-r--r--Lib/distutils/command/build_ext.py73
-rw-r--r--Lib/distutils/command/install.py2
-rw-r--r--Lib/distutils/command/upload.py40
-rw-r--r--Lib/distutils/command/wininst-14.0-amd64.exebin0 -> 84480 bytes
-rw-r--r--Lib/distutils/command/wininst-14.0.exebin0 -> 75264 bytes
-rw-r--r--Lib/distutils/dist.py69
-rw-r--r--Lib/distutils/extension.py8
-rw-r--r--Lib/distutils/msvc9compiler.py3
-rw-r--r--Lib/distutils/msvccompiler.py3
-rw-r--r--Lib/distutils/spawn.py3
-rw-r--r--Lib/distutils/sysconfig.py27
-rw-r--r--Lib/distutils/tests/test_build_ext.py56
-rw-r--r--Lib/distutils/tests/test_install.py2
-rw-r--r--Lib/distutils/version.py6
16 files changed, 176 insertions, 127 deletions
diff --git a/Lib/distutils/__init__.py b/Lib/distutils/__init__.py
index 00a5859738..451c5fbebc 100644
--- a/Lib/distutils/__init__.py
+++ b/Lib/distutils/__init__.py
@@ -13,5 +13,5 @@ used from a setup script as
# Updated automatically by the Python release process.
#
#--start constants--
-__version__ = "3.4.3"
+__version__ = "3.5.0a2"
#--end constants--
diff --git a/Lib/distutils/command/build.py b/Lib/distutils/command/build.py
index cfc15cf0dd..337dd0bfc1 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 acbe648036..c5a3ce1915 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
@@ -85,6 +88,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 +129,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 +140,7 @@ class build_ext(Command):
('compiler', 'compiler'),
('debug', 'debug'),
('force', 'force'),
+ ('parallel', 'parallel'),
('plat_name', 'plat_name'),
)
@@ -202,7 +209,7 @@ class build_ext(Command):
if MSVC_VERSION >= 9:
# Use the .lib files for the correct architecture
if self.plat_name == 'win32':
- suffix = ''
+ suffix = 'win32'
else:
# win-amd64 or win-ia64
suffix = self.plat_name[4:]
@@ -274,6 +281,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 +455,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 +545,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 +691,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):
diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py
index d768dc5463..67db007a02 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/upload.py b/Lib/distutils/command/upload.py
index 1a96e2221e..1c4fc48a12 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
new file mode 100644
index 0000000000..43b85b6d4f
--- /dev/null
+++ b/Lib/distutils/command/wininst-14.0-amd64.exe
Binary files differ
diff --git a/Lib/distutils/command/wininst-14.0.exe b/Lib/distutils/command/wininst-14.0.exe
new file mode 100644
index 0000000000..764524d746
--- /dev/null
+++ b/Lib/distutils/command/wininst-14.0.exe
Binary files differ
diff --git a/Lib/distutils/dist.py b/Lib/distutils/dist.py
index 7eb04bc3f5..ffb33ff645 100644
--- a/Lib/distutils/dist.py
+++ b/Lib/distutils/dist.py
@@ -4,7 +4,9 @@ Provides the Distribution class, which represents the module distribution
being built/installed/distributed.
"""
-import sys, os, re
+import sys
+import os
+import re
from email import message_from_file
try:
@@ -22,7 +24,7 @@ from distutils.debug import DEBUG
# the same as a Python NAME -- I don't allow leading underscores. The fact
# that they're very similar is no coincidence; the default naming scheme is
# to look for a Python module named after the command.
-command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
+command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
class Distribution:
@@ -39,7 +41,6 @@ class Distribution:
See the code for 'setup()', in core.py, for details.
"""
-
# 'global_options' describes the command-line options that may be
# supplied to the setup script prior to any actual commands.
# Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
@@ -48,12 +49,13 @@ class Distribution:
# don't want to pollute the commands with too many options that they
# have minimal control over.
# The fourth entry for verbose means that it can be repeated.
- global_options = [('verbose', 'v', "run verbosely (default)", 1),
- ('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'),
+ global_options = [
+ ('verbose', 'v', "run verbosely (default)", 1),
+ ('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'),
]
# 'common_usage' is a short (2-3 line) string describing the common
@@ -115,10 +117,9 @@ Common commands: (see '--help-commands' for more)
# negative options are options that exclude other options
negative_opt = {'quiet': 'verbose'}
-
# -- Creation/initialization methods -------------------------------
- def __init__ (self, attrs=None):
+ def __init__(self, attrs=None):
"""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
@@ -532,15 +533,15 @@ 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)):
- raise DistutilsClassError(("command class %s must provide " +
- "'user_options' attribute (a list of tuples)") % \
- cmd_class)
+ 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,
# merge it in with the global negative aliases.
@@ -552,12 +553,11 @@ 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)):
+ 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 +
@@ -570,7 +570,7 @@ Common commands: (see '--help-commands' for more)
return
if (hasattr(cmd_class, 'help_options') and
- isinstance(cmd_class.help_options, list)):
+ 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)):
@@ -647,7 +647,7 @@ Common commands: (see '--help-commands' for more)
else:
klass = self.get_command_class(command)
if (hasattr(klass, 'help_options') and
- isinstance(klass.help_options, list)):
+ isinstance(klass.help_options, list)):
parser.set_option_table(klass.user_options +
fix_help_options(klass.help_options))
else:
@@ -814,7 +814,7 @@ Common commands: (see '--help-commands' for more)
klass_name = command
try:
- __import__ (module_name)
+ __import__(module_name)
module = sys.modules[module_name]
except ImportError:
continue
@@ -823,8 +823,8 @@ Common commands: (see '--help-commands' for more)
klass = getattr(module, klass_name)
except AttributeError:
raise DistutilsModuleError(
- "invalid command '%s' (no class '%s' in module '%s')"
- % (command, klass_name, module_name))
+ "invalid command '%s' (no class '%s' in module '%s')"
+ % (command, klass_name, module_name))
self.cmdclass[command] = klass
return klass
@@ -840,7 +840,7 @@ 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(): " \
+ self.announce("Distribution.get_command_obj(): "
"creating '%s' command object" % command)
klass = self.get_command_class(command)
@@ -897,8 +897,8 @@ Common commands: (see '--help-commands' for more)
setattr(command_obj, option, value)
else:
raise DistutilsOptionError(
- "error in %s: command '%s' has no such option '%s'"
- % (source, command_name, option))
+ "error in %s: command '%s' has no such option '%s'"
+ % (source, command_name, option))
except ValueError as msg:
raise DistutilsOptionError(msg)
@@ -974,7 +974,6 @@ Common commands: (see '--help-commands' for more)
cmd_obj.run()
self.have_run[command] = 1
-
# -- Distribution query methods ------------------------------------
def has_pure_modules(self):
@@ -1112,17 +1111,17 @@ class DistributionMetadata:
"""
version = '1.0'
if (self.provides or self.requires or self.obsoletes or
- self.classifiers or self.download_url):
+ self.classifiers or self.download_url):
version = '1.1'
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() )
+ 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)
@@ -1131,7 +1130,7 @@ class DistributionMetadata:
keywords = ','.join(self.get_keywords())
if keywords:
- file.write('Keywords: %s\n' % keywords )
+ file.write('Keywords: %s\n' % keywords)
self._write_list(file, 'Platform', self.get_platforms())
self._write_list(file, 'Classifier', self.get_classifiers())
diff --git a/Lib/distutils/extension.py b/Lib/distutils/extension.py
index a93655af2c..7efbb74f89 100644
--- a/Lib/distutils/extension.py
+++ b/Lib/distutils/extension.py
@@ -131,6 +131,14 @@ class Extension:
msg = "Unknown Extension options: %s" % options
warnings.warn(msg)
+ def __repr__(self):
+ return '<%s.%s(%r) at %#x>' % (
+ self.__class__.__module__,
+ self.__class__.__qualname__,
+ self.name,
+ id(self))
+
+
def read_setup_file(filename):
"""Reads a Setup file and returns Extension instances."""
from distutils.sysconfig import (parse_makefile, expand_makefile_vars,
diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py
index 9688f20019..d1374efe13 100644
--- a/Lib/distutils/msvc9compiler.py
+++ b/Lib/distutils/msvc9compiler.py
@@ -179,6 +179,9 @@ def get_build_version():
i = i + len(prefix)
s, rest = sys.version[i:].split(" ", 1)
majorVersion = int(s[:-2]) - 6
+ if majorVersion >= 13:
+ # v13 was skipped and should be v14
+ majorVersion += 1
minorVersion = int(s[2:3]) / 10.0
# I don't think paths are affected by minor version in version 6
if majorVersion == 6:
diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py
index 8116656961..1048cd4159 100644
--- a/Lib/distutils/msvccompiler.py
+++ b/Lib/distutils/msvccompiler.py
@@ -157,6 +157,9 @@ def get_build_version():
i = i + len(prefix)
s, rest = sys.version[i:].split(" ", 1)
majorVersion = int(s[:-2]) - 6
+ if majorVersion >= 13:
+ # v13 was skipped and should be v14
+ majorVersion += 1
minorVersion = int(s[2:3]) / 10.0
# I don't think paths are affected by minor version in version 6
if majorVersion == 6:
diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py
index 22e87e8fdb..5dd415a283 100644
--- a/Lib/distutils/spawn.py
+++ b/Lib/distutils/spawn.py
@@ -137,9 +137,6 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0):
try:
pid, status = os.waitpid(pid, 0)
except OSError as exc:
- import errno
- if exc.errno == errno.EINTR:
- continue
if not DEBUG:
cmd = executable
raise DistutilsExecError(
diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py
index a1452fe167..573724ddd7 100644
--- a/Lib/distutils/sysconfig.py
+++ b/Lib/distutils/sysconfig.py
@@ -9,6 +9,7 @@ Written by: Fred L. Drake, Jr.
Email: <fdrake@acm.org>
"""
+import _imp
import os
import re
import sys
@@ -22,23 +23,15 @@ BASE_PREFIX = os.path.normpath(sys.base_prefix)
BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
# Path to the base directory of the project. On Windows the binary may
-# live in project/PCBuild9. If we're dealing with an x64 Windows build,
-# it'll live in project/PCbuild/amd64.
+# live in project/PCBuild/win32 or project/PCBuild/amd64.
# set for cross builds
if "_PYTHON_PROJECT_BASE" in os.environ:
project_base = os.path.abspath(os.environ["_PYTHON_PROJECT_BASE"])
else:
project_base = os.path.dirname(os.path.abspath(sys.executable))
-if os.name == "nt" and "pcbuild" in project_base[-8:].lower():
- project_base = os.path.abspath(os.path.join(project_base, os.path.pardir))
-# PC/VS7.1
-if os.name == "nt" and "\\pc\\v" in project_base[-10:].lower():
- project_base = os.path.abspath(os.path.join(project_base, os.path.pardir,
- os.path.pardir))
-# PC/AMD64
-if os.name == "nt" and "\\pcbuild\\amd64" in project_base[-14:].lower():
- project_base = os.path.abspath(os.path.join(project_base, os.path.pardir,
- os.path.pardir))
+if (os.name == 'nt' and
+ project_base.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))):
+ project_base = os.path.dirname(os.path.dirname(project_base))
# python_build: (Boolean) if true, we're either building Python or
# building an extension with an un-installed Python, so we use
@@ -51,11 +44,9 @@ def _is_python_source_dir(d):
return True
return False
_sys_home = getattr(sys, '_home', None)
-if _sys_home and os.name == 'nt' and \
- _sys_home.lower().endswith(('pcbuild', 'pcbuild\\amd64')):
- _sys_home = os.path.dirname(_sys_home)
- if _sys_home.endswith('pcbuild'): # must be amd64
- _sys_home = os.path.dirname(_sys_home)
+if (_sys_home and os.name == 'nt' and
+ _sys_home.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))):
+ _sys_home = os.path.dirname(os.path.dirname(_sys_home))
def _python_build():
if _sys_home:
return _is_python_source_dir(_sys_home)
@@ -468,7 +459,7 @@ def _init_nt():
# XXX hmmm.. a normal install puts include files here
g['INCLUDEPY'] = get_python_inc(plat_specific=0)
- g['EXT_SUFFIX'] = '.pyd'
+ 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))
diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py
index b9f407f401..366ffbec9f 100644
--- a/Lib/distutils/tests/test_build_ext.py
+++ b/Lib/distutils/tests/test_build_ext.py
@@ -37,6 +37,9 @@ class BuildExtTestCase(TempdirManager,
from distutils.command import build_ext
build_ext.USER_BASE = site.USER_BASE
+ def build_ext(self, *args, **kwargs):
+ return build_ext(*args, **kwargs)
+
def test_build_ext(self):
global ALREADY_TESTED
copy_xxmodule_c(self.tmp_dir)
@@ -44,7 +47,7 @@ class BuildExtTestCase(TempdirManager,
xx_ext = Extension('xx', [xx_c])
dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]})
dist.package_dir = self.tmp_dir
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
fixup_build_ext(cmd)
cmd.build_lib = self.tmp_dir
cmd.build_temp = self.tmp_dir
@@ -91,7 +94,7 @@ class BuildExtTestCase(TempdirManager,
def test_solaris_enable_shared(self):
dist = Distribution({'name': 'xx'})
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
old = sys.platform
sys.platform = 'sunos' # fooling finalize_options
@@ -113,7 +116,7 @@ class BuildExtTestCase(TempdirManager,
def test_user_site(self):
import site
dist = Distribution({'name': 'xx'})
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
# making sure the user option is there
options = [name for name, short, lable in
@@ -144,14 +147,14 @@ class BuildExtTestCase(TempdirManager,
# with the optional argument.
modules = [Extension('foo', ['xxx'], optional=False)]
dist = Distribution({'name': 'xx', 'ext_modules': modules})
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.ensure_finalized()
self.assertRaises((UnknownFileError, CompileError),
cmd.run) # should raise an error
modules = [Extension('foo', ['xxx'], optional=True)]
dist = Distribution({'name': 'xx', 'ext_modules': modules})
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.ensure_finalized()
cmd.run() # should pass
@@ -160,7 +163,7 @@ class BuildExtTestCase(TempdirManager,
# etc.) are in the include search path.
modules = [Extension('foo', ['xxx'], optional=False)]
dist = Distribution({'name': 'xx', 'ext_modules': modules})
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.finalize_options()
from distutils import sysconfig
@@ -172,14 +175,14 @@ class BuildExtTestCase(TempdirManager,
# make sure cmd.libraries is turned into a list
# if it's a string
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.libraries = 'my_lib, other_lib lastlib'
cmd.finalize_options()
self.assertEqual(cmd.libraries, ['my_lib', 'other_lib', 'lastlib'])
# make sure cmd.library_dirs is turned into a list
# if it's a string
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.library_dirs = 'my_lib_dir%sother_lib_dir' % os.pathsep
cmd.finalize_options()
self.assertIn('my_lib_dir', cmd.library_dirs)
@@ -187,7 +190,7 @@ class BuildExtTestCase(TempdirManager,
# make sure rpath is turned into a list
# if it's a string
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.rpath = 'one%stwo' % os.pathsep
cmd.finalize_options()
self.assertEqual(cmd.rpath, ['one', 'two'])
@@ -196,32 +199,32 @@ class BuildExtTestCase(TempdirManager,
# make sure define is turned into 2-tuples
# strings if they are ','-separated strings
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.define = 'one,two'
cmd.finalize_options()
self.assertEqual(cmd.define, [('one', '1'), ('two', '1')])
# make sure undef is turned into a list of
# strings if they are ','-separated strings
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.undef = 'one,two'
cmd.finalize_options()
self.assertEqual(cmd.undef, ['one', 'two'])
# make sure swig_opts is turned into a list
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.swig_opts = None
cmd.finalize_options()
self.assertEqual(cmd.swig_opts, [])
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.swig_opts = '1 2'
cmd.finalize_options()
self.assertEqual(cmd.swig_opts, ['1', '2'])
def test_check_extensions_list(self):
dist = Distribution()
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.finalize_options()
#'extensions' option must be a list of Extension instances
@@ -270,7 +273,7 @@ class BuildExtTestCase(TempdirManager,
def test_get_source_files(self):
modules = [Extension('foo', ['xxx'], optional=False)]
dist = Distribution({'name': 'xx', 'ext_modules': modules})
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.ensure_finalized()
self.assertEqual(cmd.get_source_files(), ['xxx'])
@@ -279,7 +282,7 @@ class BuildExtTestCase(TempdirManager,
# should not be overriden by a compiler instance
# when the command is run
dist = Distribution()
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.compiler = 'unix'
cmd.ensure_finalized()
cmd.run()
@@ -292,7 +295,7 @@ class BuildExtTestCase(TempdirManager,
ext = Extension('foo', [c_file], optional=False)
dist = Distribution({'name': 'xx',
'ext_modules': [ext]})
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
fixup_build_ext(cmd)
cmd.ensure_finalized()
self.assertEqual(len(cmd.get_outputs()), 1)
@@ -355,7 +358,7 @@ class BuildExtTestCase(TempdirManager,
#etree_ext = Extension('lxml.etree', [etree_c])
#dist = Distribution({'name': 'lxml', 'ext_modules': [etree_ext]})
dist = Distribution()
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.inplace = 1
cmd.distribution.package_dir = {'': 'src'}
cmd.distribution.packages = ['lxml', 'lxml.html']
@@ -462,7 +465,7 @@ class BuildExtTestCase(TempdirManager,
'ext_modules': [deptarget_ext]
})
dist.package_dir = self.tmp_dir
- cmd = build_ext(dist)
+ cmd = self.build_ext(dist)
cmd.build_lib = self.tmp_dir
cmd.build_temp = self.tmp_dir
@@ -481,8 +484,19 @@ class BuildExtTestCase(TempdirManager,
self.fail("Wrong deployment target during compilation")
+class ParallelBuildExtTestCase(BuildExtTestCase):
+
+ def build_ext(self, *args, **kwargs):
+ build_ext = super().build_ext(*args, **kwargs)
+ build_ext.parallel = True
+ return build_ext
+
+
def test_suite():
- return unittest.makeSuite(BuildExtTestCase)
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(BuildExtTestCase))
+ suite.addTest(unittest.makeSuite(ParallelBuildExtTestCase))
+ return suite
if __name__ == '__main__':
- support.run_unittest(test_suite())
+ support.run_unittest(__name__)
diff --git a/Lib/distutils/tests/test_install.py b/Lib/distutils/tests/test_install.py
index 18e1e57505..9313330e2b 100644
--- a/Lib/distutils/tests/test_install.py
+++ b/Lib/distutils/tests/test_install.py
@@ -20,8 +20,6 @@ from distutils.tests import support
def _make_ext_name(modname):
- if os.name == 'nt' and sys.executable.endswith('_d.exe'):
- modname += '_d'
return modname + sysconfig.get_config_var('EXT_SUFFIX')
diff --git a/Lib/distutils/version.py b/Lib/distutils/version.py
index ebcab84e4e..af14cc1348 100644
--- a/Lib/distutils/version.py
+++ b/Lib/distutils/version.py
@@ -48,12 +48,6 @@ class Version:
return c
return c == 0
- def __ne__(self, other):
- c = self._cmp(other)
- if c is NotImplemented:
- return c
- return c != 0
-
def __lt__(self, other):
c = self._cmp(other)
if c is NotImplemented: