From b51f6fd96bbdfc22dfdf1eb4eddc054aea335fb6 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Mon, 14 Jan 2019 10:33:33 +0900 Subject: [PATCH] Imported Upstream version 36.2.2 --- .travis.yml | 2 +- CHANGES.rst | 6 +++ setup.cfg | 2 +- setup.py | 2 +- setuptools/dist.py | 88 +++++++++++++++++++------------ setuptools/tests/test_egg_info.py | 42 ++++++++++++--- tests/requirements.txt | 1 - 7 files changed, 98 insertions(+), 45 deletions(-) diff --git a/.travis.yml b/.travis.yml index b207a8d..dbbe3ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ jobs: env: LANG=C - python: *latest_py2 env: LANG=C - - stage: deploy (does actual deploy to PYPI only for tagged commits) + - stage: deploy (to PyPI for tagged commits) python: *latest_py3 install: skip script: skip diff --git a/CHANGES.rst b/CHANGES.rst index 36b2fca..9a16816 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,9 @@ +v36.2.2 +------- + +* #1099: Revert commit a3ec721, restoring intended purpose of + extras as part of a requirement declaration. + v36.2.1 ------- diff --git a/setup.cfg b/setup.cfg index 203b931..33024f5 100755 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 36.2.1 +current_version = 36.2.2 commit = True tag = True diff --git a/setup.py b/setup.py index 854aee3..5c48f74 100755 --- a/setup.py +++ b/setup.py @@ -89,7 +89,7 @@ def pypi_link(pkg_filename): setup_params = dict( name="setuptools", - version="36.2.1", + version="36.2.2", description="Easily download, build, install, upgrade, and uninstall " "Python packages", author="Python Packaging Authority", diff --git a/setuptools/dist.py b/setuptools/dist.py index 9a034db..0787261 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -16,7 +16,7 @@ from distutils.errors import ( from distutils.util import rfc822_escape from setuptools.extern import six -from setuptools.extern.six.moves import map +from setuptools.extern.six.moves import map, filter, filterfalse from pkg_resources.extern import packaging from setuptools.depends import Require @@ -356,45 +356,63 @@ class Distribution(Distribution_parse_config_files, _Distribution): def _finalize_requires(self): """ Fix environment markers in `install_requires` and `extras_require`. + """ + self._convert_extras_requirements() + self._move_install_requirements_markers() - - move requirements in `install_requires` that are using environment - markers or extras to `extras_require`. - - convert requirements in `extras_require` of the form - `"extra": ["barbazquux; {marker}"]` to - `"extra:{marker}": ["barbazquux"]`. + def _convert_extras_requirements(self): + """ + Convert requirements in `extras_require` of the form + `"extra": ["barbazquux; {marker}"]` to + `"extra:{marker}": ["barbazquux"]`. """ - extras_require = defaultdict(list) - for k, v in ( - getattr(self, 'extras_require', None) or {} - ).items(): + spec_ext_reqs = getattr(self, 'extras_require', None) or {} + self._tmp_extras_require = defaultdict(list) + for section, v in spec_ext_reqs.items(): for r in pkg_resources.parse_requirements(v): - marker = r.marker - if marker: - r.marker = None - extras_require[k + ':' + str(marker)].append(r) - else: - extras_require[k].append(r) - install_requires = [] - for r in pkg_resources.parse_requirements( - getattr(self, 'install_requires', None) or () - ): - marker = r.marker - extras = r.extras - if not marker and not extras: - install_requires.append(r) - continue - r.extras = () - r.marker = None - for e in extras or ('',): - section = e - if marker: - section += ':' + str(marker) - extras_require[section].append(r) + suffix = self._suffix_for(r) + self._tmp_extras_require[section + suffix].append(r) + + @staticmethod + def _suffix_for(req): + """ + For a requirement, return the 'extras_require' suffix for + that requirement. + """ + return ':' + str(req.marker) if req.marker else '' + + def _move_install_requirements_markers(self): + """ + Move requirements in `install_requires` that are using environment + markers `extras_require`. + """ + + # divide the install_requires into two sets, simple ones still + # handled by install_requires and more complex ones handled + # by extras_require. + + def is_simple_req(req): + return not req.marker + + spec_inst_reqs = getattr(self, 'install_requires', None) or () + inst_reqs = list(pkg_resources.parse_requirements(spec_inst_reqs)) + simple_reqs = filter(is_simple_req, inst_reqs) + complex_reqs = filterfalse(is_simple_req, inst_reqs) + self.install_requires = list(map(str, simple_reqs)) + + for r in complex_reqs: + self._tmp_extras_require[':' + str(r.marker)].append(r) self.extras_require = dict( - (k, [str(r) for r in v]) - for k, v in extras_require.items() + (k, [str(r) for r in map(self._clean_req, v)]) + for k, v in self._tmp_extras_require.items() ) - self.install_requires = [str(r) for r in install_requires] + + def _clean_req(self, req): + """ + Given a Requirement, remove environment markers and return it. + """ + req.marker = None + return req def parse_config_files(self, filenames=None): """Parses configuration files from various levels diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index 5ea55d6..d9d4ec3 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -207,14 +207,13 @@ class TestEggInfo(object): def test_install_requires_with_extra(self, tmpdir_cwd, env): req = 'install_requires=["barbazquux [test]"],' self._setup_script_with_requires(req) - self._run_install_command(tmpdir_cwd, env) - egg_info_dir = self._find_egg_info_files(env.paths['lib']).base + self._run_install_command(tmpdir_cwd, env, cmd=['egg_info']) + egg_info_dir = os.path.join('.', 'foo.egg-info') requires_txt = os.path.join(egg_info_dir, 'requires.txt') with open(requires_txt) as fp: install_requires = fp.read() expected_requires = DALS(''' - [test] - barbazquux + barbazquux[test] ''') assert install_requires.lstrip() == expected_requires assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == [] @@ -229,8 +228,8 @@ class TestEggInfo(object): with open(requires_txt) as fp: install_requires = fp.read() expected_requires = DALS(''' - [test:{marker}] - barbazquux + [:{marker}] + barbazquux[test] ''').format(marker=self.mismatch_marker_alternate) assert install_requires.lstrip() == expected_requires assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == [] @@ -250,6 +249,37 @@ class TestEggInfo(object): tmpdir_cwd, env, cmd=['test'], output="Ran 0 tests in") assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == [] + def test_extras_require_with_extra(self, tmpdir_cwd, env): + req = 'extras_require={"extra": ["barbazquux [test]"]},' + self._setup_script_with_requires(req) + self._run_install_command(tmpdir_cwd, env, cmd=['egg_info']) + egg_info_dir = os.path.join('.', 'foo.egg-info') + requires_txt = os.path.join(egg_info_dir, 'requires.txt') + with open(requires_txt) as fp: + install_requires = fp.read() + expected_requires = DALS(''' + [extra] + barbazquux[test] + ''') + assert install_requires.lstrip() == expected_requires + assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == [] + + def test_extras_require_with_extra_and_marker_in_req(self, tmpdir_cwd, env): + tmpl = 'extras_require={{"extra": ["barbazquux [test]; {marker}"]}},' + req = tmpl.format(marker=self.mismatch_marker) + self._setup_script_with_requires(req) + self._run_install_command(tmpdir_cwd, env) + egg_info_dir = self._find_egg_info_files(env.paths['lib']).base + requires_txt = os.path.join(egg_info_dir, 'requires.txt') + with open(requires_txt) as fp: + install_requires = fp.read() + expected_requires = DALS(''' + [extra:{marker}] + barbazquux[test] + ''').format(marker=self.mismatch_marker_alternate) + assert install_requires.lstrip() == expected_requires + assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == [] + def test_extras_require_with_marker(self, tmpdir_cwd, env): tmpl = 'extras_require={{":{marker}": ["barbazquux"]}},' req = tmpl.format(marker=self.mismatch_marker) diff --git a/tests/requirements.txt b/tests/requirements.txt index 0c4df8e..44e76ed 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -3,4 +3,3 @@ mock pytest-flake8 pytest-virtualenv>=1.2.7 pytest>=3.0.2 -virtualenv -- 2.34.1