From 731df905fb0282c7255e4e0d4acf339a98e3db7e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 2 Jan 2019 14:28:33 -0500 Subject: Always specify formats=gztar, overriding the project's legacy expectation that a zip sdist should be generated. Fixes #1623. --- setuptools/build_meta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 463d3757..75178a7a 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -170,7 +170,7 @@ def build_wheel(wheel_directory, config_settings=None, def build_sdist(sdist_directory, config_settings=None): config_settings = _fix_config(config_settings) sdist_directory = os.path.abspath(sdist_directory) - sys.argv = sys.argv[:1] + ['sdist'] + \ + sys.argv = sys.argv[:1] + ['sdist', '--formats', 'gztar'] + \ config_settings["--global-option"] + \ ["--dist-dir", sdist_directory] _run_setup() -- cgit v1.2.3 From cc9305b9106eaf409c01e8a399a00137583e2a04 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 2 Jan 2019 14:37:45 -0500 Subject: Rely on iterable unpacking to extract one element from generator expression. --- setuptools/build_meta.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 463d3757..7f2786c4 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -160,11 +160,11 @@ def build_wheel(wheel_directory, config_settings=None, shutil.rmtree(wheel_directory) shutil.copytree('dist', wheel_directory) - wheels = [f for f in os.listdir(wheel_directory) - if f.endswith('.whl')] + wheels = (f for f in os.listdir(wheel_directory) + if f.endswith('.whl')) - assert len(wheels) == 1 - return wheels[0] + wheel, = wheels + return wheel def build_sdist(sdist_directory, config_settings=None): @@ -175,8 +175,8 @@ def build_sdist(sdist_directory, config_settings=None): ["--dist-dir", sdist_directory] _run_setup() - sdists = [f for f in os.listdir(sdist_directory) - if f.endswith('.tar.gz')] + sdists = (f for f in os.listdir(sdist_directory) + if f.endswith('.tar.gz')) - assert len(sdists) == 1 - return sdists[0] + sdist, = sdists + return sdist -- cgit v1.2.3 From 7378e6be2f8f8a0d96b748e256dfa6b53821c3f6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 2 Jan 2019 14:39:37 -0500 Subject: Avoid hanging indent --- setuptools/build_meta.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 7f2786c4..5a69d284 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -160,8 +160,10 @@ def build_wheel(wheel_directory, config_settings=None, shutil.rmtree(wheel_directory) shutil.copytree('dist', wheel_directory) - wheels = (f for f in os.listdir(wheel_directory) - if f.endswith('.whl')) + wheels = ( + f for f in os.listdir(wheel_directory) + if f.endswith('.whl') + ) wheel, = wheels return wheel @@ -175,8 +177,10 @@ def build_sdist(sdist_directory, config_settings=None): ["--dist-dir", sdist_directory] _run_setup() - sdists = (f for f in os.listdir(sdist_directory) - if f.endswith('.tar.gz')) + sdists = ( + f for f in os.listdir(sdist_directory) + if f.endswith('.tar.gz') + ) sdist, = sdists return sdist -- cgit v1.2.3 From 2bb8225a6efa6f429d4522f47308b779a48cd07f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 2 Jan 2019 14:42:23 -0500 Subject: Extract common behavior into a function --- setuptools/build_meta.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 5a69d284..02de4427 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -149,6 +149,15 @@ def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None): return dist_infos[0] +def _file_with_extension(directory, extension): + matching = ( + f for f in os.listdir(directory) + if f.endswith(extension) + ) + file, = matching + return file + + def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): config_settings = _fix_config(config_settings) @@ -160,13 +169,7 @@ def build_wheel(wheel_directory, config_settings=None, shutil.rmtree(wheel_directory) shutil.copytree('dist', wheel_directory) - wheels = ( - f for f in os.listdir(wheel_directory) - if f.endswith('.whl') - ) - - wheel, = wheels - return wheel + return _file_with_extension(wheel_directory, '.whl') def build_sdist(sdist_directory, config_settings=None): @@ -177,10 +180,4 @@ def build_sdist(sdist_directory, config_settings=None): ["--dist-dir", sdist_directory] _run_setup() - sdists = ( - f for f in os.listdir(sdist_directory) - if f.endswith('.tar.gz') - ) - - sdist, = sdists - return sdist + return _file_with_extension(sdist_directory, '.tar.gz') -- cgit v1.2.3 From 74c323d1658f554b879ef6ac2867faf77776a2ac Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Sun, 27 Jan 2019 11:45:10 -0500 Subject: Wrap build_meta backend in a class In order to support both the `build_meta` and `build_meta_legacy` backends, the core functionality is wrapped in a class with methods to be overridden in build_meta_legacy. The class is an implementation detail and should remain private. --- setuptools/build_meta.py | 187 ++++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 90 deletions(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index c883d92f..f40549e7 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -74,81 +74,11 @@ def _to_str(s): return s -def _run_setup(setup_script='setup.py'): - # Note that we can reuse our build directory between calls - # Correctness comes first, then optimization later - __file__ = setup_script - __name__ = '__main__' - f = getattr(tokenize, 'open', open)(__file__) - code = f.read().replace('\\r\\n', '\\n') - f.close() - exec(compile(code, __file__, 'exec'), locals()) - - -def _fix_config(config_settings): - config_settings = config_settings or {} - config_settings.setdefault('--global-option', []) - return config_settings - - -def _get_build_requires(config_settings, requirements): - config_settings = _fix_config(config_settings) - - sys.argv = sys.argv[:1] + ['egg_info'] + \ - config_settings["--global-option"] - try: - with Distribution.patch(): - _run_setup() - except SetupRequirementsError as e: - requirements += e.specifiers - - return requirements - - def _get_immediate_subdirectories(a_dir): return [name for name in os.listdir(a_dir) if os.path.isdir(os.path.join(a_dir, name))] -def get_requires_for_build_wheel(config_settings=None): - config_settings = _fix_config(config_settings) - return _get_build_requires(config_settings, requirements=['wheel']) - - -def get_requires_for_build_sdist(config_settings=None): - config_settings = _fix_config(config_settings) - return _get_build_requires(config_settings, requirements=[]) - - -def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None): - sys.argv = sys.argv[:1] + ['dist_info', '--egg-base', _to_str(metadata_directory)] - _run_setup() - - dist_info_directory = metadata_directory - while True: - dist_infos = [f for f in os.listdir(dist_info_directory) - if f.endswith('.dist-info')] - - if len(dist_infos) == 0 and \ - len(_get_immediate_subdirectories(dist_info_directory)) == 1: - dist_info_directory = os.path.join( - dist_info_directory, os.listdir(dist_info_directory)[0]) - continue - - assert len(dist_infos) == 1 - break - - # PEP 517 requires that the .dist-info directory be placed in the - # metadata_directory. To comply, we MUST copy the directory to the root - if dist_info_directory != metadata_directory: - shutil.move( - os.path.join(dist_info_directory, dist_infos[0]), - metadata_directory) - shutil.rmtree(dist_info_directory, ignore_errors=True) - - return dist_infos[0] - - def _file_with_extension(directory, extension): matching = ( f for f in os.listdir(directory) @@ -158,26 +88,103 @@ def _file_with_extension(directory, extension): return file -def build_wheel(wheel_directory, config_settings=None, - metadata_directory=None): - config_settings = _fix_config(config_settings) - wheel_directory = os.path.abspath(wheel_directory) - sys.argv = sys.argv[:1] + ['bdist_wheel'] + \ - config_settings["--global-option"] - _run_setup() - if wheel_directory != 'dist': - shutil.rmtree(wheel_directory) - shutil.copytree('dist', wheel_directory) +class _BuildMetaBackend(object): - return _file_with_extension(wheel_directory, '.whl') + def _fix_config(self, config_settings): + config_settings = config_settings or {} + config_settings.setdefault('--global-option', []) + return config_settings + def _get_build_requires(self, config_settings, requirements): + config_settings = self._fix_config(config_settings) -def build_sdist(sdist_directory, config_settings=None): - config_settings = _fix_config(config_settings) - sdist_directory = os.path.abspath(sdist_directory) - sys.argv = sys.argv[:1] + ['sdist', '--formats', 'gztar'] + \ - config_settings["--global-option"] + \ - ["--dist-dir", sdist_directory] - _run_setup() - - return _file_with_extension(sdist_directory, '.tar.gz') + sys.argv = sys.argv[:1] + ['egg_info'] + \ + config_settings["--global-option"] + try: + with Distribution.patch(): + self.run_setup() + except SetupRequirementsError as e: + requirements += e.specifiers + + return requirements + + def run_setup(self, setup_script='setup.py'): + # Note that we can reuse our build directory between calls + # Correctness comes first, then optimization later + __file__ = setup_script + __name__ = '__main__' + f = getattr(tokenize, 'open', open)(__file__) + code = f.read().replace('\\r\\n', '\\n') + f.close() + exec(compile(code, __file__, 'exec'), locals()) + + def get_requires_for_build_wheel(self, config_settings=None): + config_settings = self._fix_config(config_settings) + return self._get_build_requires(config_settings, requirements=['wheel']) + + def get_requires_for_build_sdist(self, config_settings=None): + config_settings = self._fix_config(config_settings) + return self._get_build_requires(config_settings, requirements=[]) + + def prepare_metadata_for_build_wheel(self, metadata_directory, + config_settings=None): + sys.argv = sys.argv[:1] + ['dist_info', '--egg-base', + _to_str(metadata_directory)] + self.run_setup() + + dist_info_directory = metadata_directory + while True: + dist_infos = [f for f in os.listdir(dist_info_directory) + if f.endswith('.dist-info')] + + if (len(dist_infos) == 0 and + len(_get_immediate_subdirectories(dist_info_directory)) == 1): + + dist_info_directory = os.path.join( + dist_info_directory, os.listdir(dist_info_directory)[0]) + continue + + assert len(dist_infos) == 1 + break + + # PEP 517 requires that the .dist-info directory be placed in the + # metadata_directory. To comply, we MUST copy the directory to the root + if dist_info_directory != metadata_directory: + shutil.move( + os.path.join(dist_info_directory, dist_infos[0]), + metadata_directory) + shutil.rmtree(dist_info_directory, ignore_errors=True) + + return dist_infos[0] + + def build_wheel(self, wheel_directory, config_settings=None, + metadata_directory=None): + config_settings = self._fix_config(config_settings) + wheel_directory = os.path.abspath(wheel_directory) + sys.argv = sys.argv[:1] + ['bdist_wheel'] + \ + config_settings["--global-option"] + self.run_setup() + if wheel_directory != 'dist': + shutil.rmtree(wheel_directory) + shutil.copytree('dist', wheel_directory) + + return _file_with_extension(wheel_directory, '.whl') + + def build_sdist(self, sdist_directory, config_settings=None): + config_settings = self._fix_config(config_settings) + sdist_directory = os.path.abspath(sdist_directory) + sys.argv = sys.argv[:1] + ['sdist', '--formats', 'gztar'] + \ + config_settings["--global-option"] + \ + ["--dist-dir", sdist_directory] + self.run_setup() + + return _file_with_extension(sdist_directory, '.tar.gz') + + +_BACKEND = _BuildMetaBackend() + +get_requires_for_build_wheel = _BACKEND.get_requires_for_build_wheel +get_requires_for_build_sdist = _BACKEND.get_requires_for_build_sdist +prepare_metadata_for_build_wheel = _BACKEND.prepare_metadata_for_build_wheel +build_wheel = _BACKEND.build_wheel +build_sdist = _BACKEND.build_sdist -- cgit v1.2.3 From f40a47a776904b09747502a1f210af9fc92ec542 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Sun, 27 Jan 2019 11:46:21 -0500 Subject: Add __all__ to setuptools.build_meta --- setuptools/build_meta.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index f40549e7..8e31a04d 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -35,6 +35,12 @@ import contextlib import setuptools import distutils +__all__ = ['get_requires_for_build_sdist', + 'get_requires_for_build_wheel', + 'prepare_metadata_for_build_wheel', + 'build_wheel', + 'build_sdist', + 'SetupRequirementsError'] class SetupRequirementsError(BaseException): def __init__(self, specifiers): -- cgit v1.2.3 From 11fb3f38d23ff1e0d81e64ba3b68b3de2d2b990a Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Sun, 3 Feb 2019 12:17:46 -0500 Subject: Move build_meta_legacy to build_meta:legacy Rather than exposing a top-level module for the legacy backend, we will move the legacy backend into the `setuptools.build_meta` module and specify it using the module:object syntax. --- setuptools/build_meta.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 8e31a04d..e16f319e 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -40,6 +40,7 @@ __all__ = ['get_requires_for_build_sdist', 'prepare_metadata_for_build_wheel', 'build_wheel', 'build_sdist', + 'legacy', 'SetupRequirementsError'] class SetupRequirementsError(BaseException): @@ -187,6 +188,36 @@ class _BuildMetaBackend(object): return _file_with_extension(sdist_directory, '.tar.gz') +class _BuildMetaLegacyBackend(_BuildMetaBackend): + """Compatibility backend for setuptools + + This is a version of setuptools.build_meta that endeavors to maintain backwards + compatibility with pre-PEP 517 modes of invocation. It exists as a temporary + bridge between the old packaging mechanism and the new packaging mechanism, + and will eventually be removed. + """ + def run_setup(self, setup_script='setup.py'): + # In order to maintain compatibility with scripts assuming that + # the setup.py script is in a directory on the PYTHONPATH, inject + # '' into sys.path. (pypa/setuptools#1642) + sys_path = list(sys.path) # Save the original path + + script_dir = os.path.dirname(os.path.abspath(setup_script)) + if script_dir not in sys.path: + sys.path.insert(0, script_dir) + + try: + super(_BuildMetaLegacyBackend, + self).run_setup(setup_script=setup_script) + finally: + # While PEP 517 frontends should be calling each hook in a fresh + # subprocess according to the standard (and thus it should not be + # strictly necessary to restore the old sys.path), we'll restore + # the original path so that the path manipulation does not persist + # within the hook after run_setup is called. + sys.path[:] = sys_path + +# The primary backend _BACKEND = _BuildMetaBackend() get_requires_for_build_wheel = _BACKEND.get_requires_for_build_wheel @@ -194,3 +225,7 @@ get_requires_for_build_sdist = _BACKEND.get_requires_for_build_sdist prepare_metadata_for_build_wheel = _BACKEND.prepare_metadata_for_build_wheel build_wheel = _BACKEND.build_wheel build_sdist = _BACKEND.build_sdist + + +# The legacy backend +legacy = _BuildMetaLegacyBackend() -- cgit v1.2.3 From e04a41e3129fa9945e15b16fd6d65cc212c1d946 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Tue, 5 Feb 2019 08:42:36 -0500 Subject: Rename build_meta:legacy to build_meta:__legacy__ --- setuptools/build_meta.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index e16f319e..70b7ab23 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -40,7 +40,7 @@ __all__ = ['get_requires_for_build_sdist', 'prepare_metadata_for_build_wheel', 'build_wheel', 'build_sdist', - 'legacy', + '__legacy__', 'SetupRequirementsError'] class SetupRequirementsError(BaseException): @@ -228,4 +228,4 @@ build_sdist = _BACKEND.build_sdist # The legacy backend -legacy = _BuildMetaLegacyBackend() +__legacy__ = _BuildMetaLegacyBackend() -- cgit v1.2.3 From 179115b198387a21202433ea61cc53f2efd383fc Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Thu, 31 Jan 2019 08:29:36 -0500 Subject: Add support for setup.cfg-only projects Many projects can get away with an empty `setup.py` and use *only* the declarative `setup.cfg`. With the new PEP 517 backend, we can supply a default empty `setup.py` if one is not provided. --- setuptools/build_meta.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 70b7ab23..047cc07b 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -26,6 +26,7 @@ bug reports or API stability): Again, this is not a formal definition! Just a "taste" of the module. """ +import io import os import sys import tokenize @@ -95,6 +96,14 @@ def _file_with_extension(directory, extension): return file +def _open_setup_script(setup_script): + if not os.path.exists(setup_script): + # Supply a default setup.py + return io.StringIO(u"from setuptools import setup; setup()") + + return getattr(tokenize, 'open', open)(setup_script) + + class _BuildMetaBackend(object): def _fix_config(self, config_settings): @@ -120,9 +129,10 @@ class _BuildMetaBackend(object): # Correctness comes first, then optimization later __file__ = setup_script __name__ = '__main__' - f = getattr(tokenize, 'open', open)(__file__) - code = f.read().replace('\\r\\n', '\\n') - f.close() + + with _open_setup_script(__file__) as f: + code = f.read().replace(r'\r\n', r'\n') + exec(compile(code, __file__, 'exec'), locals()) def get_requires_for_build_wheel(self, config_settings=None): -- cgit v1.2.3 From 318f739d14a810042e6803fa3eb4c4e140f0ef88 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Sat, 16 Mar 2019 12:53:05 -0400 Subject: Add requirement parsing in setuptools.build_meta This fixes GH #1682 by porting the pkg_resources requirement parsing logic into setuptools.build_meta, so that all valid requirement specifiers passed to setup_requires will be added to the get_requires_for_build_* function outputs. Fixes GH #1682 --- setuptools/build_meta.py | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 047cc07b..fb37c02a 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -36,6 +36,8 @@ import contextlib import setuptools import distutils +from setuptools._vendor import six + __all__ = ['get_requires_for_build_sdist', 'get_requires_for_build_wheel', 'prepare_metadata_for_build_wheel', @@ -51,7 +53,9 @@ class SetupRequirementsError(BaseException): class Distribution(setuptools.dist.Distribution): def fetch_build_eggs(self, specifiers): - raise SetupRequirementsError(specifiers) + specifier_list = self._parse_requirements(specifiers) + + raise SetupRequirementsError(specifier_list) @classmethod @contextlib.contextmanager @@ -68,6 +72,45 @@ class Distribution(setuptools.dist.Distribution): finally: distutils.core.Distribution = orig + def _yield_lines(self, strs): + """Yield non-empty/non-comment lines of a string or sequence""" + if isinstance(strs, six.string_types): + for s in strs.splitlines(): + s = s.strip() + # skip blank lines/comments + if s and not s.startswith('#'): + yield s + else: + for ss in strs: + for s in self._yield_lines(ss): + yield s + + def _parse_requirements(self, strs): + """Parse requirement specifiers into a list of requirement strings + + This is forked from pkg_resources.parse_requirements. + + `strs` must be a string, or a (possibly-nested) iterable thereof. + """ + # create a steppable iterator, so we can handle \-continuations + lines = iter(self._yield_lines(strs)) + + requirements = [] + + for line in lines: + # Drop comments -- a hash without a space may be in a URL. + if ' #' in line: + line = line[:line.find(' #')] + # If there is a line continuation, drop it, and append the next line. + if line.endswith('\\'): + line = line[:-2].strip() + try: + line += next(lines) + except StopIteration: + return + requirements.append(line) + + return requirements def _to_str(s): """ -- cgit v1.2.3 From 5efdf816fddcd8fbc9c3d1e6867a25848b1f9a06 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Sat, 16 Mar 2019 13:24:36 -0400 Subject: Use pkg_resources.parse_requirements in build_meta Since pkg_resources is imported elsewhere anyway, we don't get much value out of porting the requirement parser locally. --- setuptools/build_meta.py | 43 ++----------------------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index fb37c02a..47cbcbf6 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -36,7 +36,7 @@ import contextlib import setuptools import distutils -from setuptools._vendor import six +from pkg_resources import parse_requirements __all__ = ['get_requires_for_build_sdist', 'get_requires_for_build_wheel', @@ -53,7 +53,7 @@ class SetupRequirementsError(BaseException): class Distribution(setuptools.dist.Distribution): def fetch_build_eggs(self, specifiers): - specifier_list = self._parse_requirements(specifiers) + specifier_list = list(map(str, parse_requirements(specifiers))) raise SetupRequirementsError(specifier_list) @@ -72,45 +72,6 @@ class Distribution(setuptools.dist.Distribution): finally: distutils.core.Distribution = orig - def _yield_lines(self, strs): - """Yield non-empty/non-comment lines of a string or sequence""" - if isinstance(strs, six.string_types): - for s in strs.splitlines(): - s = s.strip() - # skip blank lines/comments - if s and not s.startswith('#'): - yield s - else: - for ss in strs: - for s in self._yield_lines(ss): - yield s - - def _parse_requirements(self, strs): - """Parse requirement specifiers into a list of requirement strings - - This is forked from pkg_resources.parse_requirements. - - `strs` must be a string, or a (possibly-nested) iterable thereof. - """ - # create a steppable iterator, so we can handle \-continuations - lines = iter(self._yield_lines(strs)) - - requirements = [] - - for line in lines: - # Drop comments -- a hash without a space may be in a URL. - if ' #' in line: - line = line[:line.find(' #')] - # If there is a line continuation, drop it, and append the next line. - if line.endswith('\\'): - line = line[:-2].strip() - try: - line += next(lines) - except StopIteration: - return - requirements.append(line) - - return requirements def _to_str(s): """ -- cgit v1.2.3 From 901f7cc2a036bfeb93bfbe480608e04c76c2c5ec Mon Sep 17 00:00:00 2001 From: Shashank Singh Date: Sat, 20 Apr 2019 23:24:41 -0400 Subject: Fix error when wheels already exist in dist/ `build_meta.build_wheel` assumes that the only wheel in its output directory is the one it builds, but prior to this, it also used the `dist/` folder as its working output directory. This commit uses a temporary directory instead, preventing an error that was triggered when previously-generated wheel files were still sitting in `dist/`. Fixes GH #1671 --- setuptools/build_meta.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 47cbcbf6..e40904a5 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -35,6 +35,7 @@ import contextlib import setuptools import distutils +from setuptools.py31compat import TemporaryDirectory from pkg_resources import parse_requirements @@ -182,14 +183,22 @@ class _BuildMetaBackend(object): metadata_directory=None): config_settings = self._fix_config(config_settings) wheel_directory = os.path.abspath(wheel_directory) - sys.argv = sys.argv[:1] + ['bdist_wheel'] + \ - config_settings["--global-option"] - self.run_setup() - if wheel_directory != 'dist': - shutil.rmtree(wheel_directory) - shutil.copytree('dist', wheel_directory) - return _file_with_extension(wheel_directory, '.whl') + # Build the wheel in a temporary directory, then copy to the target + with TemporaryDirectory(dir=wheel_directory) as tmp_dist_dir: + sys.argv = (sys.argv[:1] + + ['bdist_wheel', '--dist-dir', tmp_dist_dir] + + config_settings["--global-option"]) + self.run_setup() + + wheel_basename = _file_with_extension(tmp_dist_dir, '.whl') + wheel_path = os.path.join(wheel_directory, wheel_basename) + if os.path.exists(wheel_path): + # os.rename will fail overwriting on non-unix env + os.remove(wheel_path) + os.rename(os.path.join(tmp_dist_dir, wheel_basename), wheel_path) + + return wheel_basename def build_sdist(self, sdist_directory, config_settings=None): config_settings = self._fix_config(config_settings) -- cgit v1.2.3 From 5f88c42f3b4529956e4d02453ae571e32bc4692a Mon Sep 17 00:00:00 2001 From: Benoit Pierre Date: Mon, 22 Apr 2019 22:18:50 +0200 Subject: build_meta: fix 2 issues with `build_wheel` / `build_sdist` Fix the following cases: * `build_sdist` is called with another sdist already present in the destination directory * `build_wheel` is called with the destination directory not already created --- setuptools/build_meta.py | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index e40904a5..10c4b528 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -38,6 +38,7 @@ import distutils from setuptools.py31compat import TemporaryDirectory from pkg_resources import parse_requirements +from pkg_resources.py31compat import makedirs __all__ = ['get_requires_for_build_sdist', 'get_requires_for_build_wheel', @@ -179,36 +180,38 @@ class _BuildMetaBackend(object): return dist_infos[0] - def build_wheel(self, wheel_directory, config_settings=None, - metadata_directory=None): + def _build_with_temp_dir(self, setup_command, result_extension, + result_directory, config_settings): config_settings = self._fix_config(config_settings) - wheel_directory = os.path.abspath(wheel_directory) + result_directory = os.path.abspath(result_directory) - # Build the wheel in a temporary directory, then copy to the target - with TemporaryDirectory(dir=wheel_directory) as tmp_dist_dir: - sys.argv = (sys.argv[:1] + - ['bdist_wheel', '--dist-dir', tmp_dist_dir] + + # Build in a temporary directory, then copy to the target. + makedirs(result_directory, exist_ok=True) + with TemporaryDirectory(dir=result_directory) as tmp_dist_dir: + sys.argv = (sys.argv[:1] + setup_command + + ['--dist-dir', tmp_dist_dir] + config_settings["--global-option"]) self.run_setup() - wheel_basename = _file_with_extension(tmp_dist_dir, '.whl') - wheel_path = os.path.join(wheel_directory, wheel_basename) - if os.path.exists(wheel_path): - # os.rename will fail overwriting on non-unix env - os.remove(wheel_path) - os.rename(os.path.join(tmp_dist_dir, wheel_basename), wheel_path) + result_basename = _file_with_extension(tmp_dist_dir, result_extension) + result_path = os.path.join(result_directory, result_basename) + if os.path.exists(result_path): + # os.rename will fail overwriting on non-Unix. + os.remove(result_path) + os.rename(os.path.join(tmp_dist_dir, result_basename), result_path) - return wheel_basename + return result_basename - def build_sdist(self, sdist_directory, config_settings=None): - config_settings = self._fix_config(config_settings) - sdist_directory = os.path.abspath(sdist_directory) - sys.argv = sys.argv[:1] + ['sdist', '--formats', 'gztar'] + \ - config_settings["--global-option"] + \ - ["--dist-dir", sdist_directory] - self.run_setup() - return _file_with_extension(sdist_directory, '.tar.gz') + def build_wheel(self, wheel_directory, config_settings=None, + metadata_directory=None): + return self._build_with_temp_dir(['bdist_wheel'], '.whl', + wheel_directory, config_settings) + + def build_sdist(self, sdist_directory, config_settings=None): + return self._build_with_temp_dir(['sdist', '--formats', 'gztar'], + '.tar.gz', sdist_directory, + config_settings) class _BuildMetaLegacyBackend(_BuildMetaBackend): -- cgit v1.2.3 From 8f227af516c8c6b991c8e6c76f5bf4672f36c41e Mon Sep 17 00:00:00 2001 From: Emiel Wiedijk Date: Sat, 23 Feb 2019 20:51:09 +0100 Subject: Set sys.argv[0] in build scripts run by build_meta Some setup.py scripts, use sys.argv[0] to locate the source directory of a project. I added this to build_meta.__legacy__ since that is focused on backwards compatibility with old scripts. However, @pganssle said this behaviour should not be added to setuptools.build_meta. Fixes #1628 --- setuptools/build_meta.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 10c4b528..eb9e815e 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -232,6 +232,12 @@ class _BuildMetaLegacyBackend(_BuildMetaBackend): if script_dir not in sys.path: sys.path.insert(0, script_dir) + # Some setup.py scripts (e.g. in pygame and numpy) use sys.argv[0] to + # get the directory of the source code. They expect it to refer to the + # setup.py script. + sys_argv_0 = sys.argv[0] + sys.argv[0] = setup_script + try: super(_BuildMetaLegacyBackend, self).run_setup(setup_script=setup_script) @@ -242,6 +248,7 @@ class _BuildMetaLegacyBackend(_BuildMetaBackend): # the original path so that the path manipulation does not persist # within the hook after run_setup is called. sys.path[:] = sys_path + sys.argv[0] = sys_argv_0 # The primary backend _BACKEND = _BuildMetaBackend() -- cgit v1.2.3 From 3d4d8b9dde61b87271861b8c7ebeb168ac4fa72b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 19 Jan 2020 12:46:30 -0500 Subject: =?UTF-8?q?=F0=9F=91=B9=20Feed=20the=20hobgoblins=20(delint).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setuptools/build_meta.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'setuptools/build_meta.py') diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index eb9e815e..a1c951cf 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -48,6 +48,7 @@ __all__ = ['get_requires_for_build_sdist', '__legacy__', 'SetupRequirementsError'] + class SetupRequirementsError(BaseException): def __init__(self, specifiers): self.specifiers = specifiers @@ -143,7 +144,8 @@ class _BuildMetaBackend(object): def get_requires_for_build_wheel(self, config_settings=None): config_settings = self._fix_config(config_settings) - return self._get_build_requires(config_settings, requirements=['wheel']) + return self._get_build_requires( + config_settings, requirements=['wheel']) def get_requires_for_build_sdist(self, config_settings=None): config_settings = self._fix_config(config_settings) @@ -160,8 +162,10 @@ class _BuildMetaBackend(object): dist_infos = [f for f in os.listdir(dist_info_directory) if f.endswith('.dist-info')] - if (len(dist_infos) == 0 and - len(_get_immediate_subdirectories(dist_info_directory)) == 1): + if ( + len(dist_infos) == 0 and + len(_get_immediate_subdirectories(dist_info_directory)) == 1 + ): dist_info_directory = os.path.join( dist_info_directory, os.listdir(dist_info_directory)[0]) @@ -193,7 +197,8 @@ class _BuildMetaBackend(object): config_settings["--global-option"]) self.run_setup() - result_basename = _file_with_extension(tmp_dist_dir, result_extension) + result_basename = _file_with_extension( + tmp_dist_dir, result_extension) result_path = os.path.join(result_directory, result_basename) if os.path.exists(result_path): # os.rename will fail overwriting on non-Unix. @@ -202,7 +207,6 @@ class _BuildMetaBackend(object): return result_basename - def build_wheel(self, wheel_directory, config_settings=None, metadata_directory=None): return self._build_with_temp_dir(['bdist_wheel'], '.whl', @@ -217,9 +221,12 @@ class _BuildMetaBackend(object): class _BuildMetaLegacyBackend(_BuildMetaBackend): """Compatibility backend for setuptools - This is a version of setuptools.build_meta that endeavors to maintain backwards - compatibility with pre-PEP 517 modes of invocation. It exists as a temporary - bridge between the old packaging mechanism and the new packaging mechanism, + This is a version of setuptools.build_meta that endeavors + to maintain backwards + compatibility with pre-PEP 517 modes of invocation. It + exists as a temporary + bridge between the old packaging mechanism and the new + packaging mechanism, and will eventually be removed. """ def run_setup(self, setup_script='setup.py'): @@ -250,6 +257,7 @@ class _BuildMetaLegacyBackend(_BuildMetaBackend): sys.path[:] = sys_path sys.argv[0] = sys_argv_0 + # The primary backend _BACKEND = _BuildMetaBackend() -- cgit v1.2.3