Imported Upstream version 54.0.0 upstream/54.0.0
authorJinWang An <jinwang.an@samsung.com>
Mon, 27 Mar 2023 08:02:32 +0000 (17:02 +0900)
committerJinWang An <jinwang.an@samsung.com>
Mon, 27 Mar 2023 08:02:32 +0000 (17:02 +0900)
22 files changed:
.bumpversion.cfg
CHANGES.rst
MANIFEST.in
bootstrap.egg-info/PKG-INFO [new file with mode: 0644]
bootstrap.egg-info/entry_points.txt [new file with mode: 0644]
docs/userguide/declarative_config.rst
pyproject.toml
setup.cfg
setuptools/config.py
setuptools/dist.py
setuptools/tests/files.py [deleted file]
setuptools/tests/test_build_ext.py
setuptools/tests/test_build_meta.py
setuptools/tests/test_config.py
setuptools/tests/test_dist.py
setuptools/tests/test_easy_install.py
setuptools/tests/test_egg_info.py
setuptools/tests/test_glob.py
setuptools/tests/test_sphinx_upload_docs.py
setuptools/tests/test_upload_docs.py
setuptools/tests/test_virtualenv.py
setuptools/tests/test_wheel.py

index a408627e474c236aa0956fd264fd4d8bbaecb133..25490e49c920bc858586e865862fa2a47243d1c9 100644 (file)
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 53.1.0
+current_version = 54.0.0
 commit = True
 tag = True
 
index 7e8c28bf0b121bb81ef09a0d15764f0dd4b99e4b..62f911aa89162c3c92c0a895d5068c50998b116a 100644 (file)
@@ -1,3 +1,21 @@
+v54.0.0
+-------
+
+
+Breaking Changes
+^^^^^^^^^^^^^^^^
+* #2582: Simplified build-from-source story by providing bootstrapping metadata in a separate egg-info directory. Build requirements no longer include setuptools itself. Sdist once again includes the pyproject.toml. Project can no longer be installed from source on pip 19.x, but install from source is still supported on pip < 19 and pip >= 20 and install from wheel is still supported with pip >= 9.
+
+Changes
+^^^^^^^
+* #1932: Handled :code:`AttributeError` by raising :code:`DistutilsSetupError` in :code:`dist.check_specifier()` when specifier is not a string -- by :user:`melissa-kun-li`
+* #2570: Correctly parse cmdclass in setup.cfg.
+
+Documentation changes
+^^^^^^^^^^^^^^^^^^^^^
+* #2553: Added userguide example for markers in extras_require -- by :user:`pwoolvett`
+
+
 v53.1.0
 -------
 
@@ -5,7 +23,7 @@ v53.1.0
 Changes
 ^^^^^^^
 * #1937: Preserved case-sensitivity of keys in setup.cfg so that entry point names are case-sensitive. Changed sensitivity of configparser. NOTE: Any projects relying on case-insensitivity will need to adapt to accept the original case as published. -- by :user:`melissa-kun-li`
-* #2573: Fixed error in uploading a Sphinx doc with the :code:`upload_docs` command. An html builder will be used. 
+* #2573: Fixed error in uploading a Sphinx doc with the :code:`upload_docs` command. An html builder will be used.
   Note: :code:`upload_docs` is deprecated for PyPi, but is supported for other sites -- by :user:`melissa-kun-li`
 
 
index eba40c5de68bd8c15a0de60b6e60b2287fa017f2..3e8f09de37ac1f05757de27a9423dae4723f4b9d 100644 (file)
@@ -15,4 +15,3 @@ include launcher.c
 include msvc-build-launcher.cmd
 include pytest.ini
 include tox.ini
-exclude pyproject.toml  # Temporary workaround for #1644.
diff --git a/bootstrap.egg-info/PKG-INFO b/bootstrap.egg-info/PKG-INFO
new file mode 100644 (file)
index 0000000..6e11cee
--- /dev/null
@@ -0,0 +1,2 @@
+Name: setuptools-bootstrap
+Version: 1.0
diff --git a/bootstrap.egg-info/entry_points.txt b/bootstrap.egg-info/entry_points.txt
new file mode 100644 (file)
index 0000000..834d674
--- /dev/null
@@ -0,0 +1,14 @@
+[distutils.commands]
+egg_info = setuptools.command.egg_info:egg_info
+
+[distutils.setup_keywords]
+include_package_data = setuptools.dist:assert_bool
+install_requires = setuptools.dist:check_requirements
+extras_require = setuptools.dist:check_extras
+entry_points = setuptools.dist:check_entry_points
+
+[egg_info.writers]
+PKG-INFO = setuptools.command.egg_info:write_pkg_info
+dependency_links.txt = setuptools.command.egg_info:overwrite_arg
+entry_points.txt = setuptools.command.egg_info:write_entries
+requires.txt = setuptools.command.egg_info:write_requirements
index bc66869b6ef6da7d6444c96c811549717ebbb354..f2e8b81f75572749d33462514ede853670164c42 100644 (file)
@@ -243,6 +243,19 @@ data_files               dict                                 40.6.0
 
     **find_namespace directive** - The ``find_namespace:`` directive is supported since Python >=3.3.
 
+
 Notes:
 1. In the ``package_data`` section, a key named with a single asterisk (``*``)
 refers to all packages, in lieu of the empty string used in ``setup.py``.
+
+2. In the ``extras_require`` section, values are parsed as ``list-semi``. This implies that in
+order to include markers, they **must** be *dangling*:
+
+.. code-block:: ini
+
+    [options.extras_require]
+    rest = docutils>=0.3; pack ==1.1, ==1.3
+    pdf =
+      ReportLab>=1.2
+      RXP
+      importlib-metadata; python_version < "3.8"
index 414ffed581ab6a6f4ec68ae1c51239f86eb58c00..70e3473d44d52693beb0e8bccdd2001be9fbfd91 100644 (file)
@@ -1,6 +1,5 @@
 [build-system]
 requires = [
-    "setuptools >= 40.8; python_version > '3'",
     "wheel",
 ]
 build-backend = "setuptools.build_meta"
index 12ce13861da4a74a9708cb0566ac57ccf382bf3c..d60a9b2633d6171c301afe0f5ad5079c785798c1 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,7 +2,7 @@
 license_files =
     LICENSE
 name = setuptools
-version = 53.1.0
+version = 54.0.0
 author = Python Packaging Authority
 author_email = distutils-sig@python.org
 description = Easily download, build, install, upgrade, and uninstall Python packages
@@ -41,7 +41,7 @@ exclude =
 testing =
        # upstream
        pytest >= 3.5, !=3.7.3
-       pytest-checkdocs >= 1.2.3
+       pytest-checkdocs >= 2.4
        pytest-flake8
        pytest-black >= 0.3.7; python_implementation != "PyPy"
        pytest-cov
@@ -59,6 +59,7 @@ testing =
     jaraco.envs
     pytest-xdist
     sphinx
+    jaraco.path>=3.2.0
 
 docs =
     # Keep these in sync with docs/requirements.txt
index af3a3bcbd56e3c7bd170e7685ab393fabd83d150..4a6cd4694b071aaf02637fec969cd0aa744efd21 100644 (file)
@@ -574,6 +574,7 @@ class ConfigOptionsHandler(ConfigHandler):
         parse_list_semicolon = partial(self._parse_list, separator=';')
         parse_bool = self._parse_bool
         parse_dict = self._parse_dict
+        parse_cmdclass = self._parse_cmdclass
 
         return {
             'zip_safe': parse_bool,
@@ -594,6 +595,22 @@ class ConfigOptionsHandler(ConfigHandler):
             'entry_points': self._parse_file,
             'py_modules': parse_list,
             'python_requires': SpecifierSet,
+            'cmdclass': parse_cmdclass,
+        }
+
+    def _parse_cmdclass(self, value):
+        def resolve_class(qualified_class_name):
+            idx = qualified_class_name.rfind('.')
+            class_name = qualified_class_name[idx+1:]
+            pkg_name = qualified_class_name[:idx]
+
+            module = __import__(pkg_name)
+
+            return getattr(module, class_name)
+
+        return {
+            k: resolve_class(v)
+            for k, v in self._parse_dict(value).items()
         }
 
     def _parse_packages(self, value):
index c31020f0c4dc85a0b0f54db29436b524dd1237fd..6ae3886b1f914044c8b42031f79dad8f34cf2b4b 100644 (file)
@@ -292,7 +292,7 @@ def check_specifier(dist, attr, value):
     """Verify that value is a valid version specifier"""
     try:
         packaging.specifiers.SpecifierSet(value)
-    except packaging.specifiers.InvalidSpecifier as error:
+    except (packaging.specifiers.InvalidSpecifier, AttributeError) as error:
         tmpl = (
             "{attr!r} must be a string "
             "containing valid version specifiers; {error}"
diff --git a/setuptools/tests/files.py b/setuptools/tests/files.py
deleted file mode 100644 (file)
index 71194b9..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-import os
-
-
-def build_files(file_defs, prefix=""):
-    """
-    Build a set of files/directories, as described by the
-    file_defs dictionary.
-
-    Each key/value pair in the dictionary is interpreted as
-    a filename/contents
-    pair. If the contents value is a dictionary, a directory
-    is created, and the
-    dictionary interpreted as the files within it, recursively.
-
-    For example:
-
-    {"README.txt": "A README file",
-     "foo": {
-        "__init__.py": "",
-        "bar": {
-            "__init__.py": "",
-        },
-        "baz.py": "# Some code",
-     }
-    }
-    """
-    for name, contents in file_defs.items():
-        full_name = os.path.join(prefix, name)
-        if isinstance(contents, dict):
-            os.makedirs(full_name, exist_ok=True)
-            build_files(contents, prefix=full_name)
-        else:
-            if isinstance(contents, bytes):
-                with open(full_name, 'wb') as f:
-                    f.write(contents)
-            else:
-                with open(full_name, 'w') as f:
-                    f.write(contents)
index 838fdb429985a10441852062e3f8a886e6a71ffe..be03893a1bac4dfe223794973a3567b85484e65e 100644 (file)
@@ -2,12 +2,13 @@ import sys
 import distutils.command.build_ext as orig
 from distutils.sysconfig import get_config_var
 
+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 . import environment
-from .files import build_files
 from .textwrap import DALS
 
 
@@ -106,7 +107,7 @@ def test_build_ext_config_handling(tmpdir_cwd):
             build-base = foo_build
             """),
     }
-    build_files(files)
+    path.build(files)
     code, output = environment.run_setup_py(
         cmd=['build'], data_stream=(0, 2),
     )
index e117d8e6295c675e77df8a5c7b82727f6e4b5d8a..f33a69688d1cb352da05d965ba19c3c46eee23bf 100644 (file)
@@ -5,8 +5,8 @@ import importlib
 from concurrent import futures
 
 import pytest
+from jaraco import path
 
-from .files import build_files
 from .textwrap import DALS
 
 
@@ -130,7 +130,7 @@ class TestBuildMetaBackend:
 
     @pytest.fixture(params=defns)
     def build_backend(self, tmpdir, request):
-        build_files(request.param, prefix=str(tmpdir))
+        path.build(request.param, prefix=str(tmpdir))
         with tmpdir.as_cwd():
             yield self.get_build_backend()
 
@@ -170,7 +170,7 @@ class TestBuildMetaBackend:
             """),
         }
 
-        build_files(files)
+        path.build(files)
 
         dist_dir = os.path.abspath('preexisting-' + build_type)
 
@@ -262,7 +262,7 @@ class TestBuildMetaBackend:
                 build-backend = "setuptools.build_meta
                 """),
         }
-        build_files(files)
+        path.build(files)
         build_backend = self.get_build_backend()
         targz_path = build_backend.build_sdist("temp")
         with tarfile.open(os.path.join("temp", targz_path)) as tar:
@@ -271,7 +271,7 @@ class TestBuildMetaBackend:
     def test_build_sdist_setup_py_exists(self, tmpdir_cwd):
         # If build_sdist is called from a script other than setup.py,
         # ensure setup.py is included
-        build_files(defns[0])
+        path.build(defns[0])
 
         build_backend = self.get_build_backend()
         targz_path = build_backend.build_sdist("temp")
@@ -293,7 +293,7 @@ class TestBuildMetaBackend:
         """)
         }
 
-        build_files(files)
+        path.build(files)
 
         build_backend = self.get_build_backend()
         targz_path = build_backend.build_sdist("temp")
@@ -315,7 +315,7 @@ class TestBuildMetaBackend:
                 """)
         }
 
-        build_files(files)
+        path.build(files)
 
         build_backend = self.get_build_backend()
         build_backend.build_sdist("temp")
@@ -335,7 +335,7 @@ class TestBuildMetaBackend:
     }
 
     def test_build_sdist_relative_path_import(self, tmpdir_cwd):
-        build_files(self._relative_path_import_files)
+        path.build(self._relative_path_import_files)
         build_backend = self.get_build_backend()
         with pytest.raises(ImportError, match="^No module named 'hello'$"):
             build_backend.build_sdist("temp")
@@ -374,7 +374,7 @@ class TestBuildMetaBackend:
             """),
         }
 
-        build_files(files)
+        path.build(files)
 
         build_backend = self.get_build_backend()
 
@@ -409,7 +409,7 @@ class TestBuildMetaBackend:
                     """),
         }
 
-        build_files(files)
+        path.build(files)
 
         build_backend = self.get_build_backend()
 
@@ -437,7 +437,7 @@ class TestBuildMetaBackend:
     }
 
     def test_sys_argv_passthrough(self, tmpdir_cwd):
-        build_files(self._sys_argv_0_passthrough)
+        path.build(self._sys_argv_0_passthrough)
         build_backend = self.get_build_backend()
         with pytest.raises(AssertionError):
             build_backend.build_sdist("temp")
@@ -449,13 +449,13 @@ class TestBuildMetaLegacyBackend(TestBuildMetaBackend):
     # build_meta_legacy-specific tests
     def test_build_sdist_relative_path_import(self, tmpdir_cwd):
         # This must fail in build_meta, but must pass in build_meta_legacy
-        build_files(self._relative_path_import_files)
+        path.build(self._relative_path_import_files)
 
         build_backend = self.get_build_backend()
         build_backend.build_sdist("temp")
 
     def test_sys_argv_passthrough(self, tmpdir_cwd):
-        build_files(self._sys_argv_0_passthrough)
+        path.build(self._sys_argv_0_passthrough)
 
         build_backend = self.get_build_backend()
         build_backend.build_sdist("temp")
index 649075609a206454de95b5bbdf5272d43a2f068e..6db86c7c583e75248925936b6ee81ed85bcc3ee8 100644 (file)
@@ -1,3 +1,6 @@
+import types
+import sys
+
 import contextlib
 import configparser
 
@@ -7,6 +10,7 @@ from distutils.errors import DistutilsOptionError, DistutilsFileError
 from mock import patch
 from setuptools.dist import Distribution, _Distribution
 from setuptools.config import ConfigHandler, read_configuration
+from distutils.core import Command
 from .textwrap import DALS
 
 
@@ -871,6 +875,26 @@ class TestOptions:
             with get_dist(tmpdir) as dist:
                 dist.parse_config_files()
 
+    def test_cmdclass(self, tmpdir):
+        class CustomCmd(Command):
+            pass
+
+        m = types.ModuleType('custom_build', 'test package')
+
+        m.__dict__['CustomCmd'] = CustomCmd
+
+        sys.modules['custom_build'] = m
+
+        fake_env(
+            tmpdir,
+            '[options]\n'
+            'cmdclass =\n'
+            '    customcmd = custom_build.CustomCmd\n'
+        )
+
+        with get_dist(tmpdir) as dist:
+            assert dist.cmdclass == {'customcmd': CustomCmd}
+
 
 saved_dist_init = _Distribution.__init__
 
index cb47fb5848b968af046d300ae86577b7f03f5f97..e4bba47bce897b05bcc17cab240aae93786f6978 100644 (file)
@@ -9,6 +9,7 @@ from setuptools.dist import (
     _get_unpatched,
     check_package_data,
     DistDeprecationWarning,
+    check_specifier,
 )
 from setuptools import sic
 from setuptools import Distribution
@@ -323,3 +324,15 @@ def test_check_package_data(package_data, expected_message):
         with pytest.raises(
                 DistutilsSetupError, match=re.escape(expected_message)):
             check_package_data(None, str('package_data'), package_data)
+
+
+def test_check_specifier():
+    # valid specifier value
+    attrs = {'name': 'foo', 'python_requires': '>=3.0, !=3.1'}
+    dist = Distribution(attrs)
+    check_specifier(dist, attrs, attrs['python_requires'])
+
+    # invalid specifier value
+    attrs = {'name': 'foo', 'python_requires': ['>=3.0', '!=3.1']}
+    with pytest.raises(DistutilsSetupError):
+        dist = Distribution(attrs)
index 66598066d74a676744be2c315946d999011d8551..a3b2d6e66ca3a711d77fa6e43501d186c25e434e 100644 (file)
@@ -18,6 +18,7 @@ import re
 import subprocess
 
 import pytest
+from jaraco import path
 
 from setuptools import sandbox
 from setuptools.sandbox import run_setup
@@ -34,7 +35,6 @@ from setuptools.tests import fail_on_ascii
 import pkg_resources
 
 from . import contexts
-from .files import build_files
 from .textwrap import DALS
 
 
@@ -794,7 +794,7 @@ class TestSetupRequires:
                 # Create source tree for `dep`.
                 dep_pkg = os.path.join(temp_dir, 'dep')
                 os.mkdir(dep_pkg)
-                build_files({
+                path.build({
                     'setup.py':
                     DALS("""
                           import setuptools
index 1047468b185a13ad3ad3c9570c6ec783fcd6f293..bf95b03ce66af944d71358ae31f290b38aae80a5 100644 (file)
@@ -6,15 +6,15 @@ import re
 import stat
 import time
 
+import pytest
+from jaraco import path
+
 from setuptools.command.egg_info import (
     egg_info, manifest_maker, EggInfoDeprecationWarning, get_pkg_info_revision,
 )
 from setuptools.dist import Distribution
 
-import pytest
-
 from . import environment
-from .files import build_files
 from .textwrap import DALS
 from . import contexts
 
@@ -37,7 +37,7 @@ class TestEggInfo:
         """)
 
     def _create_project(self):
-        build_files({
+        path.build({
             'setup.py': self.setup_script,
             'hello.py': DALS("""
                 def run():
@@ -56,7 +56,7 @@ class TestEggInfo:
                 for dirname in subs
             )
             list(map(os.mkdir, env.paths.values()))
-            build_files({
+            path.build({
                 env.paths['home']: {
                     '.pydistutils.cfg': DALS("""
                     [egg_info]
@@ -106,7 +106,7 @@ class TestEggInfo:
         the file should remain unchanged.
         """
         setup_cfg = os.path.join(env.paths['home'], 'setup.cfg')
-        build_files({
+        path.build({
             setup_cfg: DALS("""
             [egg_info]
             tag_build =
@@ -159,8 +159,10 @@ class TestEggInfo:
             setup()
             """)
 
-        build_files({'setup.py': setup_script,
-                     'setup.cfg': setup_config})
+        path.build({
+            'setup.py': setup_script,
+            'setup.cfg': setup_config,
+        })
 
         # This command should fail with a ValueError, but because it's
         # currently configured to use a subprocess, the actual traceback
@@ -193,7 +195,7 @@ class TestEggInfo:
 
     def test_manifest_template_is_read(self, tmpdir_cwd, env):
         self._create_project()
-        build_files({
+        path.build({
             'MANIFEST.in': DALS("""
                 recursive-include docs *.rst
             """),
@@ -216,8 +218,10 @@ class TestEggInfo:
             '''
         ) % ('' if use_setup_cfg else requires)
         setup_config = requires if use_setup_cfg else ''
-        build_files({'setup.py': setup_script,
-                     'setup.cfg': setup_config})
+        path.build({
+            'setup.py': setup_script,
+            'setup.cfg': setup_config,
+        })
 
     mismatch_marker = "python_version<'{this_ver}'".format(
         this_ver=sys.version_info[0],
@@ -546,7 +550,7 @@ class TestEggInfo:
     def test_setup_cfg_license_file(
             self, tmpdir_cwd, env, files, license_in_sources):
         self._create_project()
-        build_files(files)
+        path.build(files)
 
         environment.run_setup_py(
             cmd=['egg_info'],
@@ -645,7 +649,7 @@ class TestEggInfo:
     def test_setup_cfg_license_files(
             self, tmpdir_cwd, env, files, incl_licenses, excl_licenses):
         self._create_project()
-        build_files(files)
+        path.build(files)
 
         environment.run_setup_py(
             cmd=['egg_info'],
@@ -750,7 +754,7 @@ class TestEggInfo:
     def test_setup_cfg_license_file_license_files(
             self, tmpdir_cwd, env, files, incl_licenses, excl_licenses):
         self._create_project()
-        build_files(files)
+        path.build(files)
 
         environment.run_setup_py(
             cmd=['egg_info'],
@@ -886,7 +890,7 @@ class TestEggInfo:
 
     def test_egg_info_tag_only_once(self, tmpdir_cwd, env):
         self._create_project()
-        build_files({
+        path.build({
             'setup.cfg': DALS("""
                               [egg_info]
                               tag_build = dev
index a0728c5d12ed8fef40f78d823f3e07ea7281b827..e99587f5688ea41ffa4f4d41e1d880be7d6988b9 100644 (file)
@@ -1,9 +1,8 @@
 import pytest
+from jaraco import path
 
 from setuptools.glob import glob
 
-from .files import build_files
-
 
 @pytest.mark.parametrize('tree, pattern, matches', (
     ('', b'', []),
@@ -31,5 +30,5 @@ from .files import build_files
 ))
 def test_glob(monkeypatch, tmpdir, tree, pattern, matches):
     monkeypatch.chdir(tmpdir)
-    build_files({name: '' for name in tree.split()})
+    path.build({name: '' for name in tree.split()})
     assert list(sorted(glob(pattern))) == list(sorted(matches))
index a48ba7f8b38343e3cd72f91defd28786ca6f20ca..cc5b8293bf48bbc3e71399aae02d26470ae27f83 100644 (file)
@@ -1,5 +1,6 @@
 import pytest
-import os
+
+from jaraco import path
 
 from setuptools.command.upload_docs import upload_docs
 from setuptools.dist import Distribution
@@ -7,21 +8,17 @@ from setuptools.dist import Distribution
 
 @pytest.fixture
 def sphinx_doc_sample_project(tmpdir_cwd):
-    # setup.py
-    with open('setup.py', 'wt') as f:
-        f.write('from setuptools import setup; setup()\n')
-
-    os.makedirs('build/docs')
-
-    # A test conf.py for Sphinx
-    with open('build/docs/conf.py', 'w') as f:
-        f.write("project = 'test'")
-
-    # A test index.rst for Sphinx
-    with open('build/docs/index.rst', 'w') as f:
-        f.write(".. toctree::\
+    path.build({
+        'setup.py': 'from setuptools import setup; setup()',
+        'build': {
+            'docs': {
+                'conf.py': 'project="test"',
+                'index.rst': ".. toctree::\
                     :maxdepth: 2\
-                    :caption: Contents:")
+                    :caption: Contents:",
+            },
+        },
+    })
 
 
 @pytest.mark.usefixtures('sphinx_doc_sample_project')
index a26e32a61d29bfa3d4dca96037dfcfd2fd610d95..55978aadc70e9f255d7a84934c8e66aaba1f13ec 100644 (file)
@@ -3,6 +3,7 @@ import zipfile
 import contextlib
 
 import pytest
+from jaraco import path
 
 from setuptools.command.upload_docs import upload_docs
 from setuptools.dist import Distribution
@@ -10,28 +11,20 @@ from setuptools.dist import Distribution
 from .textwrap import DALS
 from . import contexts
 
-SETUP_PY = DALS(
-    """
-    from setuptools import setup
-
-    setup(name='foo')
-    """)
-
 
 @pytest.fixture
 def sample_project(tmpdir_cwd):
-    # setup.py
-    with open('setup.py', 'wt') as f:
-        f.write(SETUP_PY)
-
-    os.mkdir('build')
-
-    # A test document.
-    with open('build/index.html', 'w') as f:
-        f.write("Hello world.")
-
-    # An empty folder.
-    os.mkdir('build/empty')
+    path.build({
+        'setup.py': DALS("""
+            from setuptools import setup
+
+            setup(name='foo')
+            """),
+        'build': {
+            'index.html': 'Hello world.',
+            'empty': {},
+        }
+    })
 
 
 @pytest.mark.usefixtures('sample_project')
index fcd5da5d45f4331a32afd020386e1ffe1e729405..f13f7997e3df69df83948ee32fd6da8cfd799eac 100644 (file)
@@ -1,6 +1,7 @@
 import glob
 import os
 import sys
+import itertools
 
 import pathlib
 
@@ -65,20 +66,29 @@ def _get_pip_versions():
             # No network, disable most of these tests
             network = False
 
+    def mark(param, *marks):
+        if not isinstance(param, type(pytest.param(''))):
+            param = pytest.param(param)
+        return param._replace(marks=param.marks + marks)
+
+    def skip_network(param):
+        return param if network else mark(param, pytest.mark.skip(reason="no network"))
+
     network_versions = [
         'pip==9.0.3',
         'pip==10.0.1',
         'pip==18.1',
-        'pip==19.0.1',
+        mark('pip==19.3.1', pytest.mark.xfail(reason='pypa/pip#6599')),
+        'pip==20.0.2',
         'https://github.com/pypa/pip/archive/master.zip',
     ]
 
-    versions = [None] + [
-        pytest.param(v, **({} if network else {'marks': pytest.mark.skip}))
-        for v in network_versions
-    ]
+    versions = itertools.chain(
+        [None],
+        map(skip_network, network_versions)
+    )
 
-    return versions
+    return list(versions)
 
 
 @pytest.mark.parametrize('pip_version', _get_pip_versions())
index e56eac14d1c6654471cdbef08b015eddca22675e..7345b135fd17ac1fec00e5886bd0a0d1ce502fdb 100644 (file)
@@ -15,6 +15,7 @@ import sys
 import zipfile
 
 import pytest
+from jaraco import path
 
 from pkg_resources import Distribution, PathMetadata, PY_MAJOR
 from setuptools.extern.packaging.utils import canonicalize_name
@@ -22,7 +23,6 @@ from setuptools.extern.packaging.tags import parse_tag
 from setuptools.wheel import Wheel
 
 from .contexts import tempdir
-from .files import build_files
 from .textwrap import DALS
 
 
@@ -91,7 +91,7 @@ def build_wheel(extra_file_defs=None, **kwargs):
     if extra_file_defs:
         file_defs.update(extra_file_defs)
     with tempdir() as source_dir:
-        build_files(file_defs, source_dir)
+        path.build(file_defs, source_dir)
         subprocess.check_call((sys.executable, 'setup.py',
                                '-q', 'bdist_wheel'), cwd=source_dir)
         yield glob.glob(os.path.join(source_dir, 'dist', '*.whl'))[0]