diff options
Diffstat (limited to 'setuptools/tests')
22 files changed, 626 insertions, 206 deletions
diff --git a/setuptools/tests/environment.py b/setuptools/tests/environment.py index bd3119ef..c0274c33 100644 --- a/setuptools/tests/environment.py +++ b/setuptools/tests/environment.py @@ -29,7 +29,7 @@ def run_setup_py(cmd, pypath=None, path=None, if pypath is not None: env["PYTHONPATH"] = pypath - # overide the execution path if needed + # override the execution path if needed if path is not None: env["PATH"] = path if not env.get("PATH", ""): diff --git a/setuptools/tests/files.py b/setuptools/tests/files.py deleted file mode 100644 index 71194b9d..00000000 --- a/setuptools/tests/files.py +++ /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) diff --git a/setuptools/tests/fixtures.py b/setuptools/tests/fixtures.py index e8cb7f52..a5a172e0 100644 --- a/setuptools/tests/fixtures.py +++ b/setuptools/tests/fixtures.py @@ -1,3 +1,8 @@ +import contextlib +import sys +import shutil +import subprocess + import pytest from . import contexts @@ -21,3 +26,49 @@ def user_override(monkeypatch): def tmpdir_cwd(tmpdir): with tmpdir.as_cwd() as orig: yield orig + + +@pytest.fixture +def tmp_src(request, tmp_path): + """Make a copy of the source dir under `$tmp/src`. + + This fixture is useful whenever it's necessary to run `setup.py` + or `pip install` against the source directory when there's no + control over the number of simultaneous invocations. Such + concurrent runs create and delete directories with the same names + under the target directory and so they influence each other's runs + when they are not being executed sequentially. + """ + tmp_src_path = tmp_path / 'src' + shutil.copytree(request.config.rootdir, tmp_src_path) + return tmp_src_path + + +@pytest.fixture(autouse=True, scope="session") +def workaround_xdist_376(request): + """ + Workaround pytest-dev/pytest-xdist#376 + + ``pytest-xdist`` tends to inject '' into ``sys.path``, + which may break certain isolation expectations. + Remove the entry so the import + machinery behaves the same irrespective of xdist. + """ + if not request.config.pluginmanager.has_plugin('xdist'): + return + + with contextlib.suppress(ValueError): + sys.path.remove('') + + +@pytest.fixture +def sample_project(tmp_path): + """ + Clone the 'sampleproject' and return a path to it. + """ + cmd = ['git', 'clone', 'https://github.com/pypa/sampleproject'] + try: + subprocess.check_call(cmd, cwd=str(tmp_path)) + except Exception: + pytest.skip("Unable to clone sampleproject") + return tmp_path / 'sampleproject' diff --git a/setuptools/tests/requirements.txt b/setuptools/tests/requirements.txt index d0d07f70..b2d84a94 100644 --- a/setuptools/tests/requirements.txt +++ b/setuptools/tests/requirements.txt @@ -11,3 +11,4 @@ paver; python_version>="3.6" futures; python_version=="2.7" pip>=19.1 # For proper file:// URLs support. jaraco.envs +sphinx diff --git a/setuptools/tests/server.py b/setuptools/tests/server.py index 7e213230..6717c053 100644 --- a/setuptools/tests/server.py +++ b/setuptools/tests/server.py @@ -65,7 +65,7 @@ class MockServer(http.server.HTTPServer, threading.Thread): http.server.HTTPServer.__init__( self, server_address, RequestHandlerClass) threading.Thread.__init__(self) - self.setDaemon(True) + self.daemon = True self.requests = [] def run(self): diff --git a/setuptools/tests/test_bdist_deprecations.py b/setuptools/tests/test_bdist_deprecations.py deleted file mode 100644 index 704164aa..00000000 --- a/setuptools/tests/test_bdist_deprecations.py +++ /dev/null @@ -1,23 +0,0 @@ -"""develop tests -""" -import mock - -import pytest - -from setuptools.dist import Distribution -from setuptools import SetuptoolsDeprecationWarning - - -@mock.patch("distutils.command.bdist_wininst.bdist_wininst") -def test_bdist_wininst_warning(distutils_cmd): - dist = Distribution(dict( - script_name='setup.py', - script_args=['bdist_wininst'], - name='foo', - py_modules=['hi'], - )) - dist.parse_command_line() - with pytest.warns(SetuptoolsDeprecationWarning): - dist.run_commands() - - distutils_cmd.run.assert_called_once() diff --git a/setuptools/tests/test_bdist_egg.py b/setuptools/tests/test_bdist_egg.py index 8760ea30..fb5b90b1 100644 --- a/setuptools/tests/test_bdist_egg.py +++ b/setuptools/tests/test_bdist_egg.py @@ -7,7 +7,6 @@ import zipfile import pytest from setuptools.dist import Distribution -from setuptools import SetuptoolsDeprecationWarning from . import contexts @@ -65,17 +64,3 @@ class Test: names = list(zi.filename for zi in zip.filelist) assert 'hi.pyc' in names assert 'hi.py' not in names - - def test_eggsecutable_warning(self, setup_context, user_override): - dist = Distribution(dict( - script_name='setup.py', - script_args=['bdist_egg'], - name='foo', - py_modules=['hi'], - entry_points={ - 'setuptools.installation': - ['eggsecutable = my_package.some_module:main_func']}, - )) - dist.parse_command_line() - with pytest.warns(SetuptoolsDeprecationWarning): - dist.run_commands() diff --git a/setuptools/tests/test_build_ext.py b/setuptools/tests/test_build_ext.py index 838fdb42..b6deebe4 100644 --- a/setuptools/tests/test_build_ext.py +++ b/setuptools/tests/test_build_ext.py @@ -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 @@ -103,10 +104,10 @@ def test_build_ext_config_handling(tmpdir_cwd): 'setup.cfg': DALS( """ [build] - build-base = foo_build + build_base = foo_build """), } - build_files(files) + path.build(files) code, output = environment.run_setup_py( cmd=['build'], data_stream=(0, 2), ) diff --git a/setuptools/tests/test_build_meta.py b/setuptools/tests/test_build_meta.py index 6d3a997e..ab75a189 100644 --- a/setuptools/tests/test_build_meta.py +++ b/setuptools/tests/test_build_meta.py @@ -3,15 +3,16 @@ import shutil import tarfile import importlib from concurrent import futures +import re import pytest +from jaraco import path -from .files import build_files from .textwrap import DALS class BuildBackendBase: - def __init__(self, cwd=None, env={}, backend_name='setuptools.build_meta'): + def __init__(self, cwd='.', env={}, backend_name='setuptools.build_meta'): self.cwd = cwd self.env = env self.backend_name = backend_name @@ -126,11 +127,11 @@ class TestBuildMetaBackend: backend_name = 'setuptools.build_meta' def get_build_backend(self): - return BuildBackend(cwd='.', backend_name=self.backend_name) + return BuildBackend(backend_name=self.backend_name) @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 +171,7 @@ class TestBuildMetaBackend: """), } - build_files(files) + path.build(files) dist_dir = os.path.abspath('preexisting-' + build_type) @@ -262,7 +263,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 +272,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 +294,7 @@ class TestBuildMetaBackend: """) } - build_files(files) + path.build(files) build_backend = self.get_build_backend() targz_path = build_backend.build_sdist("temp") @@ -315,7 +316,7 @@ class TestBuildMetaBackend: """) } - build_files(files) + path.build(files) build_backend = self.get_build_backend() build_backend.build_sdist("temp") @@ -335,9 +336,9 @@ 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): + with pytest.raises(ImportError, match="^No module named 'hello'$"): build_backend.build_sdist("temp") @pytest.mark.parametrize('setup_literal, requirements', [ @@ -374,7 +375,7 @@ class TestBuildMetaBackend: """), } - build_files(files) + path.build(files) build_backend = self.get_build_backend() @@ -409,7 +410,7 @@ class TestBuildMetaBackend: """), } - build_files(files) + path.build(files) build_backend = self.get_build_backend() @@ -437,11 +438,21 @@ 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") + @pytest.mark.parametrize('build_hook', ('build_sdist', 'build_wheel')) + def test_build_with_empty_setuppy(self, build_backend, build_hook): + files = {'setup.py': ''} + path.build(files) + + with pytest.raises( + ValueError, + match=re.escape('No distribution was found.')): + getattr(build_backend, build_hook)("temp") + class TestBuildMetaLegacyBackend(TestBuildMetaBackend): backend_name = 'setuptools.build_meta:__legacy__' @@ -449,13 +460,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") diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py index 1dee1271..21f1becd 100644 --- a/setuptools/tests/test_config.py +++ b/setuptools/tests/test_config.py @@ -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 @@ -206,8 +210,8 @@ class TestMetadata: fake_env( tmpdir, '[metadata]\n' - 'author-email = test@test.com\n' - 'home-page = http://test.test.com/test/\n' + 'author_email = test@test.com\n' + 'home_page = http://test.test.com/test/\n' 'summary = Short summary\n' 'platform = a, b\n' 'classifier =\n' @@ -503,6 +507,44 @@ class TestMetadata: with get_dist(tmpdir): pass + def test_warn_dash_deprecation(self, tmpdir): + # warn_dash_deprecation() is a method in setuptools.dist + # remove this test and the method when no longer needed + fake_env( + tmpdir, + '[metadata]\n' + 'author-email = test@test.com\n' + 'maintainer_email = foo@foo.com\n' + ) + msg = ("Usage of dash-separated 'author-email' will not be supported " + "in future versions. " + "Please use the underscore name 'author_email' instead") + with pytest.warns(UserWarning, match=msg): + with get_dist(tmpdir) as dist: + metadata = dist.metadata + + assert metadata.author_email == 'test@test.com' + assert metadata.maintainer_email == 'foo@foo.com' + + def test_make_option_lowercase(self, tmpdir): + # remove this test and the method make_option_lowercase() in setuptools.dist + # when no longer needed + fake_env( + tmpdir, + '[metadata]\n' + 'Name = foo\n' + 'description = Some description\n' + ) + msg = ("Usage of uppercase key 'Name' in 'metadata' will be deprecated in " + "future versions. " + "Please use lowercase 'name' instead") + with pytest.warns(UserWarning, match=msg): + with get_dist(tmpdir) as dist: + metadata = dist.metadata + + assert metadata.name == 'foo' + assert metadata.description == 'Some description' + class TestOptions: @@ -768,6 +810,20 @@ class TestOptions: } assert dist.metadata.provides_extras == set(['pdf', 'rest']) + def test_dash_preserved_extras_require(self, tmpdir): + fake_env( + tmpdir, + '[options.extras_require]\n' + 'foo-a = foo\n' + 'foo_b = test\n' + ) + + with get_dist(tmpdir) as dist: + assert dist.extras_require == { + 'foo-a': ['foo'], + 'foo_b': ['test'] + } + def test_entry_points(self, tmpdir): _, config = fake_env( tmpdir, @@ -802,6 +858,24 @@ class TestOptions: with get_dist(tmpdir) as dist: assert dist.entry_points == expected + def test_case_sensitive_entry_points(self, tmpdir): + _, config = fake_env( + tmpdir, + '[options.entry_points]\n' + 'GROUP1 = point1 = pack.module:func, ' + '.point2 = pack.module2:func_rest [rest]\n' + 'group2 = point3 = pack.module:func2\n' + ) + + with get_dist(tmpdir) as dist: + assert dist.entry_points == { + 'GROUP1': [ + 'point1 = pack.module:func', + '.point2 = pack.module2:func_rest [rest]', + ], + 'group2': ['point3 = pack.module:func2'] + } + def test_data_files(self, tmpdir): fake_env( tmpdir, @@ -853,6 +927,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__ diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index 2766da2f..df8db4e2 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -7,6 +7,8 @@ import sys import io import subprocess import platform +import pathlib +import textwrap from setuptools.command import test @@ -199,3 +201,55 @@ class TestNamespaces: ] with test.test.paths_on_pythonpath([str(target)]): subprocess.check_call(pkg_resources_imp) + + @staticmethod + def install_workaround(site_packages): + site_packages.mkdir(parents=True) + sc = site_packages / 'sitecustomize.py' + sc.write_text(textwrap.dedent(""" + import site + import pathlib + here = pathlib.Path(__file__).parent + site.addsitedir(str(here)) + """).lstrip()) + + @pytest.mark.xfail( + platform.python_implementation() == 'PyPy', + reason="Workaround fails on PyPy (why?)", + ) + def test_editable_prefix(self, tmp_path, sample_project): + """ + Editable install to a prefix should be discoverable. + """ + prefix = tmp_path / 'prefix' + prefix.mkdir() + + # figure out where pip will likely install the package + site_packages = prefix / next( + pathlib.Path(path).relative_to(sys.prefix) + for path in sys.path + if 'site-packages' in path + and path.startswith(sys.prefix) + ) + + # install the workaround + self.install_workaround(site_packages) + + env = dict(os.environ, PYTHONPATH=str(site_packages)) + cmd = [ + sys.executable, + '-m', 'pip', + 'install', + '--editable', + str(sample_project), + '--prefix', str(prefix), + '--no-build-isolation', + ] + subprocess.check_call(cmd, env=env) + + # now run 'sample' with the prefix on the PYTHONPATH + bin = 'Scripts' if platform.system() == 'Windows' else 'bin' + exe = prefix / bin / 'sample' + if sys.version_info < (3, 7) and platform.system() == 'Windows': + exe = str(exe) + subprocess.check_call([exe], env=env) diff --git a/setuptools/tests/test_dist.py b/setuptools/tests/test_dist.py index cb47fb58..c4279f0b 100644 --- a/setuptools/tests/test_dist.py +++ b/setuptools/tests/test_dist.py @@ -9,6 +9,9 @@ from setuptools.dist import ( _get_unpatched, check_package_data, DistDeprecationWarning, + check_specifier, + rfc822_escape, + rfc822_unescape, ) from setuptools import sic from setuptools import Distribution @@ -81,11 +84,8 @@ def __read_test_cases(): test_cases = [ ('Metadata version 1.0', params()), - ('Metadata version 1.1: Provides', params( - provides=['package'], - )), - ('Metadata version 1.1: Obsoletes', params( - obsoletes=['foo'], + ('Metadata Version 1.0: Short long description', params( + long_description='Short long description', )), ('Metadata version 1.1: Classifiers', params( classifiers=[ @@ -110,6 +110,10 @@ def __read_test_cases(): ('Metadata Version 2.1: Long Description Content Type', params( long_description_content_type='text/x-rst; charset=UTF-8', )), + ('License', params(license='MIT', )), + ('License multiline', params( + license='This is a long license \nover multiple lines', + )), pytest.param( 'Metadata Version 2.1: Provides Extra', params(provides_extras=['foo', 'bar']), @@ -161,6 +165,7 @@ def test_read_metadata(name, attrs): ('metadata_version', dist_class.get_metadata_version), ('provides', dist_class.get_provides), ('description', dist_class.get_description), + ('long_description', dist_class.get_long_description), ('download_url', dist_class.get_download_url), ('keywords', dist_class.get_keywords), ('platforms', dist_class.get_platforms), @@ -246,8 +251,8 @@ def test_maintainer_author(name, attrs, tmpdir): with io.open(str(fn.join('PKG-INFO')), 'r', encoding='utf-8') as f: raw_pkg_lines = f.readlines() - # Drop blank lines - pkg_lines = list(filter(None, raw_pkg_lines)) + # Drop blank lines and strip lines from default description + pkg_lines = list(filter(None, raw_pkg_lines[:-2])) pkg_lines_set = set(pkg_lines) @@ -323,3 +328,49 @@ 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) + + +@pytest.mark.parametrize( + 'content, result', + ( + pytest.param( + "Just a single line", + None, + id="single_line", + ), + pytest.param( + "Multiline\nText\nwithout\nextra indents\n", + None, + id="multiline", + ), + pytest.param( + "Multiline\n With\n\nadditional\n indentation", + None, + id="multiline_with_indentation", + ), + pytest.param( + " Leading whitespace", + "Leading whitespace", + id="remove_leading_whitespace", + ), + pytest.param( + " Leading whitespace\nIn\n Multiline comment", + "Leading whitespace\nIn\n Multiline comment", + id="remove_leading_whitespace_multiline", + ), + ) +) +def test_rfc822_unescape(content, result): + assert (result or content) == rfc822_unescape(rfc822_escape(content)) diff --git a/setuptools/tests/test_distutils_adoption.py b/setuptools/tests/test_distutils_adoption.py index a53773df..0e89921c 100644 --- a/setuptools/tests/test_distutils_adoption.py +++ b/setuptools/tests/test_distutils_adoption.py @@ -21,10 +21,10 @@ class VirtualEnv(jaraco.envs.VirtualEnv): @pytest.fixture -def venv(tmpdir): +def venv(tmp_path, tmp_src): env = VirtualEnv() - env.root = path.Path(tmpdir) - env.req = os.getcwd() + env.root = path.Path(tmp_path / 'venv') + env.req = str(tmp_src) return env.create() diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index dc00e697..4b2bb2b3 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -15,8 +15,10 @@ import zipfile import mock import time import re +import subprocess import pytest +from jaraco import path from setuptools import sandbox from setuptools.sandbox import run_setup @@ -25,7 +27,6 @@ from setuptools.command.easy_install import ( EasyInstallDeprecationWarning, ScriptWriter, PthDistributions, WindowsScriptWriter, ) -from setuptools.command import easy_install as easy_install_pkg from setuptools.dist import Distribution from pkg_resources import normalize_path, working_set from pkg_resources import Distribution as PRDistribution @@ -34,10 +35,19 @@ from setuptools.tests import fail_on_ascii import pkg_resources from . import contexts -from .files import build_files from .textwrap import DALS +@pytest.fixture(autouse=True) +def pip_disable_index(monkeypatch): + """ + Important: Disable the default index for pip to avoid + querying packages in the index and potentially resolving + and installing packages there. + """ + monkeypatch.setenv('PIP_NO_INDEX', 'true') + + class FakeDist: def get_entry_map(self, group): if group != 'console_scripts': @@ -445,22 +455,22 @@ class TestSetupRequires: """ monkeypatch.setenv(str('PIP_RETRIES'), str('0')) monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) + monkeypatch.setenv('PIP_NO_INDEX', 'false') with contexts.quiet(): # create an sdist that has a build-time dependency. with TestSetupRequires.create_sdist() as dist_file: with contexts.tempdir() as temp_install_dir: with contexts.environment(PYTHONPATH=temp_install_dir): - ei_params = [ + cmd = [ + sys.executable, + '-m', 'setup', + 'easy_install', '--index-url', mock_index.url, '--exclude-scripts', '--install-dir', temp_install_dir, dist_file, ] - with sandbox.save_argv(['easy_install']): - # attempt to install the dist. It should - # fail because it doesn't exist. - with pytest.raises(SystemExit): - easy_install_pkg.main(ei_params) + subprocess.Popen(cmd).wait() # there should have been one requests to the server assert [r.path for r in mock_index.requests] == ['/does-not-exist/'] @@ -618,6 +628,7 @@ class TestSetupRequires: def test_setup_requires_honors_pip_env(self, mock_index, monkeypatch): monkeypatch.setenv(str('PIP_RETRIES'), str('0')) monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) + monkeypatch.setenv('PIP_NO_INDEX', 'false') monkeypatch.setenv(str('PIP_INDEX_URL'), mock_index.url) with contexts.save_pkg_resources_state(): with contexts.tempdir() as temp_dir: @@ -648,7 +659,7 @@ class TestSetupRequires: dep_url = path_to_url(dep_sdist, authority='localhost') test_pkg = create_setup_requires_package( temp_dir, - # Ignored (overriden by setup_attrs) + # Ignored (overridden by setup_attrs) 'python-xlib', '0.19', setup_attrs=dict( setup_requires='dependency @ %s' % dep_url)) @@ -720,7 +731,7 @@ class TestSetupRequires: with contexts.save_pkg_resources_state(): test_pkg = create_setup_requires_package( str(tmpdir), - 'python-xlib', '0.19', # Ignored (overriden by setup_attrs). + 'python-xlib', '0.19', # Ignored (overridden by setup_attrs). setup_attrs=dict( setup_requires='dep', dependency_links=[index_url])) test_setup_py = os.path.join(test_pkg, 'setup.py') @@ -730,10 +741,10 @@ class TestSetupRequires: assert eggs == ['dep 1.0'] @pytest.mark.parametrize( - 'use_legacy_installer,with_dependency_links_in_setup_py', - itertools.product((False, True), (False, True))) + 'with_dependency_links_in_setup_py', + (False, True)) def test_setup_requires_with_find_links_in_setup_cfg( - self, monkeypatch, use_legacy_installer, + self, monkeypatch, with_dependency_links_in_setup_py): monkeypatch.setenv(str('PIP_RETRIES'), str('0')) monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) @@ -755,11 +766,9 @@ class TestSetupRequires: fp.write(DALS( ''' from setuptools import installer, setup - if {use_legacy_installer}: - installer.fetch_build_egg = installer._legacy_fetch_build_egg setup(setup_requires='python-xlib==42', dependency_links={dependency_links!r}) - ''').format(use_legacy_installer=use_legacy_installer, # noqa + ''').format( dependency_links=dependency_links)) with open(test_setup_cfg, 'w') as fp: fp.write(DALS( @@ -785,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 diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index 1047468b..ee07b5a1 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -5,16 +5,17 @@ import glob import re import stat import time +from typing import List, Tuple + +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 +38,7 @@ class TestEggInfo: """) def _create_project(self): - build_files({ + path.build({ 'setup.py': self.setup_script, 'hello.py': DALS(""" def run(): @@ -45,6 +46,11 @@ class TestEggInfo: """) }) + @staticmethod + def _extract_mv_version(pkg_info_lines: List[str]) -> Tuple[int, int]: + version_str = pkg_info_lines[0].split(' ')[1] + return tuple(map(int, version_str.split('.')[:2])) + @pytest.fixture def env(self): with contexts.tempdir(prefix='setuptools-test.') as env_dir: @@ -56,7 +62,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 +112,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 +165,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 +201,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 +224,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], @@ -533,7 +543,7 @@ class TestEggInfo: 'setup.cfg': DALS(""" """), 'LICENSE': "Test license" - }, False), # no license_file attribute + }, True), # no license_file attribute, LICENSE auto-included ({ 'setup.cfg': DALS(""" [metadata] @@ -541,12 +551,20 @@ class TestEggInfo: """), 'MANIFEST.in': "exclude LICENSE", 'LICENSE': "Test license" - }, False) # license file is manually excluded + }, True), # manifest is overwritten by license_file + pytest.param({ + 'setup.cfg': DALS(""" + [metadata] + license_file = LICEN[CS]E* + """), + 'LICENSE': "Test license", + }, True, + id="glob_pattern"), ]) 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'], @@ -621,7 +639,7 @@ class TestEggInfo: 'setup.cfg': DALS(""" """), 'LICENSE': "Test license" - }, [], ['LICENSE']), # no license_files attribute + }, ['LICENSE'], []), # no license_files attribute, LICENSE auto-included ({ 'setup.cfg': DALS(""" [metadata] @@ -629,7 +647,7 @@ class TestEggInfo: """), 'MANIFEST.in': "exclude LICENSE", 'LICENSE': "Test license" - }, [], ['LICENSE']), # license file is manually excluded + }, ['LICENSE'], []), # manifest is overwritten by license_files ({ 'setup.cfg': DALS(""" [metadata] @@ -640,12 +658,53 @@ class TestEggInfo: 'MANIFEST.in': "exclude LICENSE-XYZ", 'LICENSE-ABC': "ABC license", 'LICENSE-XYZ': "XYZ license" - }, ['LICENSE-ABC'], ['LICENSE-XYZ']) # subset is manually excluded + # manifest is overwritten by license_files + }, ['LICENSE-ABC', 'LICENSE-XYZ'], []), + pytest.param({ + 'setup.cfg': "", + 'LICENSE-ABC': "ABC license", + 'COPYING-ABC': "ABC copying", + 'NOTICE-ABC': "ABC notice", + 'AUTHORS-ABC': "ABC authors", + 'LICENCE-XYZ': "XYZ license", + 'LICENSE': "License", + 'INVALID-LICENSE': "Invalid license", + }, [ + 'LICENSE-ABC', + 'COPYING-ABC', + 'NOTICE-ABC', + 'AUTHORS-ABC', + 'LICENCE-XYZ', + 'LICENSE', + ], ['INVALID-LICENSE'], + # ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*') + id="default_glob_patterns"), + pytest.param({ + 'setup.cfg': DALS(""" + [metadata] + license_files = + LICENSE* + """), + 'LICENSE-ABC': "ABC license", + 'NOTICE-XYZ': "XYZ notice", + }, ['LICENSE-ABC'], ['NOTICE-XYZ'], + id="no_default_glob_patterns"), + pytest.param({ + 'setup.cfg': DALS(""" + [metadata] + license_files = + LICENSE-ABC + LICENSE* + """), + 'LICENSE-ABC': "ABC license", + }, ['LICENSE-ABC'], [], + id="files_only_added_once", + ), ]) 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'], @@ -744,13 +803,34 @@ class TestEggInfo: 'LICENSE-ABC': "ABC license", 'LICENSE-PQR': "PQR license", 'LICENSE-XYZ': "XYZ license" - # manually excluded - }, ['LICENSE-XYZ'], ['LICENSE-ABC', 'LICENSE-PQR']) + # manifest is overwritten + }, ['LICENSE-ABC', 'LICENSE-PQR', 'LICENSE-XYZ'], []), + pytest.param({ + 'setup.cfg': DALS(""" + [metadata] + license_file = LICENSE* + """), + 'LICENSE-ABC': "ABC license", + 'NOTICE-XYZ': "XYZ notice", + }, ['LICENSE-ABC'], ['NOTICE-XYZ'], + id="no_default_glob_patterns"), + pytest.param({ + 'setup.cfg': DALS(""" + [metadata] + license_file = LICENSE* + license_files = + NOTICE* + """), + 'LICENSE-ABC': "ABC license", + 'NOTICE-ABC': "ABC notice", + 'AUTHORS-ABC': "ABC authors", + }, ['LICENSE-ABC', 'NOTICE-ABC'], ['AUTHORS-ABC'], + id="combined_glob_patterrns"), ]) 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'], @@ -767,6 +847,52 @@ class TestEggInfo: for lf in excl_licenses: assert sources_lines.count(lf) == 0 + def test_license_file_attr_pkg_info(self, tmpdir_cwd, env): + """All matched license files should have a corresponding License-File.""" + self._create_project() + path.build({ + "setup.cfg": DALS(""" + [metadata] + license_files = + NOTICE* + LICENSE* + """), + "LICENSE-ABC": "ABC license", + "LICENSE-XYZ": "XYZ license", + "NOTICE": "included", + "IGNORE": "not include", + }) + + environment.run_setup_py( + cmd=['egg_info'], + pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]) + ) + egg_info_dir = os.path.join('.', 'foo.egg-info') + with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: + pkg_info_lines = pkginfo_file.read().split('\n') + license_file_lines = [ + line for line in pkg_info_lines if line.startswith('License-File:')] + + # Only 'NOTICE', LICENSE-ABC', and 'LICENSE-XYZ' should have been matched + # Also assert that order from license_files is keeped + assert "License-File: NOTICE" == license_file_lines[0] + assert "License-File: LICENSE-ABC" in license_file_lines[1:] + assert "License-File: LICENSE-XYZ" in license_file_lines[1:] + + def test_metadata_version(self, tmpdir_cwd, env): + """Make sure latest metadata version is used by default.""" + self._setup_script_with_requires("") + code, data = environment.run_setup_py( + cmd=['egg_info'], + pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]), + data_stream=1, + ) + egg_info_dir = os.path.join('.', 'foo.egg-info') + with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: + pkg_info_lines = pkginfo_file.read().split('\n') + # Update metadata version if changed + assert self._extract_mv_version(pkg_info_lines) == (2, 1) + def test_long_description_content_type(self, tmpdir_cwd, env): # Test that specifying a `long_description_content_type` keyword arg to # the `setup` function results in writing a `Description-Content-Type` @@ -793,6 +919,29 @@ class TestEggInfo: assert expected_line in pkg_info_lines assert 'Metadata-Version: 2.1' in pkg_info_lines + def test_long_description(self, tmpdir_cwd, env): + # Test that specifying `long_description` and `long_description_content_type` + # keyword args to the `setup` function results in writing + # the description in the message payload of the `PKG-INFO` file + # in the `<distribution>.egg-info` directory. + self._setup_script_with_requires( + "long_description='This is a long description\\nover multiple lines'," + "long_description_content_type='text/markdown'," + ) + code, data = environment.run_setup_py( + cmd=['egg_info'], + pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]), + data_stream=1, + ) + egg_info_dir = os.path.join('.', 'foo.egg-info') + with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: + pkg_info_lines = pkginfo_file.read().split('\n') + assert 'Metadata-Version: 2.1' in pkg_info_lines + assert '' == pkg_info_lines[-1] # last line should be empty + long_desc_lines = pkg_info_lines[pkg_info_lines.index(''):] + assert 'This is a long description' in long_desc_lines + assert 'over multiple lines' in long_desc_lines + def test_project_urls(self, tmpdir_cwd, env): # Test that specifying a `project_urls` dict to the `setup` # function results in writing multiple `Project-URL` lines to @@ -822,7 +971,40 @@ class TestEggInfo: assert expected_line in pkg_info_lines expected_line = 'Project-URL: Link Two, https://example.com/two/' assert expected_line in pkg_info_lines - assert 'Metadata-Version: 1.2' in pkg_info_lines + assert self._extract_mv_version(pkg_info_lines) >= (1, 2) + + def test_license(self, tmpdir_cwd, env): + """Test single line license.""" + self._setup_script_with_requires( + "license='MIT'," + ) + code, data = environment.run_setup_py( + cmd=['egg_info'], + pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]), + data_stream=1, + ) + egg_info_dir = os.path.join('.', 'foo.egg-info') + with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: + pkg_info_lines = pkginfo_file.read().split('\n') + assert 'License: MIT' in pkg_info_lines + + def test_license_escape(self, tmpdir_cwd, env): + """Test license is escaped correctly if longer than one line.""" + self._setup_script_with_requires( + "license='This is a long license text \\nover multiple lines'," + ) + code, data = environment.run_setup_py( + cmd=['egg_info'], + pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]), + data_stream=1, + ) + egg_info_dir = os.path.join('.', 'foo.egg-info') + with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: + pkg_info_lines = pkginfo_file.read().split('\n') + + assert 'License: This is a long license text ' in pkg_info_lines + assert ' over multiple lines' in pkg_info_lines + assert 'text \n over multiple' in '\n'.join(pkg_info_lines) def test_python_requires_egg_info(self, tmpdir_cwd, env): self._setup_script_with_requires( @@ -840,7 +1022,7 @@ class TestEggInfo: with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: pkg_info_lines = pkginfo_file.read().split('\n') assert 'Requires-Python: >=2.7.12' in pkg_info_lines - assert 'Metadata-Version: 1.2' in pkg_info_lines + assert self._extract_mv_version(pkg_info_lines) >= (1, 2) def test_manifest_maker_warning_suppression(self): fixtures = [ @@ -886,7 +1068,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 diff --git a/setuptools/tests/test_glob.py b/setuptools/tests/test_glob.py index a0728c5d..e99587f5 100644 --- a/setuptools/tests/test_glob.py +++ b/setuptools/tests/test_glob.py @@ -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)) diff --git a/setuptools/tests/test_namespaces.py b/setuptools/tests/test_namespaces.py index 6c8c522d..270f90c9 100644 --- a/setuptools/tests/test_namespaces.py +++ b/setuptools/tests/test_namespaces.py @@ -62,8 +62,9 @@ class TestNamespaces: target.mkdir() install_cmd = [ sys.executable, - '-m', 'easy_install', - '-d', str(target), + '-m', 'pip', + 'install', + '-t', str(target), str(pkg), ] with test.test.paths_on_pythonpath([str(target)]): diff --git a/setuptools/tests/test_sphinx_upload_docs.py b/setuptools/tests/test_sphinx_upload_docs.py new file mode 100644 index 00000000..cc5b8293 --- /dev/null +++ b/setuptools/tests/test_sphinx_upload_docs.py @@ -0,0 +1,38 @@ +import pytest + +from jaraco import path + +from setuptools.command.upload_docs import upload_docs +from setuptools.dist import Distribution + + +@pytest.fixture +def sphinx_doc_sample_project(tmpdir_cwd): + path.build({ + 'setup.py': 'from setuptools import setup; setup()', + 'build': { + 'docs': { + 'conf.py': 'project="test"', + 'index.rst': ".. toctree::\ + :maxdepth: 2\ + :caption: Contents:", + }, + }, + }) + + +@pytest.mark.usefixtures('sphinx_doc_sample_project') +class TestSphinxUploadDocs: + def test_sphinx_doc(self): + params = dict( + name='foo', + packages=['test'], + ) + dist = Distribution(params) + + cmd = upload_docs(dist) + + cmd.initialize_options() + assert cmd.upload_dir is None + assert cmd.has_sphinx() is True + cmd.finalize_options() diff --git a/setuptools/tests/test_upload_docs.py b/setuptools/tests/test_upload_docs.py index a26e32a6..55978aad 100644 --- a/setuptools/tests/test_upload_docs.py +++ b/setuptools/tests/test_upload_docs.py @@ -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') diff --git a/setuptools/tests/test_virtualenv.py b/setuptools/tests/test_virtualenv.py index 21dea5bb..399dbaf0 100644 --- a/setuptools/tests/test_virtualenv.py +++ b/setuptools/tests/test_virtualenv.py @@ -1,6 +1,7 @@ import glob import os import sys +import itertools import pathlib @@ -40,14 +41,11 @@ def bare_virtualenv(): yield venv -SOURCE_DIR = os.path.join(os.path.dirname(__file__), '../..') - - -def test_clean_env_install(bare_virtualenv): +def test_clean_env_install(bare_virtualenv, tmp_src): """ Check setuptools can be installed in a clean environment. """ - bare_virtualenv.run(['python', 'setup.py', 'install'], cd=SOURCE_DIR) + bare_virtualenv.run(['python', 'setup.py', 'install'], cd=tmp_src) def _get_pip_versions(): @@ -68,24 +66,38 @@ 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")) + + issue2599 = pytest.mark.skipif( + sys.version_info > (3, 10), + reason="pypa/setuptools#2599", + ) + network_versions = [ - 'pip==9.0.3', - 'pip==10.0.1', - 'pip==18.1', - 'pip==19.0.1', - 'https://github.com/pypa/pip/archive/master.zip', + mark('pip==9.0.3', issue2599), + mark('pip==10.0.1', issue2599), + mark('pip==18.1', issue2599), + mark('pip==19.3.1', pytest.mark.xfail(reason='pypa/pip#6599')), + 'pip==20.0.2', + 'https://github.com/pypa/pip/archive/main.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()) -def test_pip_upgrade_from_source(pip_version, virtualenv): +def test_pip_upgrade_from_source(pip_version, tmp_src, virtualenv): """ Check pip can upgrade setuptools from source. """ @@ -104,7 +116,7 @@ def test_pip_upgrade_from_source(pip_version, virtualenv): virtualenv.run(' && '.join(( 'python setup.py -q sdist -d {dist}', 'python setup.py -q bdist_wheel -d {dist}', - )).format(dist=dist_dir), cd=SOURCE_DIR) + )).format(dist=dist_dir), cd=tmp_src) sdist = glob.glob(os.path.join(dist_dir, '*.zip'))[0] wheel = glob.glob(os.path.join(dist_dir, '*.whl'))[0] # Then update from wheel. @@ -113,12 +125,12 @@ def test_pip_upgrade_from_source(pip_version, virtualenv): virtualenv.run('pip install --no-cache-dir --upgrade ' + sdist) -def _check_test_command_install_requirements(virtualenv, tmpdir): +def _check_test_command_install_requirements(virtualenv, tmpdir, cwd): """ Check the test command will install all required dependencies. """ # Install setuptools. - virtualenv.run('python setup.py develop', cd=SOURCE_DIR) + virtualenv.run('python setup.py develop', cd=cwd) def sdist(distname, version): dist_path = tmpdir.join('%s-%s.tar.gz' % (distname, version)) @@ -175,22 +187,21 @@ def _check_test_command_install_requirements(virtualenv, tmpdir): assert tmpdir.join('success').check() -def test_test_command_install_requirements(virtualenv, tmpdir): +def test_test_command_install_requirements(virtualenv, tmpdir, request): # Ensure pip/wheel packages are installed. virtualenv.run( "python -c \"__import__('pkg_resources').require(['pip', 'wheel'])\"") - _check_test_command_install_requirements(virtualenv, tmpdir) - - -def test_test_command_install_requirements_when_using_easy_install( - bare_virtualenv, tmpdir): - _check_test_command_install_requirements(bare_virtualenv, tmpdir) + # uninstall setuptools so that 'setup.py develop' works + virtualenv.run("python -m pip uninstall -y setuptools") + # disable index URL so bits and bobs aren't requested from PyPI + virtualenv.env['PIP_NO_INDEX'] = '1' + _check_test_command_install_requirements(virtualenv, tmpdir, request.config.rootdir) -def test_no_missing_dependencies(bare_virtualenv): +def test_no_missing_dependencies(bare_virtualenv, request): """ Quick and dirty test to ensure all external dependencies are vendored. """ for command in ('upload',): # sorted(distutils.command.__all__): - bare_virtualenv.run( - ['python', 'setup.py', command, '-h'], cd=SOURCE_DIR) + cmd = ['python', 'setup.py', command, '-h'] + bare_virtualenv.run(cmd, cd=request.config.rootdir) diff --git a/setuptools/tests/test_wheel.py b/setuptools/tests/test_wheel.py index e56eac14..7345b135 100644 --- a/setuptools/tests/test_wheel.py +++ b/setuptools/tests/test_wheel.py @@ -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] diff --git a/setuptools/tests/test_windows_wrappers.py b/setuptools/tests/test_windows_wrappers.py index fa647de8..27853aae 100644 --- a/setuptools/tests/test_windows_wrappers.py +++ b/setuptools/tests/test_windows_wrappers.py @@ -167,7 +167,7 @@ class TestGUI(WrapperTester): """).strip() def test_basic(self, tmpdir): - """Test the GUI version with the simple scipt, bar-script.py""" + """Test the GUI version with the simple script, bar-script.py""" self.create_script(tmpdir) cmd = [ |