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
e878a5d4
Commit
e878a5d4
authored
Oct 18, 2020
by
Arun Babu Neelicattu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
locker: handle cyclic dependencies during walk
Resolves: #3213
parent
89e1d7c1
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
75 additions
and
21 deletions
+75
-21
poetry/packages/locker.py
+19
-21
tests/utils/test_exporter.py
+56
-0
No files found.
poetry/packages/locker.py
View file @
e878a5d4
...
@@ -226,14 +226,31 @@ class Locker(object):
...
@@ -226,14 +226,31 @@ class Locker(object):
next_level_dependencies
=
[]
next_level_dependencies
=
[]
for
requirement
in
dependencies
:
for
requirement
in
dependencies
:
key
=
(
requirement
.
name
,
requirement
.
pretty_constraint
)
locked_package
=
cls
.
__get_locked_package
(
requirement
,
packages_by_name
)
locked_package
=
cls
.
__get_locked_package
(
requirement
,
packages_by_name
)
if
locked_package
:
if
locked_package
:
# create dependency from locked package to retain dependency metadata
# if this is not done, we can end-up with incorrect nested dependencies
marker
=
requirement
.
marker
requirement
=
locked_package
.
to_dependency
()
requirement
.
marker
=
requirement
.
marker
.
intersect
(
marker
)
key
=
(
requirement
.
name
,
requirement
.
pretty_constraint
)
if
pinned_versions
:
requirement
.
set_constraint
(
locked_package
.
to_dependency
()
.
constraint
)
if
key
not
in
nested_dependencies
:
for
require
in
locked_package
.
requires
:
for
require
in
locked_package
.
requires
:
if
require
.
marker
.
is_empty
():
if
require
.
marker
.
is_empty
():
require
.
marker
=
requirement
.
marker
require
.
marker
=
requirement
.
marker
else
:
else
:
require
.
marker
=
require
.
marker
.
intersect
(
requirement
.
marker
)
require
.
marker
=
require
.
marker
.
intersect
(
requirement
.
marker
)
require
.
marker
=
require
.
marker
.
intersect
(
locked_package
.
marker
)
require
.
marker
=
require
.
marker
.
intersect
(
locked_package
.
marker
)
next_level_dependencies
.
append
(
require
)
next_level_dependencies
.
append
(
require
)
...
@@ -242,29 +259,10 @@ class Locker(object):
...
@@ -242,29 +259,10 @@ class Locker(object):
# project level dependencies take precedence
# project level dependencies take precedence
continue
continue
if
locked_package
:
if
not
locked_package
:
# create dependency from locked package to retain dependency metadata
# if this is not done, we can end-up with incorrect nested dependencies
marker
=
requirement
.
marker
requirement
=
locked_package
.
to_dependency
()
requirement
.
marker
=
requirement
.
marker
.
intersect
(
marker
)
else
:
# we make a copy to avoid any side-effects
# we make a copy to avoid any side-effects
requirement
=
deepcopy
(
requirement
)
requirement
=
deepcopy
(
requirement
)
if
pinned_versions
:
requirement
.
set_constraint
(
cls
.
__get_locked_package
(
requirement
,
packages_by_name
)
.
to_dependency
()
.
constraint
)
# dependencies use extra to indicate that it was activated via parent
# package's extras, this is not required for nested exports as we assume
# the resolver already selected this dependency
requirement
.
marker
=
requirement
.
marker
.
without_extras
()
key
=
(
requirement
.
name
,
requirement
.
pretty_constraint
)
if
key
not
in
nested_dependencies
:
if
key
not
in
nested_dependencies
:
nested_dependencies
[
key
]
=
requirement
nested_dependencies
[
key
]
=
requirement
else
:
else
:
...
...
tests/utils/test_exporter.py
View file @
e878a5d4
...
@@ -696,6 +696,62 @@ foo @ git+https://github.com/foo/foo.git@123456
...
@@ -696,6 +696,62 @@ foo @ git+https://github.com/foo/foo.git@123456
assert
expected
==
content
assert
expected
==
content
def
test_exporter_can_export_requirements_txt_with_nested_packages_cyclic
(
tmp_dir
,
poetry
):
poetry
.
locker
.
mock_lock_data
(
{
"package"
:
[
{
"name"
:
"foo"
,
"version"
:
"1.2.3"
,
"category"
:
"main"
,
"optional"
:
False
,
"python-versions"
:
"*"
,
"dependencies"
:
{
"bar"
:
{
"version"
:
"4.5.6"
}},
},
{
"name"
:
"bar"
,
"version"
:
"4.5.6"
,
"category"
:
"main"
,
"optional"
:
False
,
"python-versions"
:
"*"
,
"dependencies"
:
{
"baz"
:
{
"version"
:
"7.8.9"
}},
},
{
"name"
:
"baz"
,
"version"
:
"7.8.9"
,
"category"
:
"main"
,
"optional"
:
False
,
"python-versions"
:
"*"
,
"dependencies"
:
{
"foo"
:
{
"version"
:
"1.2.3"
}},
},
],
"metadata"
:
{
"python-versions"
:
"*"
,
"content-hash"
:
"123456789"
,
"hashes"
:
{
"foo"
:
[],
"bar"
:
[],
"baz"
:
[]},
},
}
)
set_package_requires
(
poetry
,
skip
=
{
"bar"
,
"baz"
})
exporter
=
Exporter
(
poetry
)
exporter
.
export
(
"requirements.txt"
,
Path
(
tmp_dir
),
"requirements.txt"
)
with
(
Path
(
tmp_dir
)
/
"requirements.txt"
)
.
open
(
encoding
=
"utf-8"
)
as
f
:
content
=
f
.
read
()
expected
=
"""
\
bar==4.5.6
baz==7.8.9
foo==1.2.3
"""
assert
expected
==
content
def
test_exporter_can_export_requirements_txt_with_git_packages_and_markers
(
def
test_exporter_can_export_requirements_txt_with_git_packages_and_markers
(
tmp_dir
,
poetry
tmp_dir
,
poetry
):
):
...
...
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