Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge with pypa/distutils@b65aa40 #3496

Merged
merged 94 commits into from Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
6c0ed90
Convert test_cmd to pytest
jaraco Aug 4, 2022
c24974b
Convert BasePyPIRCCommandTestCase to pytest
jaraco Aug 4, 2022
ca9ed49
Convert RegisterTestCase to pytest
jaraco Aug 4, 2022
885a877
⚫ Fade to black.
jaraco Aug 4, 2022
461590c
Use jaraco.path to generate a tree.
jaraco Aug 4, 2022
12fe2ac
Port sdist tests to pytest
jaraco Aug 4, 2022
0802d58
Convert TestUpload to pytest
jaraco Aug 4, 2022
79681e2
Convert TestUpload to parametrized test. Remove dependence on unittes…
jaraco Aug 4, 2022
4fada1c
Implement HTTP 400 error as a pytest.param to avoid collection error.…
jaraco Aug 4, 2022
51d3ec1
Convert core tests to pytest
jaraco Aug 4, 2022
e46bbf9
⚫ Fade to black.
jaraco Aug 4, 2022
1f3e6af
Convert TestVersion to pytest.
jaraco Aug 4, 2022
5f5addf
Convert TestConfig to pytest
jaraco Aug 6, 2022
0ebb6f0
Convert TestCygwinCCompiler to pytest
jaraco Aug 6, 2022
6b2f75a
Convert TestDirUtil to pytest
jaraco Aug 6, 2022
65fe024
Convert TestFileUtil to pytest
jaraco Aug 6, 2022
26a3295
Convert TestSysconfig to pytest
jaraco Aug 6, 2022
2bfa852
⚫ Fade to black.
jaraco Aug 6, 2022
538c728
👹 Feed the hobgoblins (delint).
jaraco Aug 6, 2022
0bddfa3
Remove patching of uname.
jaraco Aug 6, 2022
c146a9d
Convert TestUtil to pytest
jaraco Aug 6, 2022
81a7c89
Convert TestUnixCCompiler to pytest
jaraco Aug 6, 2022
e7750dc
Prefer pytest for skip
jaraco Aug 6, 2022
dadeb7e
Convert more tests to pytest
jaraco Aug 6, 2022
a84053c
Prefer pytest for skip
jaraco Aug 6, 2022
3774252
Prefer pytest for skip
jaraco Aug 6, 2022
69e46e5
Convert TestBuild to pytest
jaraco Aug 6, 2022
94467c2
Prefer pytest for skip
jaraco Aug 6, 2022
b712592
Prefer pytest for skip
jaraco Aug 6, 2022
e43857e
Remove unreachable code
jaraco Aug 6, 2022
3f16eed
Copy xxmodule.c from Python 3.11 and 3.8, restoring tests for build_ext.
jaraco Aug 6, 2022
36f96c1
Exclude Python 3.11 on macOS due to lack of wheels. Ref pypa/distutil…
jaraco Aug 6, 2022
6fcdbce
Mark test as xfail for now. Ref pypa/distutils#166.
jaraco Aug 6, 2022
78a0389
Use pathlib to read the text
jaraco Aug 6, 2022
3e984a6
⚫ Fade to black.
jaraco Aug 6, 2022
2bf5e9e
Convert TestInstall to pytest
jaraco Aug 6, 2022
3a0b6d6
Only xfail on Windows
jaraco Aug 6, 2022
45cbb60
Allow overriding toxworkdir with an env var.
jaraco Aug 6, 2022
31f6310
Ensure sys.version is restored in test_cygwinccompiler. Fixes #166.
jaraco Aug 6, 2022
1dafb52
Run test_xx in process, utilizing import_helper
jaraco Aug 6, 2022
6757e55
Redirect extension module to a directory that's not deleted on Windows.
jaraco Aug 6, 2022
41eeed0
Include cygwin
jaraco Aug 6, 2022
41ff21f
Merge pull request pypa/distutils#168 from pypa/tests/in-process-exte…
jaraco Aug 6, 2022
43ab893
Prefer pytest in test_build_py
jaraco Aug 6, 2022
02edee3
Prefer pytest in test_check
jaraco Aug 7, 2022
1f95850
Refactor imports around docutils.
jaraco Aug 7, 2022
ac50c2f
Replace addCleanup with monkeypatch.
jaraco Aug 7, 2022
327e447
Enable tests requiring docutils.
jaraco Aug 7, 2022
6a3710c
Fix broken tests around docutils.
jaraco Aug 7, 2022
c424429
Convert PendingDeprecationWarnings to DeprecationWarnings.
jaraco Aug 7, 2022
e1a17fa
Ignore unactionable warnings in docutils.
jaraco Aug 7, 2022
ebed3ab
Prefer pytest for skip
jaraco Aug 7, 2022
28a8896
Prefer pytest for skip
jaraco Aug 7, 2022
61ec7e4
Prefer pytest for skip
jaraco Aug 7, 2022
34e6c21
Prefer pytest for skip
jaraco Aug 7, 2022
be281f5
Prefer pytest for skip
jaraco Aug 7, 2022
d404b3a
Convert TestLog to pytest.
jaraco Aug 7, 2022
b321a62
Prefer pytest for skip
jaraco Aug 7, 2022
8f53164
Consolidate tests
jaraco Aug 7, 2022
e69b761
Prefer pytest for skip
jaraco Aug 7, 2022
3d5bd7c
Prefer pytest for skip
jaraco Aug 7, 2022
61c65f5
Convert unconditional skip to conditional skip. Mark test as xfail be…
jaraco Aug 7, 2022
d444c8c
Prefer pytest for skip
jaraco Aug 7, 2022
8e8d371
⚫ Fade to black.
jaraco Aug 7, 2022
3e2c8ab
Convert unix_compat to pytest skips
jaraco Aug 7, 2022
9c85832
Consistently import unittest.mock.
jaraco Aug 7, 2022
73350d2
Prefer pytest for skip
jaraco Aug 7, 2022
59a108f
Remove unnecessary comment.
jaraco Aug 7, 2022
46c0d76
⚫ Fade to black.
jaraco Aug 7, 2022
a7c11f8
👹 Feed the hobgoblins (delint).
jaraco Aug 7, 2022
f7cff18
Prefer tabs
jaraco Aug 7, 2022
17fda7e
Add pytest-flake8 and pytest-black and pytest-cov to test lint and st…
jaraco Aug 7, 2022
8813a17
👹 Feed the hobgoblins (delint).
jaraco Aug 7, 2022
80dd6f7
Add test capturing failed expectation.
jaraco Aug 6, 2022
dc11307
Add compatibility for Python 3.7
jaraco Aug 6, 2022
47c61e1
Windows is sensitive even on Python 3.10
jaraco Aug 6, 2022
561b705
Also test library dirs
jaraco Aug 6, 2022
1afdbe3
Extract fixture for c_file
jaraco Aug 6, 2022
7849c89
Generate a C file that imports Python.h and something platform specific.
jaraco Aug 8, 2022
530b119
Ensure Python include directory is configured.
jaraco Aug 8, 2022
71cffcb
Extend the test to compile a second time after setting include dirs a…
jaraco Aug 9, 2022
c84d3e5
Ensure Windows SDK directories are not cleared when caller specifies …
zooba Jun 17, 2022
d7b020b
Remove stray colon
zooba Jun 17, 2022
a223350
Fixup bad super() call
zooba Jun 17, 2022
d1e3b46
Use CCompiler._fix_compile_args to fix args to compile()
zooba Aug 1, 2022
7d9c9d4
⚫ Fade to black.
jaraco Aug 9, 2022
53eace5
Merge branch 'bugfix/153-test' into msvccompiler
jaraco Aug 9, 2022
9f9a3e5
Allow compiler classes to supply include and library dirs at the clas…
jaraco Aug 10, 2022
3e4c7a7
Disallow repeat calls to .initialize in one place.
jaraco Aug 10, 2022
b65aa40
Merge pull request #153 from zooba/msvccompiler
jaraco Aug 10, 2022
1d36597
Merge https://github.com/pypa/distutils into distutils-b65aa40
jaraco Aug 10, 2022
73d8052
Update changelog
jaraco Aug 10, 2022
ba9a3ea
Revert "Disallow repeat calls to .initialize in one place."
jaraco Aug 10, 2022
d6d341f
Merge https://github.com/pypa/distutils into distutils-b65aa40
jaraco Aug 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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