Commit 5fcdb369 by Arun Babu Neelicattu Committed by GitHub

exporter: handle dev extras correctly (#3038)

Resolves: #3018
parent 3611523f
......@@ -182,9 +182,9 @@ class Locker(object):
return packages
def get_project_dependencies(
self, project_requires, pinned_versions=False, with_nested=False
): # type: (List[Dependency], bool, bool) -> Any
packages = self.locked_repository().packages
self, project_requires, pinned_versions=False, with_nested=False, with_dev=False
): # type: (List[Dependency], bool, bool, bool) -> Any
packages = self.locked_repository(with_dev).packages
# group packages entries by name, this is required because requirement might use
# different constraints
......@@ -230,6 +230,10 @@ class Locker(object):
# project level dependencies take precedence
continue
# we make a copy to avoid any side-effects
requirement = deepcopy(requirement)
requirement._category = pkg.category
if pinned_versions:
requirement.set_constraint(
__get_locked_package(requirement).to_dependency().constraint
......
......@@ -68,12 +68,14 @@ class Exporter(object):
dependency_lines = set()
for dependency in self._poetry.locker.get_project_dependencies(
project_requires=self._poetry.package.requires
if not dev
else self._poetry.package.all_requires,
project_requires=self._poetry.package.all_requires,
with_nested=True,
with_dev=dev,
):
package = repository.find_packages(dependency=dependency)[0]
try:
package = repository.find_packages(dependency=dependency)[0]
except IndexError:
continue
# If a package is optional and we haven't opted in to it, continue
if package.optional and package.name not in extra_package_names:
......
......@@ -779,6 +779,68 @@ foo==1.2.3 \\
assert expected == content
@pytest.mark.parametrize(
("dev", "expected"),
[
(True, ["bar==1.2.2", "baz==1.2.3", "foo==1.2.1"]),
(False, ["bar==1.2.2", "foo==1.2.1"]),
],
)
def test_exporter_exports_requirements_txt_with_dev_extras(
tmp_dir, poetry, dev, expected
):
poetry.locker.mock_lock_data(
{
"package": [
{
"name": "foo",
"version": "1.2.1",
"category": "main",
"optional": False,
"python-versions": "*",
},
{
"name": "bar",
"version": "1.2.2",
"category": "main",
"optional": False,
"python-versions": "*",
"dependencies": {
"baz": {
"version": ">=0.1.0",
"optional": True,
"markers": "extra == 'baz'",
}
},
"extras": {"baz": ["baz (>=0.1.0)"]},
},
{
"name": "baz",
"version": "1.2.3",
"category": "dev",
"optional": False,
"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", dev=dev)
with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
assert content == "{}\n".format("\n".join(expected))
def test_exporter_exports_requirements_txt_with_legacy_packages_and_duplicate_sources(
tmp_dir, poetry
):
......
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