summaryrefslogtreecommitdiff
path: root/setuptools/build_meta.py
diff options
context:
space:
mode:
authorPaul Ganssle <paul@ganssle.io>2019-03-16 12:53:05 -0400
committerPaul Ganssle <paul@ganssle.io>2019-03-16 12:58:29 -0400
commit318f739d14a810042e6803fa3eb4c4e140f0ef88 (patch)
treeb7f6d6f6c71d783632221c12faa386d8f6c99262 /setuptools/build_meta.py
parent1aa781cd8ee638e7b403ebbd1caa82f8c7d4e6cd (diff)
downloadpython-setuptools-git-318f739d14a810042e6803fa3eb4c4e140f0ef88.tar.gz
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
Diffstat (limited to 'setuptools/build_meta.py')
-rw-r--r--setuptools/build_meta.py45
1 files changed, 44 insertions, 1 deletions
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):
"""