Commit 37eb2562 by Sébastien Eustace

Fix Python requirements not properly set when resolving dependencies

parent 4871b627
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
- Fixed handling of `in` environment markers with commas. - Fixed handling of `in` environment markers with commas.
- Fixed a `UnicodeDecodeError` when an error occurs in venv. - Fixed a `UnicodeDecodeError` when an error occurs in venv.
- Fixed Python requirements not properly set when resolving dependencies.
## [0.10.1] - 2018-05-28 ## [0.10.1] - 2018-05-28
......
...@@ -44,6 +44,8 @@ class Dependency(object): ...@@ -44,6 +44,8 @@ class Dependency(object):
self._extras = [] self._extras = []
self._in_extras = [] self._in_extras = []
self._activated = not self._optional
self.is_root = False self.is_root = False
@property @property
...@@ -106,6 +108,9 @@ class Dependency(object): ...@@ -106,6 +108,9 @@ class Dependency(object):
def is_optional(self): def is_optional(self):
return self._optional return self._optional
def is_activated(self):
return self._activated
def is_vcs(self): def is_vcs(self):
return False return False
...@@ -244,13 +249,16 @@ class Dependency(object): ...@@ -244,13 +249,16 @@ class Dependency(object):
""" """
Set the dependency as mandatory. Set the dependency as mandatory.
""" """
self._optional = False self._activated = True
def deactivate(self): def deactivate(self):
""" """
Set the dependency as optional. Set the dependency as optional.
""" """
self._optional = True if not self._optional:
self._optional = True
self._activated = False
def with_constraint(self, constraint): def with_constraint(self, constraint):
new = Dependency( new = Dependency(
......
...@@ -171,7 +171,7 @@ class Locker: ...@@ -171,7 +171,7 @@ class Locker:
def _dump_package(self, package): # type: (poetry.packages.Package) -> dict def _dump_package(self, package): # type: (poetry.packages.Package) -> dict
dependencies = {} dependencies = {}
for dependency in package.requires: for dependency in package.requires:
if dependency.is_optional(): if dependency.is_optional() and not dependency.is_activated():
continue continue
dependencies[dependency.pretty_name] = str(dependency.pretty_constraint) dependencies[dependency.pretty_name] = str(dependency.pretty_constraint)
......
...@@ -303,7 +303,7 @@ class Provider: ...@@ -303,7 +303,7 @@ class Provider:
return [ return [
r r
for r in package.requires for r in package.requires
if not r.is_optional() and r.name not in self.UNSAFE_PACKAGES if not r.is_activated() and r.name not in self.UNSAFE_PACKAGES
] ]
else: else:
return Dependencies(package, self) return Dependencies(package, self)
...@@ -324,7 +324,7 @@ class Provider: ...@@ -324,7 +324,7 @@ class Provider:
return [ return [
r r
for r in package.requires for r in package.requires
if not r.is_optional() if r.is_activated()
and self._package.python_constraint.allows_any(r.python_constraint) and self._package.python_constraint.allows_any(r.python_constraint)
and self._package.platform_constraint.matches(package.platform_constraint) and self._package.platform_constraint.matches(package.platform_constraint)
and r.name not in self.UNSAFE_PACKAGES and r.name not in self.UNSAFE_PACKAGES
......
...@@ -17,7 +17,7 @@ python-versions = "*" ...@@ -17,7 +17,7 @@ python-versions = "*"
platform = "*" platform = "*"
[package.requirements] [package.requirements]
python = ">=2.4,<2.5" python = "~2.4"
[[package]] [[package]]
name = "C" name = "C"
...@@ -32,7 +32,7 @@ platform = "*" ...@@ -32,7 +32,7 @@ platform = "*"
D = "^1.2" D = "^1.2"
[package.requirements] [package.requirements]
python = ">=2.7,<2.8 || >=3.4,<4.0" python = "~2.7 || ^3.4"
[[package]] [[package]]
name = "D" name = "D"
...@@ -44,7 +44,10 @@ python-versions = "*" ...@@ -44,7 +44,10 @@ python-versions = "*"
platform = "*" platform = "*"
[package.requirements] [package.requirements]
python = ">=2.7,<2.8 || >=3.4,<4.0" python = "~2.7 || ^3.4"
[extras]
foo = ["A"]
[metadata] [metadata]
python-versions = "~2.7 || ^3.4" python-versions = "~2.7 || ^3.4"
......
...@@ -46,6 +46,9 @@ platform = "*" ...@@ -46,6 +46,9 @@ platform = "*"
[package.requirements] [package.requirements]
platform = "darwin" platform = "darwin"
[extras]
foo = ["A"]
[metadata] [metadata]
python-versions = "*" python-versions = "*"
platform = "*" platform = "*"
......
...@@ -316,6 +316,7 @@ def test_run_with_optional_and_python_restricted_dependencies( ...@@ -316,6 +316,7 @@ def test_run_with_optional_and_python_restricted_dependencies(
repo.add_package(package_c13) repo.add_package(package_c13)
repo.add_package(package_d) repo.add_package(package_d)
package.extras = {"foo": [get_dependency("A", "~1.0")]}
package.add_dependency("A", {"version": "~1.0", "optional": True}) package.add_dependency("A", {"version": "~1.0", "optional": True})
package.add_dependency("B", {"version": "^1.0", "python": "~2.4"}) package.add_dependency("B", {"version": "^1.0", "python": "~2.4"})
package.add_dependency("C", {"version": "^1.0", "python": "~2.7 || ^3.4"}) package.add_dependency("C", {"version": "^1.0", "python": "~2.7 || ^3.4"})
...@@ -350,6 +351,7 @@ def test_run_with_optional_and_platform_restricted_dependencies( ...@@ -350,6 +351,7 @@ def test_run_with_optional_and_platform_restricted_dependencies(
repo.add_package(package_c13) repo.add_package(package_c13)
repo.add_package(package_d) repo.add_package(package_d)
package.extras = {"foo": [get_dependency("A", "~1.0")]}
package.add_dependency("A", {"version": "~1.0", "optional": True}) package.add_dependency("A", {"version": "~1.0", "optional": True})
package.add_dependency("B", {"version": "^1.0", "platform": "custom"}) package.add_dependency("B", {"version": "^1.0", "platform": "custom"})
package.add_dependency("C", {"version": "^1.0", "platform": "darwin"}) package.add_dependency("C", {"version": "^1.0", "platform": "darwin"})
......
...@@ -540,9 +540,9 @@ def test_solver_sub_dependencies_with_requirements(solver, repo, package): ...@@ -540,9 +540,9 @@ def test_solver_sub_dependencies_with_requirements(solver, repo, package):
def test_solver_sub_dependencies_with_requirements_complex(solver, repo, package): def test_solver_sub_dependencies_with_requirements_complex(solver, repo, package):
package.add_dependency("A") package.add_dependency("A", {"version": "^1.0", "python": "<5.0"})
package.add_dependency("B") package.add_dependency("B", {"version": "^1.0", "python": "<5.0"})
package.add_dependency("C") package.add_dependency("C", {"version": "^1.0", "python": "<4.0"})
package_a = get_package("A", "1.0") package_a = get_package("A", "1.0")
package_b = get_package("B", "1.0") package_b = get_package("B", "1.0")
...@@ -551,11 +551,11 @@ def test_solver_sub_dependencies_with_requirements_complex(solver, repo, package ...@@ -551,11 +551,11 @@ def test_solver_sub_dependencies_with_requirements_complex(solver, repo, package
package_e = get_package("E", "1.0") package_e = get_package("E", "1.0")
package_f = get_package("F", "1.0") package_f = get_package("F", "1.0")
package_a.add_dependency("B", "^1.0") package_a.add_dependency("B", {"version": "^1.0", "python": "<4.0"})
package_a.add_dependency("D", {"version": "^1.0", "python": "<4.0"}) package_a.add_dependency("D", {"version": "^1.0", "python": "<4.0"})
package_b.add_dependency("E", {"version": "^1.0", "platform": "win32"}) package_b.add_dependency("E", {"version": "^1.0", "platform": "win32"})
package_b.add_dependency("F") package_b.add_dependency("F", {"version": "^1.0", "python": "<5.0"})
package_c.add_dependency("F", "^1.0") package_c.add_dependency("F", {"version": "^1.0", "python": "<4.0"})
package_d.add_dependency("F") package_d.add_dependency("F")
repo.add_package(package_a) repo.add_package(package_a)
...@@ -579,11 +579,17 @@ def test_solver_sub_dependencies_with_requirements_complex(solver, repo, package ...@@ -579,11 +579,17 @@ def test_solver_sub_dependencies_with_requirements_complex(solver, repo, package
], ],
) )
op = ops[0]
assert op.package.requirements == {"python": "<4.0"}
op = ops[1] op = ops[1]
assert op.package.requirements == {"platform": "win32"} assert op.package.requirements == {"platform": "win32", "python": "<5.0"}
op = ops[2] op = ops[2]
assert op.package.requirements == {} assert op.package.requirements == {"python": "<5.0"}
op = ops[4]
assert op.package.requirements == {"python": "<5.0"}
def test_solver_sub_dependencies_with_not_supported_python_version( def test_solver_sub_dependencies_with_not_supported_python_version(
...@@ -730,3 +736,26 @@ def test_solver_with_dependency_and_prerelease_sub_dependencies(solver, repo, pa ...@@ -730,3 +736,26 @@ def test_solver_with_dependency_and_prerelease_sub_dependencies(solver, repo, pa
{"job": "install", "package": package_a}, {"job": "install", "package": package_a},
], ],
) )
def test_solver_circular_dependency(solver, repo, package):
package.add_dependency("A")
package_a = get_package("A", "1.0")
package_a.add_dependency("B", "^1.0")
package_b = get_package("B", "1.0")
package_b.add_dependency("A", "^1.0")
repo.add_package(package_a)
repo.add_package(package_b)
ops = solver.solve()
check_solver_result(
ops,
[
{"job": "install", "package": package_b},
{"job": "install", "package": package_a},
],
)
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