From c241e7894f34412e6374c19bada3d72be8ab8d55 Mon Sep 17 00:00:00 2001 From: finswimmer Date: Sat, 27 Nov 2021 15:04:33 +0100 Subject: [PATCH] Fix dropped markers in dependency walk This is a backport of #4686. Note that the test is changed due to a regression in `master` -- somewhere, the ability to drop two markers that negate each other was lost. Co-authored-by: Bjorn Neergaard --- poetry/packages/locker.py | 17 ++++----- tests/utils/test_exporter.py | 73 ++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/poetry/packages/locker.py b/poetry/packages/locker.py index 586eae8da1a..68ba611d48a 100644 --- a/poetry/packages/locker.py +++ b/poetry/packages/locker.py @@ -245,16 +245,15 @@ def __walk_dependency_level( locked_package.to_dependency().constraint ) - if key not in nested_dependencies: - for require in locked_package.requires: - if require.marker.is_empty(): - require.marker = requirement.marker - else: - require.marker = require.marker.intersect( - requirement.marker - ) + for require in locked_package.requires: + if require.marker.is_empty(): + require.marker = requirement.marker + else: + require.marker = require.marker.intersect(requirement.marker) + + require.marker = require.marker.intersect(locked_package.marker) - require.marker = require.marker.intersect(locked_package.marker) + if key not in nested_dependencies: next_level_dependencies.append(require) if requirement.name in project_level_dependencies and level == 0: diff --git a/tests/utils/test_exporter.py b/tests/utils/test_exporter.py index 2082bd23181..6cae992844f 100644 --- a/tests/utils/test_exporter.py +++ b/tests/utils/test_exporter.py @@ -752,6 +752,79 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_cyclic( assert expected == content +def test_exporter_can_export_requirements_txt_with_nested_packages_and_multiple_markers( + tmp_dir, poetry +): + poetry.locker.mock_lock_data( + { + "package": [ + { + "name": "foo", + "version": "1.2.3", + "category": "main", + "optional": False, + "python-versions": "*", + "dependencies": { + "bar": [ + { + "version": ">=1.2.3,<7.8.10", + "markers": 'platform_system != "Windows"', + }, + { + "version": ">=4.5.6,<7.8.10", + "markers": 'platform_system == "Windows"', + }, + ] + }, + }, + { + "name": "bar", + "version": "7.8.9", + "category": "main", + "optional": True, + "python-versions": "*", + "dependencies": { + "baz": { + "version": "!=10.11.12", + "markers": 'platform_system == "Windows"', + } + }, + }, + { + "name": "baz", + "version": "10.11.13", + "category": "main", + "optional": True, + "python-versions": "*", + }, + ], + "metadata": { + "python-versions": "*", + "content-hash": "123456789", + "hashes": {"foo": [], "bar": [], "baz": []}, + }, + } + ) + set_package_requires(poetry) + + exporter = Exporter(poetry) + + exporter.export( + "requirements.txt", Path(tmp_dir), "requirements.txt", with_hashes=False + ) + + with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f: + content = f.read() + + expected = """\ +bar==7.8.9 +baz==10.11.13; platform_system == "Windows" +foo==1.2.3 +""" + + assert expected == content + + def test_exporter_can_export_requirements_txt_with_git_packages_and_markers( tmp_dir, poetry ):