From: JinWang An Date: Mon, 27 Mar 2023 08:02:54 +0000 (+0900) Subject: Imported Upstream version 64.0.3 X-Git-Tag: upstream/64.0.3^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cfab6b79e402bbe459e0b3f80a9501ef900435a9;p=platform%2Fupstream%2Fpython-setuptools.git Imported Upstream version 64.0.3 --- diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 617ffcb..f8ab2b2 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 64.0.2 +current_version = 64.0.3 commit = True tag = True diff --git a/CHANGES.rst b/CHANGES.rst index 3efa5f7..cceb12b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,18 @@ +v64.0.3 +------- + + +Misc +^^^^ +* #3515: Fixed "inline" file copying for editable installations and + optional extensions. +* #3517: Fixed ``editable_wheel`` to ensure other commands are finalized before using + them. This should prevent errors with plugins trying to use different commands + or reinitializing them. +* #3517: Augmented filter to prevent transient/temporary source files from being + considered ``package_data`` or ``data_files``. + + v64.0.2 ------- diff --git a/docs/userguide/development_mode.rst b/docs/userguide/development_mode.rst index ddf9a3f..d2d5c70 100644 --- a/docs/userguide/development_mode.rst +++ b/docs/userguide/development_mode.rst @@ -200,8 +200,8 @@ This *may* cause the installer (e.g. ``pip``) to effectively run the "legacy" installation command: ``python setup.py develop`` [#installer]_. -How editable installations work? --------------------------------- +How editable installations work +------------------------------- *Advanced topic* diff --git a/setup.cfg b/setup.cfg index 840b82e..23f119a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = setuptools -version = 64.0.2 +version = 64.0.3 author = Python Packaging Authority author_email = distutils-sig@python.org description = Easily download, build, install, upgrade, and uninstall Python packages diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py index 7ad5a87..cbfe3ec 100644 --- a/setuptools/command/build_ext.py +++ b/setuptools/command/build_ext.py @@ -104,7 +104,8 @@ class build_ext(_build_ext): # Always copy, even if source is older than destination, to ensure # that the right extensions for the current Python/platform are # used. - self.copy_file(regular_file, inplace_file, level=self.verbose) + if os.path.exists(regular_file) or not ext.optional: + self.copy_file(regular_file, inplace_file, level=self.verbose) if ext._needs_stub: inplace_stub = self._get_equivalent_stub(ext, inplace_file) diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 8b1a332..ec06274 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -184,7 +184,7 @@ class build_py(orig.build_py): files = ei_cmd.filelist.files check = _IncludePackageDataAbuse() - for path in _filter_absolute_egg_info(files, egg_info_dir): + for path in self._filter_build_files(files, egg_info_dir): d, f = os.path.split(assert_relative(path)) prev = None oldf = f @@ -202,6 +202,25 @@ class build_py(orig.build_py): check.warn(importable) mf.setdefault(src_dirs[d], []).append(path) + def _filter_build_files(self, files: Iterable[str], egg_info: str) -> Iterator[str]: + """ + ``build_meta`` may try to create egg_info outside of the project directory, + and this can be problematic for certain plugins (reported in issue #3500). + + Extensions might also include between their sources files created on the + ``build_lib`` and ``build_temp`` directories. + + This function should filter this case of invalid files out. + """ + build = self.get_finalized_command("build") + build_dirs = (egg_info, self.build_lib, build.build_temp, build.build_base) + norm_dirs = [os.path.normpath(p) for p in build_dirs if p] + + for file in files: + norm_path = os.path.normpath(file) + if not os.path.isabs(file) or all(d not in norm_path for d in norm_dirs): + yield file + def get_data_files(self): pass # Lazily compute data files in _get_data_files() function. @@ -347,15 +366,3 @@ class _IncludePackageDataAbuse: msg = textwrap.dedent(self.MESSAGE).format(importable=importable) warnings.warn(msg, SetuptoolsDeprecationWarning, stacklevel=2) self._already_warned.add(importable) - - -def _filter_absolute_egg_info(files: Iterable[str], egg_info: str) -> Iterator[str]: - """ - ``build_meta`` may try to create egg_info outside of the project directory, - and this can be problematic for certain plugins (reported in issue #3500). - This function should filter this case of invalid files out. - """ - egg_info_name = Path(egg_info).name - for file in files: - if not (egg_info_name in file and os.path.isabs(file)): - yield file diff --git a/setuptools/command/editable_wheel.py b/setuptools/command/editable_wheel.py index 2631a08..560efeb 100644 --- a/setuptools/command/editable_wheel.py +++ b/setuptools/command/editable_wheel.py @@ -133,7 +133,8 @@ class editable_wheel(Command): self._ensure_dist_info() # Add missing dist_info files - bdist_wheel = self.reinitialize_command("bdist_wheel") + self.reinitialize_command("bdist_wheel") + bdist_wheel = self.get_finalized_command("bdist_wheel") bdist_wheel.write_wheelfile(self.dist_info_dir) self._create_wheel_file(bdist_wheel) @@ -156,7 +157,7 @@ class editable_wheel(Command): if self.dist_info_dir is None: dist_info = self.reinitialize_command("dist_info") dist_info.output_dir = self.dist_dir - dist_info.finalize_options() + dist_info.ensure_finalized() dist_info.run() self.dist_info_dir = dist_info.dist_info_dir else: @@ -278,7 +279,7 @@ class editable_wheel(Command): # Also remove _safely_run, TestCustomBuildPy. Suggested date: Aug/2023. build: Command = self.get_finalized_command("build") for name in build.get_sub_commands(): - cmd = self.distribution.get_command_obj(name) + cmd = self.get_finalized_command(name) if name == "build_py" and type(cmd) != build_py_cls: self._safely_run(name) else: diff --git a/setuptools/tests/test_build_ext.py b/setuptools/tests/test_build_ext.py index 07ebcaf..92ce80e 100644 --- a/setuptools/tests/test_build_ext.py +++ b/setuptools/tests/test_build_ext.py @@ -9,10 +9,13 @@ from jaraco import path from setuptools.command.build_ext import build_ext, get_abi3_suffix from setuptools.dist import Distribution from setuptools.extension import Extension +from setuptools.errors import CompileError from . import environment from .textwrap import DALS +import pytest + IS_PYPY = '__pypy__' in sys.builtin_module_names @@ -176,6 +179,40 @@ class TestBuildExt: assert example_stub.endswith(".pyc") +class TestBuildExtInplace: + def get_build_ext_cmd(self, optional: bool, **opts): + files = { + "eggs.c": "#include missingheader.h\n", + ".build": {"lib": {}, "tmp": {}}, + } + path.build(files) + extension = Extension('spam.eggs', ['eggs.c'], optional=optional) + dist = Distribution(dict(ext_modules=[extension])) + dist.script_name = 'setup.py' + cmd = build_ext(dist) + vars(cmd).update(build_lib=".build/lib", build_temp=".build/tmp", **opts) + cmd.ensure_finalized() + return cmd + + def test_optional(self, tmpdir_cwd, capsys): + """ + If optional extensions fail to build, setuptools should show the error + in the logs but not fail to build + """ + cmd = self.get_build_ext_cmd(optional=True, inplace=True) + cmd.run() + logs = capsys.readouterr() + messages = (logs.out + logs.err) + assert 'build_ext: building extension "spam.eggs" failed' in messages + # No compile error exception should be raised + + def test_non_optional(self, tmpdir_cwd): + # Non-optional extensions should raise an exception + cmd = self.get_build_ext_cmd(optional=False, inplace=True) + with pytest.raises(CompileError): + cmd.run() + + def test_build_ext_config_handling(tmpdir_cwd): files = { 'setup.py': DALS( diff --git a/setuptools/tests/test_editable_install.py b/setuptools/tests/test_editable_install.py index 67d377e..900ec1b 100644 --- a/setuptools/tests/test_editable_install.py +++ b/setuptools/tests/test_editable_install.py @@ -25,6 +25,7 @@ from setuptools.command.editable_wheel import ( _find_namespaces, _find_package_roots, _finder_template, + editable_wheel, ) from setuptools.dist import Distribution @@ -846,6 +847,36 @@ class TestCustomBuildPy: assert b"42" in out +class TestCustomBuildWheel: + def install_custom_build_wheel(self, dist): + bdist_wheel_cls = dist.get_command_class("bdist_wheel") + + class MyBdistWheel(bdist_wheel_cls): + def get_tag(self): + # In issue #3513, we can see that some extensions may try to access + # the `plat_name` property in bdist_wheel + if self.plat_name.startswith("macosx-"): + _ = "macOS platform" + return super().get_tag() + + dist.cmdclass["bdist_wheel"] = MyBdistWheel + + def test_access_plat_name(self, tmpdir_cwd): + # Even when a custom bdist_wheel tries to access plat_name the build should + # be successful + jaraco.path.build({"module.py": "x = 42"}) + dist = Distribution() + dist.script_name = "setup.py" + dist.set_defaults() + self.install_custom_build_wheel(dist) + cmd = editable_wheel(dist) + cmd.ensure_finalized() + cmd.run() + wheel_file = str(next(Path().glob('dist/*'))) + assert "editable" in wheel_file + assert wheel_file.endswith(".whl") + + def install_project(name, venv, tmp_path, files, *opts): project = tmp_path / name project.mkdir()