Commit 050808db authored by Benoit Pierre's avatar Benoit Pierre

fix handling of environment markers in `install_requires`

parent f8899569
...@@ -8,6 +8,7 @@ import distutils.log ...@@ -8,6 +8,7 @@ import distutils.log
import distutils.core import distutils.core
import distutils.cmd import distutils.cmd
import distutils.dist import distutils.dist
from collections import defaultdict
from distutils.errors import (DistutilsOptionError, DistutilsPlatformError, from distutils.errors import (DistutilsOptionError, DistutilsPlatformError,
DistutilsSetupError) DistutilsSetupError)
from distutils.util import rfc822_escape from distutils.util import rfc822_escape
...@@ -134,7 +135,13 @@ def check_extras(dist, attr, value): ...@@ -134,7 +135,13 @@ def check_extras(dist, attr, value):
k, m = k.split(':', 1) k, m = k.split(':', 1)
if pkg_resources.invalid_marker(m): if pkg_resources.invalid_marker(m):
raise DistutilsSetupError("Invalid environment marker: " + m) raise DistutilsSetupError("Invalid environment marker: " + m)
list(pkg_resources.parse_requirements(v)) for r in pkg_resources.parse_requirements(v):
if r.marker:
tmpl = (
"'extras_require' requirements cannot include "
"environment markers, in {section!r}: '{req!s}'"
)
raise DistutilsSetupError(tmpl.format(section=k, req=r))
except (TypeError, ValueError, AttributeError): except (TypeError, ValueError, AttributeError):
raise DistutilsSetupError( raise DistutilsSetupError(
"'extras_require' must be a dictionary whose values are " "'extras_require' must be a dictionary whose values are "
...@@ -346,6 +353,31 @@ class Distribution(Distribution_parse_config_files, _Distribution): ...@@ -346,6 +353,31 @@ class Distribution(Distribution_parse_config_files, _Distribution):
) )
if getattr(self, 'python_requires', None): if getattr(self, 'python_requires', None):
self.metadata.python_requires = self.python_requires self.metadata.python_requires = self.python_requires
self._finalize_requires()
def _finalize_requires(self):
"""Move requirements in `install_requires` that
are using environment markers to `extras_require`.
"""
if not self.install_requires:
return
extras_require = defaultdict(list, (
(k, list(pkg_resources.parse_requirements(v)))
for k, v in (self.extras_require or {}).items()
))
install_requires = []
for r in pkg_resources.parse_requirements(self.install_requires):
marker = r.marker
if not marker:
install_requires.append(r)
continue
r.marker = None
extras_require[':'+str(marker)].append(r)
self.extras_require = dict(
(k, [str(r) for r in v])
for k, v in extras_require.items()
)
self.install_requires = [str(r) for r in install_requires]
def parse_config_files(self, filenames=None): def parse_config_files(self, filenames=None):
"""Parses configuration files from various levels """Parses configuration files from various levels
......
...@@ -185,8 +185,12 @@ class TestEggInfo(object): ...@@ -185,8 +185,12 @@ class TestEggInfo(object):
self._run_install_command(tmpdir_cwd, env) self._run_install_command(tmpdir_cwd, env)
egg_info_dir = self._find_egg_info_files(env.paths['lib']).base egg_info_dir = self._find_egg_info_files(env.paths['lib']).base
requires_txt = os.path.join(egg_info_dir, 'requires.txt') requires_txt = os.path.join(egg_info_dir, 'requires.txt')
assert "barbazquux;python_version<'2'" in open( with open(requires_txt) as fp:
requires_txt).read().split('\n') install_requires = fp.read()
assert install_requires.lstrip() == DALS('''
[:python_version < "2"]
barbazquux
''')
assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == [] assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == []
def test_setup_requires_with_markers(self, tmpdir_cwd, env): def test_setup_requires_with_markers(self, tmpdir_cwd, env):
...@@ -202,10 +206,11 @@ class TestEggInfo(object): ...@@ -202,10 +206,11 @@ class TestEggInfo(object):
tmpdir_cwd, env, cmd=['test'], output="Ran 0 tests in") tmpdir_cwd, env, cmd=['test'], output="Ran 0 tests in")
assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == [] assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == []
def test_extra_requires_with_markers(self, tmpdir_cwd, env): def test_extras_require_with_markers(self, tmpdir_cwd, env):
self._setup_script_with_requires( self._setup_script_with_requires(
"""extra_requires={":python_version<'2'": ["barbazquux"]},""") """extras_require={"extra": ["barbazquux; python_version<'2'"]},""")
self._run_install_command(tmpdir_cwd, env) with pytest.raises(AssertionError):
self._run_install_command(tmpdir_cwd, env)
assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == [] assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == []
def test_python_requires_egg_info(self, tmpdir_cwd, env): def test_python_requires_egg_info(self, tmpdir_cwd, env):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment