Skip to content

Commit

Permalink
Merge pull request #3496 from pypa/distutils-b65aa40
Browse files Browse the repository at this point in the history
  • Loading branch information
jaraco committed Aug 10, 2022
2 parents 71c44d9 + d6d341f commit 2dc468c
Show file tree
Hide file tree
Showing 40 changed files with 1,378 additions and 719 deletions.
1 change: 1 addition & 0 deletions changelog.d/3496.misc.rst
@@ -0,0 +1 @@
Update to pypa/distutils@b65aa40 including more robust support for library/include dir handling in msvccompiler (pypa/distutils#153) and test suite improvements.
25 changes: 15 additions & 10 deletions setuptools/_distutils/_msvccompiler.py
Expand Up @@ -17,7 +17,7 @@
import subprocess
import contextlib
import warnings
import unittest.mock
import unittest.mock as mock

with contextlib.suppress(ImportError):
import winreg
Expand Down Expand Up @@ -224,6 +224,18 @@ def __init__(self, verbose=0, dry_run=0, force=0):
self.plat_name = None
self.initialized = False

@classmethod
def _configure(cls, vc_env):
"""
Set class-level include/lib dirs.
"""
cls.include_dirs = cls._parse_path(vc_env.get('include', ''))
cls.library_dirs = cls._parse_path(vc_env.get('lib', ''))

@staticmethod
def _parse_path(val):
return [dir.rstrip(os.sep) for dir in val.split(os.pathsep) if dir]

def initialize(self, plat_name=None):
# multi-init means we would need to check platform same each time...
assert not self.initialized, "don't init multiple times"
Expand All @@ -243,6 +255,7 @@ def initialize(self, plat_name=None):
raise DistutilsPlatformError(
"Unable to find a compatible " "Visual Studio installation."
)
self._configure(vc_env)

self._paths = vc_env.get('path', '')
paths = self._paths.split(os.pathsep)
Expand All @@ -253,14 +266,6 @@ def initialize(self, plat_name=None):
self.mc = _find_exe("mc.exe", paths) # message compiler
self.mt = _find_exe("mt.exe", paths) # message compiler

for dir in vc_env.get('include', '').split(os.pathsep):
if dir:
self.add_include_dir(dir.rstrip(os.sep))

for dir in vc_env.get('lib', '').split(os.pathsep):
if dir:
self.add_library_dir(dir.rstrip(os.sep))

self.preprocess_options = None
# bpo-38597: Always compile with dynamic linking
# Future releases of Python 3.x will include all past
Expand Down Expand Up @@ -554,7 +559,7 @@ def _fallback_spawn(self, cmd, env):
else:
return
warnings.warn("Fallback spawn triggered. Please update distutils monkeypatch.")
with unittest.mock.patch.dict('os.environ', env):
with mock.patch.dict('os.environ', env):
bag.value = super().spawn(cmd)

# -- Miscellaneous methods -----------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion setuptools/_distutils/archive_util.py
Expand Up @@ -121,7 +121,7 @@ def _set_uid_gid(tarinfo):

# compression using `compress`
if compress == 'compress':
warn("'compress' will be deprecated.", PendingDeprecationWarning)
warn("'compress' is deprecated.", DeprecationWarning)
# the option varies depending on the platform
compressed_name = archive_name + compress_ext[compress]
if sys.platform == 'win32':
Expand Down
35 changes: 17 additions & 18 deletions setuptools/_distutils/ccompiler.py
Expand Up @@ -91,6 +91,16 @@ class CCompiler:
}
language_order = ["c++", "objc", "c"]

include_dirs = []
"""
include dirs specific to this compiler class
"""

library_dirs = []
"""
library dirs specific to this compiler class
"""

def __init__(self, verbose=0, dry_run=0, force=0):
self.dry_run = dry_run
self.force = force
Expand Down Expand Up @@ -324,24 +334,7 @@ def set_link_objects(self, objects):

def _setup_compile(self, outdir, macros, incdirs, sources, depends, extra):
"""Process arguments and decide which source files to compile."""
if outdir is None:
outdir = self.output_dir
elif not isinstance(outdir, str):
raise TypeError("'output_dir' must be a string or None")

if macros is None:
macros = self.macros
elif isinstance(macros, list):
macros = macros + (self.macros or [])
else:
raise TypeError("'macros' (if supplied) must be a list of tuples")

if incdirs is None:
incdirs = self.include_dirs
elif isinstance(incdirs, (list, tuple)):
incdirs = list(incdirs) + (self.include_dirs or [])
else:
raise TypeError("'include_dirs' (if supplied) must be a list of strings")
outdir, macros, incdirs = self._fix_compile_args(outdir, macros, incdirs)

if extra is None:
extra = []
Expand Down Expand Up @@ -400,6 +393,9 @@ def _fix_compile_args(self, output_dir, macros, include_dirs):
else:
raise TypeError("'include_dirs' (if supplied) must be a list of strings")

# add include dirs for class
include_dirs += self.__class__.include_dirs

return output_dir, macros, include_dirs

def _prep_compile(self, sources, output_dir, depends=None):
Expand Down Expand Up @@ -456,6 +452,9 @@ def _fix_lib_args(self, libraries, library_dirs, runtime_library_dirs):
else:
raise TypeError("'library_dirs' (if supplied) must be a list of strings")

# add library dirs for class
library_dirs += self.__class__.library_dirs

if runtime_library_dirs is None:
runtime_library_dirs = self.runtime_library_dirs
elif isinstance(runtime_library_dirs, (list, tuple)):
Expand Down
38 changes: 19 additions & 19 deletions setuptools/_distutils/command/check.py
Expand Up @@ -2,17 +2,18 @@
Implements the Distutils 'check' command.
"""
import contextlib

from distutils.core import Command
from distutils.errors import DistutilsSetupError

try:
# docutils is installed
from docutils.utils import Reporter
from docutils.parsers.rst import Parser
from docutils import frontend
from docutils import nodes
with contextlib.suppress(ImportError):
import docutils.utils
import docutils.parsers.rst
import docutils.frontend
import docutils.nodes

class SilentReporter(Reporter):
class SilentReporter(docutils.utils.Reporter):
def __init__(
self,
source,
Expand All @@ -30,16 +31,10 @@ def __init__(

def system_message(self, level, message, *children, **kwargs):
self.messages.append((level, message, children, kwargs))
return nodes.system_message(
return docutils.nodes.system_message(
message, level=level, type=self.levels[level], *children, **kwargs
)

HAS_DOCUTILS = True
except Exception:
# Catch all exceptions because exceptions besides ImportError probably
# indicate that docutils is not ported to Py3k.
HAS_DOCUTILS = False


class check(Command):
"""This command checks the meta-data of the package."""
Expand Down Expand Up @@ -81,8 +76,11 @@ def run(self):
if self.metadata:
self.check_metadata()
if self.restructuredtext:
if HAS_DOCUTILS:
self.check_restructuredtext()
if 'docutils' in globals():
try:
self.check_restructuredtext()
except TypeError as exc:
raise DistutilsSetupError(str(exc))
elif self.strict:
raise DistutilsSetupError('The docutils package is needed.')

Expand Down Expand Up @@ -124,8 +122,10 @@ def _check_rst_data(self, data):
"""Returns warnings when the provided data doesn't compile."""
# the include and csv_table directives need this to be a path
source_path = self.distribution.script_name or 'setup.py'
parser = Parser()
settings = frontend.OptionParser(components=(Parser,)).get_default_values()
parser = docutils.parsers.rst.Parser()
settings = docutils.frontend.OptionParser(
components=(docutils.parsers.rst.Parser,)
).get_default_values()
settings.tab_width = 4
settings.pep_references = None
settings.rfc_references = None
Expand All @@ -139,7 +139,7 @@ def _check_rst_data(self, data):
error_handler=settings.error_encoding_error_handler,
)

document = nodes.document(settings, reporter, source=source_path)
document = docutils.nodes.document(settings, reporter, source=source_path)
document.note_source(source_path, -1)
try:
parser.parse(data, document)
Expand Down
6 changes: 3 additions & 3 deletions setuptools/_distutils/command/register.py
Expand Up @@ -66,9 +66,9 @@ def run(self):
def check_metadata(self):
"""Deprecated API."""
warn(
"distutils.command.register.check_metadata is deprecated, \
use the check command instead",
PendingDeprecationWarning,
"distutils.command.register.check_metadata is deprecated; "
"use the check command instead",
DeprecationWarning,
)
check = self.distribution.get_command_obj('check')
check.ensure_finalized()
Expand Down
12 changes: 12 additions & 0 deletions setuptools/_distutils/tests/py38compat.py
Expand Up @@ -42,5 +42,17 @@
)


try:
from test.support.import_helper import (
DirsOnSysPath,
CleanImport,
)
except (ModuleNotFoundError, ImportError):
from test.support import (
DirsOnSysPath,
CleanImport,
)


if sys.version_info < (3, 9):
requires_zlib = lambda: test.support.requires_zlib
29 changes: 5 additions & 24 deletions setuptools/_distutils/tests/support.py
Expand Up @@ -3,7 +3,6 @@
import sys
import shutil
import tempfile
import unittest
import sysconfig
import itertools

Expand Down Expand Up @@ -31,9 +30,8 @@ def clear_logs(self):

@pytest.mark.usefixtures('distutils_managed_tempdir')
class TempdirManager:
"""Mix-in class that handles temporary directories for test cases.
This is intended to be used with unittest.TestCase.
"""
Mix-in class that handles temporary directories for test cases.
"""

def mkdtemp(self):
Expand Down Expand Up @@ -99,29 +97,12 @@ def test_compile(self):
If the source file can be found, it will be copied to *directory*. If not,
the test will be skipped. Errors during copy are not caught.
"""
filename = _get_xxmodule_path()
if filename is None:
raise unittest.SkipTest(
'cannot find xxmodule.c (test must run in ' 'the python build dir)'
)
shutil.copy(filename, directory)
shutil.copy(_get_xxmodule_path(), os.path.join(directory, 'xxmodule.c'))


def _get_xxmodule_path():
srcdir = sysconfig.get_config_var('srcdir')
candidates = [
# use installed copy if available
os.path.join(os.path.dirname(__file__), 'xxmodule.c'),
# otherwise try using copy from build directory
os.path.join(srcdir, 'Modules', 'xxmodule.c'),
# srcdir mysteriously can be $srcdir/Lib/distutils/tests when
# this file is run from its parent directory, so walk up the
# tree to find the real srcdir
os.path.join(srcdir, '..', '..', '..', 'Modules', 'xxmodule.c'),
]
for path in candidates:
if os.path.exists(path):
return path
source_name = 'xxmodule.c' if sys.version_info > (3, 9) else 'xxmodule-3.8.c'
return os.path.join(os.path.dirname(__file__), source_name)


def fixup_build_ext(cmd):
Expand Down

0 comments on commit 2dc468c

Please sign in to comment.