From f9eb56d63c25dbc1e31d4d87c4d569f2b7b301c3 Mon Sep 17 00:00:00 2001 From: JinWang An Date: Mon, 27 Mar 2023 17:02:35 +0900 Subject: [PATCH] Imported Upstream version 57.5.0 --- .bumpversion.cfg | 2 +- .pre-commit-config.yaml | 10 ------- CHANGES.rst | 13 +++++++++ docs/setuptools.rst | 2 +- docs/userguide/declarative_config.rst | 1 + docs/userguide/dependency_management.rst | 37 ++++++++++++------------ docs/userguide/entry_point.rst | 6 ++-- docs/userguide/extension.rst | 2 +- docs/userguide/package_discovery.rst | 25 ++++++++-------- setup.cfg | 16 +++++----- setuptools/command/easy_install.py | 6 ++-- setuptools/config.py | 31 +++++++++++++++++++- setuptools/tests/test_config.py | 35 ++++++++++++++++++++++ tox.ini | 3 ++ 14 files changed, 131 insertions(+), 58 deletions(-) delete mode 100644 .pre-commit-config.yaml diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 53c5152..a1bb0f9 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 57.4.0 +current_version = 57.5.0 commit = True tag = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index c15ab0c..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,10 +0,0 @@ -repos: -- repo: https://github.com/psf/black - rev: 20.8b1 - hooks: - - id: black - -- repo: https://github.com/asottile/blacken-docs - rev: v1.9.1 - hooks: - - id: blacken-docs diff --git a/CHANGES.rst b/CHANGES.rst index d995138..2abf009 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,16 @@ +v57.5.0 +------- + + +Changes +^^^^^^^ +* #2712: Added implicit globbing support for `[options.data_files]` values. + +Documentation changes +^^^^^^^^^^^^^^^^^^^^^ +* #2737: fix various syntax and style errors in code snippets in docs + + v57.4.0 ------- diff --git a/docs/setuptools.rst b/docs/setuptools.rst index 1440016..c5a89ad 100644 --- a/docs/setuptools.rst +++ b/docs/setuptools.rst @@ -132,7 +132,7 @@ only a ``setuptools.setup()`` call. .. note:: :pep:`517` doesn't support editable installs so this is currently - incompatible with ``pip install -e .``, as :pep:`517` does not support editable installs. + incompatible with ``pip install -e .``. This means that you can have a Python project with all build configuration specified in ``setup.cfg``, without a ``setup.py`` file, if you **can rely diff --git a/docs/userguide/declarative_config.rst b/docs/userguide/declarative_config.rst index 128d9f9..3b72611 100644 --- a/docs/userguide/declarative_config.rst +++ b/docs/userguide/declarative_config.rst @@ -68,6 +68,7 @@ boilerplate code in some cases. site.d/00_default.conf host.d/00_default.conf data = data/img/logo.png, data/svg/icon.svg + fonts = data/fonts/*.ttf, data/fonts/*.otf Metadata and options are set in the config sections of the same name. diff --git a/docs/userguide/dependency_management.rst b/docs/userguide/dependency_management.rst index 1c61079..b97896b 100644 --- a/docs/userguide/dependency_management.rst +++ b/docs/userguide/dependency_management.rst @@ -62,11 +62,11 @@ finesse to it, let's start with a simple example. .. code-block:: python setup( - #..., - install_requires = [ + ..., + install_requires=[ 'docutils', - 'BazSpam ==1.1' - ] + 'BazSpam ==1.1', + ], ) @@ -98,9 +98,10 @@ the Python version is older than 3.4. To accomplish this .. code-block:: python setup( - #... + ..., install_requires=[ - "enum34;python_version<'3.4'",] + "enum34;python_version<'3.4'", + ], ) Similarly, if you also wish to declare ``pywin32`` with a minimal version of 1.0 @@ -121,11 +122,11 @@ and only install it if the user is using a Windows operating system: .. code-block:: python setup( - #... + ..., install_requires=[ "enum34;python_version<'3.4'", - "pywin32 >= 1.0;platform_system=='Windows'" - ] + "pywin32 >= 1.0;platform_system=='Windows'", + ], ) The environmental markers that may be used for testing platform types are @@ -204,9 +205,9 @@ distributions, if the package's dependencies aren't already installed: .. code-block:: python setup( - #... + ..., dependency_links=[ - "http://peak.telecommunity.com/snapshots/" + "http://peak.telecommunity.com/snapshots/", ], ) @@ -242,10 +243,10 @@ dependencies for it to work: setup( name="Project-A", - #... + ..., extras_require={ - "PDF": ["ReportLab>=1.2", "RXP"], - } + "PDF": ["ReportLab>=1.2", "RXP"], + }, ) The name ``PDF`` is an arbitrary identifier of such a list of dependencies, to @@ -274,14 +275,14 @@ First is the console_scripts entry point: .. code-block:: python setup( - name = "Project-A" - #..., + name="Project-A", + ..., entry_points={ "console_scripts": [ "rst2pdf = project_a.tools.pdfgen [PDF]", "rst2html = project_a.tools.htmlgen", ], - } + }, ) This syntax indicates that the entry point (in this case a console script) @@ -315,7 +316,7 @@ installed, it might declare the dependency like this: setup( name="Project-B", install_requires=["Project-A[PDF]"], - ... + ..., ) This will cause ReportLab to be installed along with project A, if project B is diff --git a/docs/userguide/entry_point.rst b/docs/userguide/entry_point.rst index 63d30a4..c92ccf7 100644 --- a/docs/userguide/entry_point.rst +++ b/docs/userguide/entry_point.rst @@ -36,6 +36,7 @@ and ``__main__.py`` providing a hook: .. code-block:: python from . import hello_world + if __name__ == '__main__': hello_world() @@ -102,7 +103,7 @@ module (part of stdlib since Python 3.8) or its backport, For example, to find the console script entry points from the example above: -.. code-block:: python +.. code-block:: pycon >>> from importlib import metadata >>> eps = metadata.entry_points()['console_scripts'] @@ -121,13 +122,14 @@ method to import and load that entry point (module or object). Then, a different project wishing to load 'my.plugins' plugins could run the following routine to load (and invoke) such plugins: -.. code-block:: python +.. code-block:: pycon >>> from importlib import metadata >>> eps = metadata.entry_points()['my.plugins'] >>> for ep in eps: ... plugin = ep.load() ... plugin() + ... The project soliciting the entry points needs not to have any dependency or prior knowledge about the libraries implementing the entry points, and diff --git a/docs/userguide/extension.rst b/docs/userguide/extension.rst index 4de24ec..93b5950 100644 --- a/docs/userguide/extension.rst +++ b/docs/userguide/extension.rst @@ -202,7 +202,7 @@ called "foobar", you would write a function something like this: .. code-block:: python def find_files_for_foobar(dirname): - # loop to yield paths that start with `dirname` + ... # loop to yield paths that start with `dirname` And you would register it in a setup script using something like this:: diff --git a/docs/userguide/package_discovery.rst b/docs/userguide/package_discovery.rst index 0a8070a..551e02e 100644 --- a/docs/userguide/package_discovery.rst +++ b/docs/userguide/package_discovery.rst @@ -34,8 +34,8 @@ included manually in the following manner: .. code-block:: python setup( - #... - packages = ['mypkg1', 'mypkg2'] + # ... + packages=['mypkg1', 'mypkg2'] ) This can get tiresome reallly quickly. To speed things up, we introduce two @@ -55,7 +55,8 @@ functions provided by setuptools: .. code-block:: python from setuptools import find_packages - #or + + # or from setuptools import find_namespace_packages @@ -98,14 +99,14 @@ in ``src`` that starts with the name ``pkg`` and not ``additional``: .. code-block:: python setup( - #... - packages = find_packages( - where = 'src', - include = ['pkg*',], - exclude = ['additional',] + # ... + packages=find_packages( + where='src', + include=['pkg*'], + exclude=['additional'], ), - package_dir = {"":"src"} - #... + package_dir={"": "src"} + # ... ) @@ -129,7 +130,7 @@ If both ``Desktop`` and ``Library`` are on your ``PYTHONPATH``, then a namespace package called ``timmins`` will be created automatically for you when you invoke the import mechanism, allowing you to accomplish the following -.. code-block:: python +.. code-block:: pycon >>> import timmins.foo >>> import timmins.bar @@ -220,7 +221,7 @@ And the ``namespace_packages`` keyword in your ``setup.cfg`` or ``setup.py``: setup( # ... - namespace_packages = ['timmins'] + namespace_packages=['timmins'] ) And your directory should look like this diff --git a/setup.cfg b/setup.cfg index 790b5c6..b1afa54 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,8 +1,6 @@ [metadata] -license_files = - LICENSE name = setuptools -version = 57.4.0 +version = 57.5.0 author = Python Packaging Authority author_email = distutils-sig@python.org description = Easily download, build, install, upgrade, and uninstall Python packages @@ -44,13 +42,13 @@ testing = pytest >= 4.6 pytest-checkdocs >= 2.4 pytest-flake8 - # python_implementation: workaround for jaraco/skeleton#22 - # python_version: workaround for python/typed_ast#156 - pytest-black >= 0.3.7; python_implementation != "PyPy" and python_version < "3.10" + pytest-black >= 0.3.7; \ + # workaround for jaraco/skeleton#22 + python_implementation != "PyPy" pytest-cov - # python_implementation: workaround for jaraco/skeleton#22 - # python_version: workaround for python/typed_ast#156 - pytest-mypy; python_implementation != "PyPy" and python_version < "3.10" + pytest-mypy; \ + # workaround for jaraco/skeleton#22 + python_implementation != "PyPy" pytest-enabler >= 1.0.1 # local diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 45adb6a..43bd295 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -6,7 +6,7 @@ A tool for doing automatic download/extract/build of distutils-based Python packages. For detailed documentation, see the accompanying EasyInstall.txt file, or visit the `EasyInstall home page`__. -__ https://setuptools.readthedocs.io/en/latest/easy_install.html +__ https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html """ @@ -513,7 +513,7 @@ class easy_install(Command): For information on other options, you may wish to consult the documentation at: - https://setuptools.readthedocs.io/en/latest/easy_install.html + https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html Please make the appropriate changes for your system and try again. """).lstrip() # noqa @@ -1306,7 +1306,7 @@ class easy_install(Command): * You can set up the installation directory to support ".pth" files by using one of the approaches described here: - https://setuptools.readthedocs.io/en/latest/easy_install.html#custom-installation-locations + https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html#custom-installation-locations Please make the appropriate changes for your system and try again. diff --git a/setuptools/config.py b/setuptools/config.py index 44de7cf..7ab6bfd 100644 --- a/setuptools/config.py +++ b/setuptools/config.py @@ -9,6 +9,7 @@ import importlib from collections import defaultdict from functools import partial from functools import wraps +from glob import iglob import contextlib from distutils.errors import DistutilsOptionError, DistutilsFileError @@ -255,6 +256,34 @@ class ConfigHandler: return [chunk.strip() for chunk in value if chunk.strip()] + @classmethod + def _parse_list_glob(cls, value, separator=','): + """Equivalent to _parse_list() but expands any glob patterns using glob(). + + However, unlike with glob() calls, the results remain relative paths. + + :param value: + :param separator: List items separator character. + :rtype: list + """ + glob_characters = ('*', '?', '[', ']', '{', '}') + values = cls._parse_list(value, separator=separator) + expanded_values = [] + for value in values: + + # Has globby characters? + if any(char in value for char in glob_characters): + # then expand the glob pattern while keeping paths *relative*: + expanded_values.extend(sorted( + os.path.relpath(path, os.getcwd()) + for path in iglob(os.path.abspath(value)))) + + else: + # take the value as-is: + expanded_values.append(value) + + return expanded_values + @classmethod def _parse_dict(cls, value): """Represents value as a dict. @@ -711,5 +740,5 @@ class ConfigOptionsHandler(ConfigHandler): :param dict section_options: """ - parsed = self._parse_section_to_dict(section_options, self._parse_list) + parsed = self._parse_section_to_dict(section_options, self._parse_list_glob) self['data_files'] = [(k, v) for k, v in parsed.items()] diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py index 21f1bec..ec65250 100644 --- a/setuptools/tests/test_config.py +++ b/setuptools/tests/test_config.py @@ -893,6 +893,41 @@ class TestOptions: ] assert sorted(dist.data_files) == sorted(expected) + def test_data_files_globby(self, tmpdir): + fake_env( + tmpdir, + '[options.data_files]\n' + 'cfg =\n' + ' a/b.conf\n' + ' c/d.conf\n' + 'data = *.dat\n' + 'icons = \n' + ' *.ico\n' + 'audio = \n' + ' *.wav\n' + ' sounds.db\n' + ) + + # Create dummy files for glob()'s sake: + tmpdir.join('a.dat').write('') + tmpdir.join('b.dat').write('') + tmpdir.join('c.dat').write('') + tmpdir.join('a.ico').write('') + tmpdir.join('b.ico').write('') + tmpdir.join('c.ico').write('') + tmpdir.join('beep.wav').write('') + tmpdir.join('boop.wav').write('') + tmpdir.join('sounds.db').write('') + + with get_dist(tmpdir) as dist: + expected = [ + ('cfg', ['a/b.conf', 'c/d.conf']), + ('data', ['a.dat', 'b.dat', 'c.dat']), + ('icons', ['a.ico', 'b.ico', 'c.ico']), + ('audio', ['beep.wav', 'boop.wav', 'sounds.db']), + ] + assert sorted(dist.data_files) == sorted(expected) + def test_python_requires_simple(self, tmpdir): fake_env( tmpdir, diff --git a/tox.ini b/tox.ini index 28ff16a..8a48a1c 100644 --- a/tox.ini +++ b/tox.ini @@ -7,6 +7,9 @@ toxworkdir={env:TOX_WORK_DIR:.tox} [testenv] deps = + # workaround for sphinx-doc/sphinx#9562 + # TODO: remove after Sphinx>4.1.2 is available. + sphinx@git+https://github.com/sphinx-doc/sphinx; python_version>="3.10" commands = pytest {posargs} usedevelop = True -- 2.34.1