From: JinWang An Date: Mon, 27 Mar 2023 08:02:55 +0000 (+0900) Subject: Imported Upstream version 65.0.1 X-Git-Tag: upstream/65.0.1^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4d0cca8263330203fb13faca5cb8f5eb84a12c6e;p=platform%2Fupstream%2Fpython-setuptools.git Imported Upstream version 65.0.1 --- diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 05e78cd..bbfad4b 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 65.0.0 +current_version = 65.0.1 commit = True tag = True diff --git a/CHANGES.rst b/CHANGES.rst index d4d6437..185697c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,20 @@ +v65.0.1 +------- + + +Documentation changes +^^^^^^^^^^^^^^^^^^^^^ +* #3529: Added clarification to :doc:`/userguide/quickstart` about support + to ``setup.py``. + +Misc +^^^^ +* #3526: Fix backward compatibility of editable installs and custom ``build_ext`` + commands inheriting directly from ``distutils``. +* #3528: Fixed ``buid_meta.prepare_metadata_for_build_wheel`` when + given ``metadata_directory`` is ``"."``. + + v65.0.0 ------- diff --git a/docs/pkg_resources.rst b/docs/pkg_resources.rst index 21ff6dc..40e5e6f 100644 --- a/docs/pkg_resources.rst +++ b/docs/pkg_resources.rst @@ -10,12 +10,13 @@ eggs, support for merging packages that have separately-distributed modules or subpackages, and APIs for managing Python's current "working set" of active packages. -Use of ``pkg_resources`` is discouraged in favor of -`importlib.resources `_, -`importlib.metadata `_, -and their backports (:pypi:`importlib_resources`, -:pypi:`importlib_metadata`). -Please consider using those libraries instead of pkg_resources. +.. attention:: + Use of ``pkg_resources`` is discouraged in favor of + `importlib.resources `_, + `importlib.metadata `_, + and their backports (:pypi:`importlib_resources`, + :pypi:`importlib_metadata`). + Please consider using those libraries instead of pkg_resources. -------- diff --git a/docs/userguide/quickstart.rst b/docs/userguide/quickstart.rst index bf76f2c..352a37b 100644 --- a/docs/userguide/quickstart.rst +++ b/docs/userguide/quickstart.rst @@ -59,8 +59,7 @@ library will be used to actually do the packaging. In addition to specifying a build system, you also will need to add some package information such as metadata, contents, dependencies, etc. This can be done in the same ``pyproject.toml`` [#beta]_ file, -or in a separated one: ``setup.cfg`` or ``setup.py`` (please note however -that configuring new projects via ``setup.py`` is discouraged [#setup.py]_). +or in a separated one: ``setup.cfg`` or ``setup.py`` [#setup.py]_. The following example demonstrates a minimum configuration (which assumes the project depends on :pypi:`requests` and @@ -149,6 +148,27 @@ to specify to properly package your project. could have a diagram for that (explaining for example that "wheels" are built from "sdists" not the source tree). +.. _setuppy_discouraged: +.. admonition:: Info: Using ``setup.py`` + :class: seealso + + Setuptools offers first class support for ``setup.py`` files as a configuration + mechanism. + + It is important to remember, however, that running this file as a + script (e.g. ``python setup.py sdist``) is strongly **discouraged**, and + that the majority of the command line interfaces are (or will be) **deprecated** + (e.g. ``python setup.py install``, ``python setup.py bdist_wininst``, ...). + + We also recommend users to expose as much as possible configuration in a + more *declarative* way via the :doc:`pyproject.toml ` or + :doc:`setup.cfg `, and keep the ``setup.py`` minimal + with only the dynamic parts (or even omit it completely if applicable). + + See `Why you shouldn't invoke setup.py directly`_ for more background. + +.. _Why you shouldn't invoke setup.py directly: https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html + Overview ======== @@ -438,14 +458,15 @@ up-to-date references that can help you when it is time to distribute your work. .. rubric:: Notes .. [#setup.py] - The ``setup.py`` file should be used only when custom scripting during the - build is necessary. + New projects are advised to avoid ``setup.py`` configurations (beyond the minimal stub) + when custom scripting during the build is not necessary. Examples are kept in this document to help people interested in maintaining or contributing to existing packages that use ``setup.py``. Note that you can still keep most of configuration declarative in :doc:`setup.cfg ` or :doc:`pyproject.toml ` and use ``setup.py`` only for the parts not supported in those files (e.g. C extensions). + See :ref:`note `. .. [#beta] Support for adding build configuration options via the ``[tool.setuptools]`` diff --git a/setup.cfg b/setup.cfg index 25a0541..3346b1f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = setuptools -version = 65.0.0 +version = 65.0.1 author = Python Packaging Authority author_email = distutils-sig@python.org description = Easily download, build, install, upgrade, and uninstall Python packages diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 98fb148..8ff9a5c 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -40,6 +40,7 @@ from typing import Dict, Iterator, List, Optional, Union import setuptools import distutils +from . import errors from ._path import same_path from ._reqs import parse_strings from ._deprecation_warning import SetuptoolsDeprecationWarning @@ -346,16 +347,23 @@ class _BuildMetaBackend(_ConfigSettingsTranslator): Returns the basename of the info directory, e.g. `proj-0.0.0.dist-info`. """ - candidates = list(Path(metadata_directory).glob(f"**/*{suffix}/")) - assert len(candidates) == 1, f"Exactly one {suffix} should have been produced" - info_dir = candidates[0] - + info_dir = self._find_info_directory(metadata_directory, suffix) if not same_path(info_dir.parent, metadata_directory): shutil.move(str(info_dir), metadata_directory) # PEP 517 allow other files and dirs to exist in metadata_directory - return info_dir.name + def _find_info_directory(self, metadata_directory: str, suffix: str) -> Path: + for parent, dirs, _ in os.walk(metadata_directory): + candidates = [f for f in dirs if f.endswith(suffix)] + + if len(candidates) != 0 or len(dirs) != 1: + assert len(candidates) == 1, f"Multiple {suffix} directories found" + return Path(parent, candidates[0]) + + msg = f"No {suffix} directory found in {metadata_directory}" + raise errors.InternalError(msg) + def prepare_metadata_for_build_wheel(self, metadata_directory, config_settings=None): sys.argv = [ diff --git a/setuptools/command/editable_wheel.py b/setuptools/command/editable_wheel.py index 560efeb..ea21484 100644 --- a/setuptools/command/editable_wheel.py +++ b/setuptools/command/editable_wheel.py @@ -237,6 +237,8 @@ class editable_wheel(Command): cmd = dist.get_command_obj(cmd_name) if hasattr(cmd, "editable_mode"): cmd.editable_mode = True + elif hasattr(cmd, "inplace"): + cmd.inplace = True # backward compatibility with distutils def _collect_build_outputs(self) -> Tuple[List[str], Dict[str, str]]: files: List[str] = [] diff --git a/setuptools/tests/test_build_meta.py b/setuptools/tests/test_build_meta.py index e70c71b..bf1c27f 100644 --- a/setuptools/tests/test_build_meta.py +++ b/setuptools/tests/test_build_meta.py @@ -485,6 +485,23 @@ class TestBuildMetaBackend: assert os.path.isfile(os.path.join(dist_dir, dist_info, 'METADATA')) + def test_prepare_metadata_inplace(self, build_backend): + """ + Some users might pass metadata_directory pre-populated with `.tox` or `.venv`. + See issue #3523. + """ + for pre_existing in [ + ".tox/python/lib/python3.10/site-packages/attrs-22.1.0.dist-info", + ".tox/python/lib/python3.10/site-packages/autocommand-2.2.1.dist-info", + ".nox/python/lib/python3.10/site-packages/build-0.8.0.dist-info", + ".venv/python3.10/site-packages/click-8.1.3.dist-info", + "venv/python3.10/site-packages/distlib-0.3.5.dist-info", + "env/python3.10/site-packages/docutils-0.19.dist-info", + ]: + os.makedirs(pre_existing, exist_ok=True) + dist_info = build_backend.prepare_metadata_for_build_wheel(".") + assert os.path.isfile(os.path.join(dist_info, 'METADATA')) + def test_build_sdist_explicit_dist(self, build_backend): # explicitly specifying the dist folder should work # the folder sdist_directory and the ``--dist-dir`` can be the same diff --git a/setuptools/tests/test_editable_install.py b/setuptools/tests/test_editable_install.py index 900ec1b..6b5cdd1 100644 --- a/setuptools/tests/test_editable_install.py +++ b/setuptools/tests/test_editable_install.py @@ -5,6 +5,7 @@ import subprocess import platform from copy import deepcopy from importlib import import_module +from importlib.machinery import EXTENSION_SUFFIXES from pathlib import Path from textwrap import dedent from unittest.mock import Mock @@ -28,6 +29,7 @@ from setuptools.command.editable_wheel import ( editable_wheel, ) from setuptools.dist import Distribution +from setuptools.extension import Extension @pytest.fixture(params=["strict", "lenient"]) @@ -872,9 +874,40 @@ class TestCustomBuildWheel: cmd = editable_wheel(dist) cmd.ensure_finalized() cmd.run() - wheel_file = str(next(Path().glob('dist/*'))) + wheel_file = str(next(Path().glob('dist/*.whl'))) assert "editable" in wheel_file - assert wheel_file.endswith(".whl") + + +class TestCustomBuildExt: + def install_custom_build_ext_distutils(self, dist): + from distutils.command.build_ext import build_ext as build_ext_cls + + class MyBuildExt(build_ext_cls): + pass + + dist.cmdclass["build_ext"] = MyBuildExt + + @pytest.mark.skipif( + sys.platform != "linux", reason="compilers may fail without correct setup" + ) + def test_distutils_leave_inplace_files(self, tmpdir_cwd): + jaraco.path.build({"module.c": ""}) + attrs = { + "ext_modules": [Extension("module", ["module.c"])], + } + dist = Distribution(attrs) + dist.script_name = "setup.py" + dist.set_defaults() + self.install_custom_build_ext_distutils(dist) + cmd = editable_wheel(dist) + cmd.ensure_finalized() + cmd.run() + wheel_file = str(next(Path().glob('dist/*.whl'))) + assert "editable" in wheel_file + files = [p for p in Path().glob("module.*") if p.suffix != ".c"] + assert len(files) == 1 + name = files[0].name + assert any(name.endswith(ext) for ext in EXTENSION_SUFFIXES) def install_project(name, venv, tmp_path, files, *opts):