Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
python-poetry
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
python-poetry
Commits
10c49e3f
Unverified
Commit
10c49e3f
authored
Sep 17, 2018
by
Sébastien Eustace
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix dependency resolution for Python-restricted dependencies
parent
10c3d0d5
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
128 additions
and
10 deletions
+128
-10
poetry/packages/__init__.py
+2
-0
poetry/packages/dependency_package.py
+33
-0
poetry/packages/package_collection.py
+20
-0
poetry/puzzle/provider.py
+45
-5
poetry/puzzle/solver.py
+6
-3
pyproject.toml
+1
-1
tests/mixology/helpers.py
+4
-0
tests/puzzle/test_solver.py
+17
-1
No files found.
poetry/packages/__init__.py
View file @
10c49e3f
...
@@ -4,10 +4,12 @@ import re
...
@@ -4,10 +4,12 @@ import re
from
poetry.version.requirements
import
Requirement
from
poetry.version.requirements
import
Requirement
from
.dependency
import
Dependency
from
.dependency
import
Dependency
from
.dependency_package
import
DependencyPackage
from
.directory_dependency
import
DirectoryDependency
from
.directory_dependency
import
DirectoryDependency
from
.file_dependency
import
FileDependency
from
.file_dependency
import
FileDependency
from
.locker
import
Locker
from
.locker
import
Locker
from
.package
import
Package
from
.package
import
Package
from
.package_collection
import
PackageCollection
from
.project_package
import
ProjectPackage
from
.project_package
import
ProjectPackage
from
.utils.link
import
Link
from
.utils.link
import
Link
from
.utils.utils
import
convert_markers
from
.utils.utils
import
convert_markers
...
...
poetry/packages/dependency_package.py
0 → 100644
View file @
10c49e3f
from
.package
import
Package
class
DependencyPackage
:
def
__init__
(
self
,
dependency
,
package
):
self
.
_dependency
=
dependency
self
.
_package
=
package
@property
def
dependency
(
self
):
return
self
.
_dependency
@property
def
package
(
self
):
return
self
.
_package
def
__getattr__
(
self
,
name
):
return
getattr
(
self
.
_package
,
name
)
def
__str__
(
self
):
return
str
(
self
.
_package
)
def
__repr__
(
self
):
return
repr
(
self
.
_package
)
def
__hash__
(
self
):
return
hash
(
self
.
_package
)
def
__eq__
(
self
,
other
):
if
isinstance
(
other
,
DependencyPackage
):
other
=
other
.
package
return
self
.
_package
==
other
poetry/packages/package_collection.py
0 → 100644
View file @
10c49e3f
from
.dependency_package
import
DependencyPackage
class
PackageCollection
(
list
):
def
__init__
(
self
,
dependency
,
packages
=
None
):
self
.
_dependency
=
dependency
if
packages
is
None
:
packages
=
[]
super
(
PackageCollection
,
self
)
.
__init__
()
for
package
in
packages
:
self
.
append
(
package
)
def
append
(
self
,
package
):
if
not
isinstance
(
package
,
DependencyPackage
):
package
=
DependencyPackage
(
self
.
_dependency
,
package
)
return
super
(
PackageCollection
,
self
)
.
append
(
package
)
poetry/puzzle/provider.py
View file @
10c49e3f
...
@@ -12,9 +12,11 @@ from tempfile import mkdtemp
...
@@ -12,9 +12,11 @@ from tempfile import mkdtemp
from
typing
import
List
from
typing
import
List
from
poetry.packages
import
Dependency
from
poetry.packages
import
Dependency
from
poetry.packages
import
DependencyPackage
from
poetry.packages
import
DirectoryDependency
from
poetry.packages
import
DirectoryDependency
from
poetry.packages
import
FileDependency
from
poetry.packages
import
FileDependency
from
poetry.packages
import
Package
from
poetry.packages
import
Package
from
poetry.packages
import
PackageCollection
from
poetry.packages
import
VCSDependency
from
poetry.packages
import
VCSDependency
from
poetry.packages
import
dependency_from_pep_508
from
poetry.packages
import
dependency_from_pep_508
...
@@ -101,10 +103,10 @@ class Provider:
...
@@ -101,10 +103,10 @@ class Provider:
order, so the latest version ought to be last.
order, so the latest version ought to be last.
"""
"""
if
dependency
.
is_root
:
if
dependency
.
is_root
:
return
[
self
.
_package
]
return
PackageCollection
(
dependency
,
[
self
.
_package
])
if
dependency
in
self
.
_search_for
:
if
dependency
in
self
.
_search_for
:
return
self
.
_search_for
[
dependency
]
return
PackageCollection
(
dependency
,
self
.
_search_for
[
dependency
])
if
dependency
.
is_vcs
():
if
dependency
.
is_vcs
():
packages
=
self
.
search_for_vcs
(
dependency
)
packages
=
self
.
search_for_vcs
(
dependency
)
...
@@ -132,7 +134,7 @@ class Provider:
...
@@ -132,7 +134,7 @@ class Provider:
self
.
_search_for
[
dependency
]
=
packages
self
.
_search_for
[
dependency
]
=
packages
return
self
.
_search_for
[
dependency
]
return
PackageCollection
(
dependency
,
self
.
_search_for
[
dependency
])
def
search_for_vcs
(
self
,
dependency
):
# type: (VCSDependency) -> List[Package]
def
search_for_vcs
(
self
,
dependency
):
# type: (VCSDependency) -> List[Package]
"""
"""
...
@@ -314,6 +316,41 @@ class Provider:
...
@@ -314,6 +316,41 @@ class Provider:
if
not
package
.
python_constraint
.
allows_all
(
if
not
package
.
python_constraint
.
allows_all
(
self
.
_package
.
python_constraint
self
.
_package
.
python_constraint
):
):
# The package Python requirement is not compatible
# with the root package python requirement.
#
# However, it should be accepted if it comes from
# a dependency with a compatible Python constraint.
#
# An example of this is:
# - The root package is compatible with Python ~2.7 || ^3.6
# - The root package depends on black for Python ^3.6
# - black is only compatible with Python >=3.6
# - black should be authorized.
#
# In this particular case, we notify the resolver that it needs
# to branch the dependency tree. What this means is if we have
# root Python ~2.7 || ^3.6 and dependency Python >=3.6
# we have to resolve for ^3.6 (>=3.6, <4.0)
if
(
not
package
.
dependency
.
python_constraint
.
is_any
()
and
not
package
.
python_constraint
.
intersect
(
package
.
dependency
.
python_constraint
)
.
is_empty
()
):
self
.
debug
(
"<warning>Found conditional dependency for {} (Python {}).</warning>"
.
format
(
package
,
package
.
dependency
.
python_constraint
)
)
raise
CompatibilityError
(
str
(
package
.
python_constraint
.
intersect
(
package
.
dependency
.
python_constraint
)
)
)
return
[
return
[
Incompatibility
(
Incompatibility
(
[
Term
(
package
.
to_dependency
(),
True
)],
[
Term
(
package
.
to_dependency
(),
True
)],
...
@@ -354,8 +391,11 @@ class Provider:
...
@@ -354,8 +391,11 @@ class Provider:
return
package
return
package
if
package
.
source_type
not
in
{
"directory"
,
"file"
,
"git"
}:
if
package
.
source_type
not
in
{
"directory"
,
"file"
,
"git"
}:
package
=
self
.
_pool
.
package
(
package
=
DependencyPackage
(
package
.
name
,
package
.
version
.
text
,
extras
=
package
.
requires_extras
package
.
dependency
,
self
.
_pool
.
package
(
package
.
name
,
package
.
version
.
text
,
extras
=
package
.
requires_extras
),
)
)
dependencies
=
[
dependencies
=
[
...
...
poetry/puzzle/solver.py
View file @
10c49e3f
...
@@ -2,6 +2,7 @@ from typing import List
...
@@ -2,6 +2,7 @@ from typing import List
from
poetry.mixology
import
resolve_version
from
poetry.mixology
import
resolve_version
from
poetry.mixology.failure
import
SolveFailure
from
poetry.mixology.failure
import
SolveFailure
from
poetry.packages
import
DependencyPackage
from
poetry.packages.constraints.generic_constraint
import
GenericConstraint
from
poetry.packages.constraints.generic_constraint
import
GenericConstraint
from
poetry.semver
import
parse_constraint
from
poetry.semver
import
parse_constraint
...
@@ -84,7 +85,7 @@ class Solver:
...
@@ -84,7 +85,7 @@ class Solver:
def
solve_in_compatibility_mode
(
self
,
constraints
,
use_latest
=
None
):
def
solve_in_compatibility_mode
(
self
,
constraints
,
use_latest
=
None
):
locked
=
{}
locked
=
{}
for
package
in
self
.
_locked
.
packages
:
for
package
in
self
.
_locked
.
packages
:
locked
[
package
.
name
]
=
package
locked
[
package
.
name
]
=
DependencyPackage
(
package
.
to_dependency
(),
package
)
packages
=
[]
packages
=
[]
depths
=
[]
depths
=
[]
...
@@ -114,7 +115,7 @@ class Solver:
...
@@ -114,7 +115,7 @@ class Solver:
def
_solve
(
self
,
use_latest
=
None
):
def
_solve
(
self
,
use_latest
=
None
):
locked
=
{}
locked
=
{}
for
package
in
self
.
_locked
.
packages
:
for
package
in
self
.
_locked
.
packages
:
locked
[
package
.
name
]
=
package
locked
[
package
.
name
]
=
DependencyPackage
(
package
.
to_dependency
(),
package
)
try
:
try
:
result
=
resolve_version
(
result
=
resolve_version
(
...
@@ -217,7 +218,9 @@ class Solver:
...
@@ -217,7 +218,9 @@ class Solver:
break
break
for
pkg
in
packages
:
for
pkg
in
packages
:
if
pkg
.
name
==
dependency
.
name
:
if
pkg
.
name
==
dependency
.
name
and
dependency
.
constraint
.
allows
(
pkg
.
version
):
# If there is already a child with this name
# If there is already a child with this name
# we merge the requirements
# we merge the requirements
existing
=
None
existing
=
None
...
...
pyproject.toml
View file @
10c49e3f
...
@@ -22,7 +22,7 @@ classifiers = [
...
@@ -22,7 +22,7 @@ classifiers = [
# Requirements
# Requirements
[tool.poetry.dependencies]
[tool.poetry.dependencies]
python
=
"~2.7 || ^3.4"
python
=
"~2.7
.9
|| ^3.4"
cleo
=
"^0.6.7"
cleo
=
"^0.6.7"
requests
=
"^2.18"
requests
=
"^2.18"
cachy
=
"^0.2"
cachy
=
"^0.2"
...
...
tests/mixology/helpers.py
View file @
10c49e3f
from
poetry.packages
import
DependencyPackage
from
poetry.packages
import
Package
from
poetry.packages
import
Package
from
poetry.mixology.failure
import
SolveFailure
from
poetry.mixology.failure
import
SolveFailure
from
poetry.mixology.version_solver
import
VersionSolver
from
poetry.mixology.version_solver
import
VersionSolver
...
@@ -18,6 +19,9 @@ def add_to_repo(repository, name, version, deps=None, python=None):
...
@@ -18,6 +19,9 @@ def add_to_repo(repository, name, version, deps=None, python=None):
def
check_solver_result
(
def
check_solver_result
(
root
,
provider
,
result
=
None
,
error
=
None
,
tries
=
None
,
locked
=
None
,
use_latest
=
None
root
,
provider
,
result
=
None
,
error
=
None
,
tries
=
None
,
locked
=
None
,
use_latest
=
None
):
):
if
locked
is
not
None
:
locked
=
{
k
:
DependencyPackage
(
l
.
to_dependency
(),
l
)
for
k
,
l
in
locked
.
items
()}
solver
=
VersionSolver
(
root
,
provider
,
locked
=
locked
,
use_latest
=
use_latest
)
solver
=
VersionSolver
(
root
,
provider
,
locked
=
locked
,
use_latest
=
use_latest
)
try
:
try
:
...
...
tests/puzzle/test_solver.py
View file @
10c49e3f
...
@@ -785,7 +785,7 @@ def test_solver_duplicate_dependencies_same_constraint(solver, repo, package):
...
@@ -785,7 +785,7 @@ def test_solver_duplicate_dependencies_same_constraint(solver, repo, package):
)
)
op
=
ops
[
0
]
op
=
ops
[
0
]
assert
op
.
package
.
requirements
==
{
"python"
:
"
>=2.7,<2.8
|| >=3.4"
}
assert
op
.
package
.
requirements
==
{
"python"
:
"
2.7
|| >=3.4"
}
def
test_solver_duplicate_dependencies_different_constraints
(
solver
,
repo
,
package
):
def
test_solver_duplicate_dependencies_different_constraints
(
solver
,
repo
,
package
):
...
@@ -962,3 +962,19 @@ def test_solver_can_resolve_git_dependencies_with_extras(solver, repo, package):
...
@@ -962,3 +962,19 @@ def test_solver_can_resolve_git_dependencies_with_extras(solver, repo, package):
{
"job"
:
"install"
,
"package"
:
get_package
(
"demo"
,
"0.1.2"
)},
{
"job"
:
"install"
,
"package"
:
get_package
(
"demo"
,
"0.1.2"
)},
],
],
)
)
def
test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requirement_is_compatible
(
solver
,
repo
,
package
):
package
.
python_versions
=
"~2.7 || ^3.6"
package
.
add_dependency
(
"A"
,
{
"version"
:
"^1.0"
,
"python"
:
"^3.6"
})
package_a
=
get_package
(
"A"
,
"1.0.0"
)
package_a
.
python_versions
=
">=3.6"
repo
.
add_package
(
package_a
)
ops
=
solver
.
solve
()
check_solver_result
(
ops
,
[{
"job"
:
"install"
,
"package"
:
package_a
}])
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment