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
d6289470
Unverified
Commit
d6289470
authored
Jul 10, 2020
by
Sébastien Eustace
Committed by
GitHub
Jul 10, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use the proper main Python constraint when resolving for installation (#2625)
parent
feef53be
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
73 additions
and
28 deletions
+73
-28
poetry/puzzle/provider.py
+9
-7
poetry/puzzle/solver.py
+8
-2
poetry/utils/env.py
+1
-0
tests/mixology/version_solver/conftest.py
+7
-1
tests/mixology/version_solver/test_python_constraint.py
+2
-2
tests/puzzle/test_solver.py
+46
-16
No files found.
poetry/puzzle/provider.py
View file @
d6289470
...
...
@@ -18,6 +18,7 @@ from poetry.core.packages import Package
from
poetry.core.packages
import
URLDependency
from
poetry.core.packages
import
VCSDependency
from
poetry.core.packages.utils.utils
import
get_python_constraint_from_marker
from
poetry.core.semver.version
import
Version
from
poetry.core.vcs.git
import
Git
from
poetry.core.version.markers
import
MarkerUnion
from
poetry.inspection.info
import
PackageInfo
...
...
@@ -80,12 +81,15 @@ class Provider:
@contextmanager
def
use_environment
(
self
,
env
):
# type: (Env) -> Provider
original_env
=
self
.
_env
original_python_constraint
=
self
.
_python_constraint
self
.
_env
=
env
self
.
_python_constraint
=
Version
.
parse
(
env
.
marker_env
[
"python_full_version"
])
yield
self
self
.
_env
=
original_env
self
.
_python_constraint
=
original_python_constraint
def
search_for
(
self
,
dependency
):
# type: (Dependency) -> List[Package]
"""
...
...
@@ -380,9 +384,7 @@ class Provider:
else
:
dependencies
=
package
.
requires
if
not
package
.
python_constraint
.
allows_all
(
self
.
_package
.
python_constraint
):
if
not
package
.
python_constraint
.
allows_all
(
self
.
_python_constraint
):
transitive_python_constraint
=
get_python_constraint_from_marker
(
package
.
dependency
.
transitive_marker
)
...
...
@@ -392,7 +394,7 @@ class Provider:
difference
=
transitive_python_constraint
.
difference
(
intersection
)
if
(
transitive_python_constraint
.
is_any
()
or
self
.
_p
ackage
.
p
ython_constraint
.
intersect
(
or
self
.
_python_constraint
.
intersect
(
package
.
dependency
.
python_constraint
)
.
is_empty
()
or
intersection
.
is_empty
()
...
...
@@ -402,7 +404,7 @@ class Provider:
Incompatibility
(
[
Term
(
package
.
to_dependency
(),
True
)],
PythonCause
(
package
.
python_versions
,
s
elf
.
_package
.
python_versions
package
.
python_versions
,
s
tr
(
self
.
_python_constraint
)
),
)
]
...
...
@@ -411,7 +413,7 @@ class Provider:
dep
for
dep
in
dependencies
if
dep
.
name
not
in
self
.
UNSAFE_PACKAGES
and
self
.
_p
ackage
.
p
ython_constraint
.
allows_any
(
dep
.
python_constraint
)
and
self
.
_python_constraint
.
allows_any
(
dep
.
python_constraint
)
and
(
not
self
.
_env
or
dep
.
marker
.
validate
(
self
.
_env
.
marker_env
))
]
...
...
@@ -477,7 +479,7 @@ class Provider:
_dependencies
=
[
r
for
r
in
requires
if
self
.
_p
ackage
.
p
ython_constraint
.
allows_any
(
r
.
python_constraint
)
if
self
.
_python_constraint
.
allows_any
(
r
.
python_constraint
)
and
r
.
name
not
in
self
.
UNSAFE_PACKAGES
and
(
not
self
.
_env
or
r
.
marker
.
validate
(
self
.
_env
.
marker_env
))
]
...
...
poetry/puzzle/solver.py
View file @
d6289470
...
...
@@ -4,6 +4,7 @@ from contextlib import contextmanager
from
typing
import
Any
from
typing
import
Dict
from
typing
import
List
from
typing
import
Optional
from
clikit.io
import
ConsoleIO
...
...
@@ -33,14 +34,19 @@ class Solver:
installed
,
# type: Repository
locked
,
# type: Repository
io
,
# type: ConsoleIO
remove_untracked
=
False
,
# type: bool
remove_untracked
=
False
,
# type: bool,
provider
=
None
,
# type: Optional[Provider]
):
self
.
_package
=
package
self
.
_pool
=
pool
self
.
_installed
=
installed
self
.
_locked
=
locked
self
.
_io
=
io
self
.
_provider
=
Provider
(
self
.
_package
,
self
.
_pool
,
self
.
_io
)
if
provider
is
None
:
provider
=
Provider
(
self
.
_package
,
self
.
_pool
,
self
.
_io
)
self
.
_provider
=
provider
self
.
_overrides
=
[]
self
.
_remove_untracked
=
remove_untracked
...
...
poetry/utils/env.py
View file @
d6289470
...
...
@@ -1238,6 +1238,7 @@ class MockEnv(NullEnv):
marker_env
[
"python_implementation"
]
=
self
.
_python_implementation
marker_env
[
"version_info"
]
=
self
.
_version_info
marker_env
[
"python_version"
]
=
"."
.
join
(
str
(
v
)
for
v
in
self
.
_version_info
[:
2
])
marker_env
[
"python_full_version"
]
=
"."
.
join
(
str
(
v
)
for
v
in
self
.
_version_info
)
marker_env
[
"sys_platform"
]
=
self
.
_platform
return
marker_env
...
...
tests/mixology/version_solver/conftest.py
View file @
d6289470
...
...
@@ -3,11 +3,17 @@ import pytest
from
clikit.io
import
NullIO
from
poetry.core.packages.project_package
import
ProjectPackage
from
poetry.puzzle.provider
import
Provider
from
poetry.puzzle.provider
import
Provider
as
BaseProvider
from
poetry.repositories
import
Pool
from
poetry.repositories
import
Repository
class
Provider
(
BaseProvider
):
def
set_package_python_versions
(
self
,
python_versions
):
self
.
_package
.
python_versions
=
python_versions
self
.
_python_constraint
=
self
.
_package
.
python_constraint
@pytest.fixture
def
repo
():
return
Repository
()
...
...
tests/mixology/version_solver/test_python_constraint.py
View file @
d6289470
...
...
@@ -3,12 +3,12 @@ from ..helpers import check_solver_result
def
test_dependency_does_not_match_root_python_constraint
(
root
,
provider
,
repo
):
root
.
python_versions
=
"^3.6"
provider
.
set_package_python_versions
(
"^3.6"
)
root
.
add_dependency
(
"foo"
,
"*"
)
add_to_repo
(
repo
,
"foo"
,
"1.0.0"
,
python
=
"<3.5"
)
error
=
"""The current project's Python requirement (
^3.6
)
\
error
=
"""The current project's Python requirement (
>=3.6,<4.0
)
\
is not compatible with some of the required packages Python requirement:
- foo requires Python <3.5, so it will not be satisfied for Python >=3.6,<4.0
...
...
tests/puzzle/test_solver.py
View file @
d6289470
...
...
@@ -7,10 +7,12 @@ from poetry.core.packages import dependency_from_pep_508
from
poetry.core.version.markers
import
parse_marker
from
poetry.puzzle
import
Solver
from
poetry.puzzle.exceptions
import
SolverProblemError
from
poetry.puzzle.provider
import
Provider
as
BaseProvider
from
poetry.repositories.installed_repository
import
InstalledRepository
from
poetry.repositories.pool
import
Pool
from
poetry.repositories.repository
import
Repository
from
poetry.utils._compat
import
Path
from
poetry.utils.env
import
MockEnv
from
tests.helpers
import
get_dependency
from
tests.helpers
import
get_package
from
tests.repositories.test_legacy_repository
import
(
...
...
@@ -19,6 +21,12 @@ from tests.repositories.test_legacy_repository import (
from
tests.repositories.test_pypi_repository
import
MockRepository
as
MockPyPIRepository
class
Provider
(
BaseProvider
):
def
set_package_python_versions
(
self
,
python_versions
):
self
.
_package
.
python_versions
=
python_versions
self
.
_python_constraint
=
self
.
_package
.
python_constraint
@pytest.fixture
()
def
io
():
return
NullIO
()
...
...
@@ -51,7 +59,9 @@ def pool(repo):
@pytest.fixture
()
def
solver
(
package
,
pool
,
installed
,
locked
,
io
):
return
Solver
(
package
,
pool
,
installed
,
locked
,
io
)
return
Solver
(
package
,
pool
,
installed
,
locked
,
io
,
provider
=
Provider
(
package
,
pool
,
io
)
)
def
check_solver_result
(
ops
,
expected
):
...
...
@@ -295,7 +305,7 @@ def test_solver_sets_categories(solver, repo, package):
def
test_solver_respects_root_package_python_versions
(
solver
,
repo
,
package
):
package
.
python_versions
=
"~3.4"
solver
.
provider
.
set_package_python_versions
(
"~3.4"
)
package
.
add_dependency
(
"A"
)
package
.
add_dependency
(
"B"
)
...
...
@@ -326,7 +336,7 @@ def test_solver_respects_root_package_python_versions(solver, repo, package):
def
test_solver_fails_if_mismatch_root_python_versions
(
solver
,
repo
,
package
):
package
.
python_versions
=
"^3.4"
solver
.
provider
.
set_package_python_versions
(
"^3.4"
)
package
.
add_dependency
(
"A"
)
package
.
add_dependency
(
"B"
)
...
...
@@ -346,7 +356,7 @@ def test_solver_fails_if_mismatch_root_python_versions(solver, repo, package):
def
test_solver_solves_optional_and_compatible_packages
(
solver
,
repo
,
package
):
package
.
python_versions
=
"~3.4"
solver
.
provider
.
set_package_python_versions
(
"~3.4"
)
package
.
extras
[
"foo"
]
=
[
get_dependency
(
"B"
)]
package
.
add_dependency
(
"A"
,
{
"version"
:
"*"
,
"python"
:
"^3.4"
})
package
.
add_dependency
(
"B"
,
{
"version"
:
"*"
,
"optional"
:
True
})
...
...
@@ -563,7 +573,7 @@ def test_solver_sub_dependencies_with_requirements_complex(solver, repo, package
def
test_solver_sub_dependencies_with_not_supported_python_version
(
solver
,
repo
,
package
):
package
.
python_versions
=
"^3.5"
solver
.
provider
.
set_package_python_versions
(
"^3.5"
)
package
.
add_dependency
(
"A"
)
package_a
=
get_package
(
"A"
,
"1.0"
)
...
...
@@ -583,7 +593,7 @@ def test_solver_sub_dependencies_with_not_supported_python_version(
def
test_solver_with_dependency_in_both_main_and_dev_dependencies
(
solver
,
repo
,
package
):
package
.
python_versions
=
"^3.5"
solver
.
provider
.
set_package_python_versions
(
"^3.5"
)
package
.
add_dependency
(
"A"
)
package
.
add_dependency
(
"A"
,
{
"version"
:
"*"
,
"extras"
:
[
"foo"
]},
category
=
"dev"
)
...
...
@@ -962,7 +972,7 @@ def test_solver_can_resolve_git_dependencies_with_ref(solver, repo, package, ref
def
test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requirement_is_compatible
(
solver
,
repo
,
package
):
package
.
python_versions
=
"~2.7 || ^3.4"
solver
.
provider
.
set_package_python_versions
(
"~2.7 || ^3.4"
)
package
.
add_dependency
(
"A"
,
{
"version"
:
"^1.0"
,
"python"
:
"^3.6"
})
package_a
=
get_package
(
"A"
,
"1.0.0"
)
...
...
@@ -978,7 +988,7 @@ def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requir
def
test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requirement_is_compatible_multiple
(
solver
,
repo
,
package
):
package
.
python_versions
=
"~2.7 || ^3.4"
solver
.
provider
.
set_package_python_versions
(
"~2.7 || ^3.4"
)
package
.
add_dependency
(
"A"
,
{
"version"
:
"^1.0"
,
"python"
:
"^3.6"
})
package
.
add_dependency
(
"B"
,
{
"version"
:
"^1.0"
,
"python"
:
"^3.5.3"
})
...
...
@@ -1006,7 +1016,7 @@ def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requir
def
test_solver_triggers_conflict_for_dependency_python_not_fully_compatible_with_package_python
(
solver
,
repo
,
package
):
package
.
python_versions
=
"~2.7 || ^3.4"
solver
.
provider
.
set_package_python_versions
(
"~2.7 || ^3.4"
)
package
.
add_dependency
(
"A"
,
{
"version"
:
"^1.0"
,
"python"
:
"^3.5"
})
package_a
=
get_package
(
"A"
,
"1.0.0"
)
...
...
@@ -1021,7 +1031,7 @@ def test_solver_triggers_conflict_for_dependency_python_not_fully_compatible_wit
def
test_solver_finds_compatible_package_for_dependency_python_not_fully_compatible_with_package_python
(
solver
,
repo
,
package
):
package
.
python_versions
=
"~2.7 || ^3.4"
solver
.
provider
.
set_package_python_versions
(
"~2.7 || ^3.4"
)
package
.
add_dependency
(
"A"
,
{
"version"
:
"^1.0"
,
"python"
:
"^3.5"
})
package_a101
=
get_package
(
"A"
,
"1.0.1"
)
...
...
@@ -1077,7 +1087,7 @@ def test_solver_does_not_trigger_new_resolution_on_duplicate_dependencies_if_onl
def
test_solver_does_not_raise_conflict_for_locked_conditional_dependencies
(
solver
,
repo
,
package
):
package
.
python_versions
=
"~2.7 || ^3.4"
solver
.
provider
.
set_package_python_versions
(
"~2.7 || ^3.4"
)
package
.
add_dependency
(
"A"
,
{
"version"
:
"^1.0"
,
"python"
:
"^3.6"
})
package
.
add_dependency
(
"B"
,
"^1.0"
)
...
...
@@ -1161,7 +1171,7 @@ def test_solver_should_not_resolve_prerelease_version_if_not_requested(
def
test_solver_ignores_dependencies_with_incompatible_python_full_version_marker
(
solver
,
repo
,
package
):
package
.
python_versions
=
"^3.6"
solver
.
provider
.
set_package_python_versions
(
"^3.6"
)
package
.
add_dependency
(
"A"
,
"^1.0"
)
package
.
add_dependency
(
"B"
,
"^2.0"
)
...
...
@@ -1729,7 +1739,7 @@ def test_solver_discards_packages_with_empty_markers(
def
test_solver_does_not_raise_conflict_for_conditional_dev_dependencies
(
solver
,
repo
,
package
):
package
.
python_versions
=
"~2.7 || ^3.5"
solver
.
provider
.
set_package_python_versions
(
"~2.7 || ^3.5"
)
package
.
add_dependency
(
"A"
,
{
"version"
:
"^1.0"
,
"python"
:
"~2.7"
},
category
=
"dev"
)
package
.
add_dependency
(
"A"
,
{
"version"
:
"^2.0"
,
"python"
:
"^3.5"
},
category
=
"dev"
)
...
...
@@ -1753,7 +1763,7 @@ def test_solver_does_not_raise_conflict_for_conditional_dev_dependencies(
def
test_solver_does_not_loop_indefinitely_on_duplicate_constraints_with_extras
(
solver
,
repo
,
package
):
package
.
python_versions
=
"~2.7 || ^3.5"
solver
.
provider
.
set_package_python_versions
(
"~2.7 || ^3.5"
)
package
.
add_dependency
(
"requests"
,
{
"version"
:
"^2.22.0"
,
"extras"
:
[
"security"
]})
requests
=
get_package
(
"requests"
,
"2.22.0"
)
...
...
@@ -1825,7 +1835,7 @@ def test_ignore_python_constraint_no_overlap_dependencies(solver, repo, package)
def
test_solver_should_not_go_into_an_infinite_loop_on_duplicate_dependencies
(
solver
,
repo
,
package
):
package
.
python_versions
=
"~2.7 || ^3.5"
solver
.
provider
.
set_package_python_versions
(
"~2.7 || ^3.5"
)
package
.
add_dependency
(
"A"
,
"^1.0"
)
package_a
=
get_package
(
"A"
,
"1.0.0"
)
...
...
@@ -2000,8 +2010,28 @@ def test_solver_should_not_update_same_version_packages_if_installed_has_no_sour
ops
=
solver
.
solve
()
check_solver_result
(
ops
,
[{
"job"
:
"install"
,
"package"
:
foo
,
"skipped"
:
True
}])
def
test_solver_should_use_the_python_constraint_from_the_environment_if_available
(
solver
,
repo
,
package
,
installed
):
solver
.
provider
.
set_package_python_versions
(
"~2.7 || ^3.5"
)
package
.
add_dependency
(
"A"
,
"^1.0"
)
a
=
get_package
(
"A"
,
"1.0.0"
)
a
.
add_dependency
(
"B"
,
{
"version"
:
"^1.0.0"
,
"markers"
:
'python_version < "3.2"'
})
b
=
get_package
(
"B"
,
"1.0.0"
)
b
.
python_versions
=
">=2.6, <3"
repo
.
add_package
(
a
)
repo
.
add_package
(
b
)
with
solver
.
use_environment
(
MockEnv
((
2
,
7
,
18
))):
ops
=
solver
.
solve
()
check_solver_result
(
ops
,
[{
"job"
:
"install"
,
"package"
:
foo
,
"skipped"
:
True
}],
ops
,
[{
"job"
:
"install"
,
"package"
:
b
},
{
"job"
:
"install"
,
"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