Skip to content

Commit

Permalink
fix: do not ignore dynamic project dependencies via `tool.poetry.depe…
Browse files Browse the repository at this point in the history
…ndencies` if `project.optional-dependencies` are defined
  • Loading branch information
radoering committed Jan 10, 2025
1 parent 6243e3f commit 8b66b86
Show file tree
Hide file tree
Showing 23 changed files with 290 additions and 37 deletions.
17 changes: 15 additions & 2 deletions src/poetry/core/packages/dependency_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,20 @@ def name(self) -> str:

@property
def dependencies(self) -> list[Dependency]:
return self._dependencies or self._poetry_dependencies
if not self._dependencies:
return self._poetry_dependencies
if self._poetry_dependencies:
if all(dep.is_optional() for dep in self._dependencies):
return [
*self._dependencies,
*(d for d in self._poetry_dependencies if not d.is_optional()),
]
if all(not dep.is_optional() for dep in self._dependencies):
return [
*self._dependencies,
*(d for d in self._poetry_dependencies if d.is_optional()),
]
return self._dependencies

@property
def dependencies_for_locking(self) -> list[Dependency]:
Expand All @@ -40,7 +53,7 @@ def dependencies_for_locking(self) -> list[Dependency]:
poetry_dependencies_by_name[dep.name].append(dep)

dependencies = []
for dep in self._dependencies:
for dep in self.dependencies:
if dep.name in poetry_dependencies_by_name:
enriched = False
dep_marker = dep.marker
Expand Down
2 changes: 2 additions & 0 deletions tests/fixtures/sample_project_dynamic/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
My Package
==========
83 changes: 83 additions & 0 deletions tests/fixtures/sample_project_dynamic/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
[project]
name = "my-package"
version = "1.2.3"
description = "Some description."
readme = "README.rst"
requires-python = ">=3.6"
license = { text = "MIT" }
keywords = ["packaging", "dependency", "poetry"]
authors = [
{ name = "Sébastien Eustace", email = "sebastien@eustace.io" }
]
maintainers = [
{ name = "Sébastien Eustace", email = "sebastien@eustace.io" }
]
dynamic = [ "version", "readme", "dependencies", "classifiers" ]

[project.optional-dependencies]
db = [
"orator ~=0.9"
]
network = [
"requests[security] ~=2.18"
]

[project.urls]
homepage = "https://python-poetry.org"
repository = "/~https://github.com/python-poetry/poetry"
documentation = "https://python-poetry.org/docs"

[project.scripts]
my-script = "my_package:main"

[tool.poetry]
version = "1.2.3"
readme = "README.rst"
classifiers = [
"Topic :: Software Development :: Build Tools",
"Topic :: Software Development :: Libraries :: Python Modules"
]

# Requirements
[tool.poetry.dependencies]
python = ">=3.6"
cleo = "^0.6"
pendulum = { git = "/~https://github.com/sdispater/pendulum.git", branch = "2.0" }
tomlkit = { git = "/~https://github.com/sdispater/tomlkit.git", rev = "3bff550", develop = true }
pathlib2 = { version = "^2.2", python = "~2.7" }

# File dependency
demo = { path = "../distributions/demo-0.1.0-py2.py3-none-any.whl" }

# Dir dependency with setup.py
my-package = { path = "../project_with_setup/" }

# Dir dependency with pyproject.toml
simple-project = { path = "../simple_project/" }

# Dependency with markers
functools32 = { version = "^3.2.3", markers = "python_version ~= '2.7' and sys_platform == 'win32' or python_version in '3.4 3.5'" }

# Dependency with python constraint
dataclasses = { version = "^0.7", python = ">=3.6.1,<3.7" }


# Non-regression test for /~https://github.com/python-poetry/poetry-core/pull/492.
# The underlying issue occurred because `tomlkit` can either return a TOML table as `Table` instance or an
# `OutOfOrderProxy` one, if a table is discontinuous and multiple sections of a table are separated by a non-related
# table, but we were too strict in our type check assertions.
# So adding `tool.black` here ensure that we have discontinuous tables, so that we don't re-introduce the issue caused
# by the type check assertion that ended up being reverted.
[tool.black]
preview = true

[tool.poetry.group.dev.dependencies]
pytest = "~3.4"


[tool.poetry.scripts]
my-script = "my_package:main"


[tool.poetry.plugins."blogtool.parsers"]
".rst" = "some_module::SomeClass"
Empty file.
Empty file.
Empty file.
20 changes: 20 additions & 0 deletions tests/masonry/builders/fixtures/complete_dynamic/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2018 Sébastien Eustace

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2 changes: 2 additions & 0 deletions tests/masonry/builders/fixtures/complete_dynamic/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
My Package
==========
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

echo "Hello World!"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "1.2.3"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Empty file.
62 changes: 62 additions & 0 deletions tests/masonry/builders/fixtures/complete_dynamic/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
[project]
name = "my-package"
version = "1.2.3"
description = "Some description."
requires-python = ">=3.6,<4.0"
license = { "text" = "MIT" }
authors = [
{ "name" = "Sébastien Eustace", "email" = "sebastien@eustace.io" }
]
maintainers = [
{ name = "People Everywhere", email = "people@everywhere.com" }
]
keywords = ["packaging", "dependency", "poetry"]
dynamic = [ "version", "classifiers", "readme", "dependencies" ]

[project.optional-dependencies]
time = [ "pendulum>=1.4,<2.0 ; python_version ~= '2.7' and sys_platform == 'win32' or python_version in '3.4 3.5'" ]

[project.urls]
homepage = "https://python-poetry.org/"
repository = "/~https://github.com/python-poetry/poetry"
documentation = "https://python-poetry.org/docs"
"Issue Tracker" = "/~https://github.com/python-poetry/poetry/issues"

[project.scripts]
my-script = "my_package:main"
my-2nd-script = "my_package:main2"
extra-script = "my_package.extra:main"

[project.entry-points."poetry.application.plugin"]
my-command = "my_package.plugins:MyApplicationPlugin"


[tool.poetry]
version = "1.2.3"
readme = "README.rst"

classifiers = [
"Topic :: Software Development :: Build Tools",
"Topic :: Software Development :: Libraries :: Python Modules"
]

exclude = [
"does-not-exist",
"**/*.xml"
]

# Requirements
[tool.poetry.dependencies]
cleo = "^0.6"
cachy = { version = "^0.2.0", extras = ["msgpack"] }

[tool.poetry.dependencies.pendulum]
version = "^1.4"
markers = 'python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5"'
optional = true

[tool.poetry.group.dev.dependencies]
pytest = "~3.4"

[tool.poetry.scripts]
file-script = { reference = "bin/script.sh", type = "file" }
2 changes: 1 addition & 1 deletion tests/masonry/builders/test_complete.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def test_wheel_c_extension(project: str, exptected_c_dir: str) -> None:
assert len(set(record_files)) == len(record_files)


@pytest.mark.parametrize("project", ["complete", "complete_new"])
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
@pytest.mark.parametrize("no_vcs", [False, True])
def test_complete(project: str, no_vcs: bool) -> None:
module_path = fixtures_dir / project
Expand Down
28 changes: 21 additions & 7 deletions tests/masonry/builders/test_sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ def test_convert_dependencies() -> None:
assert result == (main, extras)


@pytest.mark.parametrize("project_name", ["complete", "complete_new"])
@pytest.mark.parametrize(
"project_name", ["complete", "complete_new", "complete_dynamic"]
)
def test_make_setup(project_name: str) -> None:
poetry = Factory().create_poetry(project(project_name))

Expand Down Expand Up @@ -156,7 +158,9 @@ def test_make_setup(project_name: str) -> None:
}


@pytest.mark.parametrize("project_name", ["complete", "complete_new"])
@pytest.mark.parametrize(
"project_name", ["complete", "complete_new", "complete_dynamic"]
)
def test_make_pkg_info(project_name: str, mocker: MockerFixture) -> None:
get_metadata_content = mocker.patch(
"poetry.core.masonry.builders.builder.Builder.get_metadata_content"
Expand All @@ -180,7 +184,9 @@ def test_make_pkg_info_any_python() -> None:
assert "Requires-Python" not in parsed


@pytest.mark.parametrize("project_name", ["complete", "complete_new"])
@pytest.mark.parametrize(
"project_name", ["complete", "complete_new", "complete_dynamic"]
)
def test_find_files_to_add(project_name: str) -> None:
poetry = Factory().create_poetry(project(project_name))

Expand Down Expand Up @@ -239,7 +245,9 @@ def test_make_pkg_info_multi_constraints_dependency() -> None:
]


@pytest.mark.parametrize("project_name", ["complete", "complete_new"])
@pytest.mark.parametrize(
"project_name", ["complete", "complete_new", "complete_dynamic"]
)
def test_find_packages(project_name: str) -> None:
poetry = Factory().create_poetry(project(project_name))

Expand Down Expand Up @@ -277,7 +285,9 @@ def test_find_packages(project_name: str) -> None:
assert pkg_data == {"": ["*"]}


@pytest.mark.parametrize("project_name", ["complete", "complete_new"])
@pytest.mark.parametrize(
"project_name", ["complete", "complete_new", "complete_dynamic"]
)
def test_package(project_name: str) -> None:
poetry = Factory().create_poetry(project(project_name))

Expand Down Expand Up @@ -309,7 +319,9 @@ def test_package_target_dir(tmp_path: Path, target_dir: str | None) -> None:
assert "my_package-1.2.3/LICENSE" in tar.getnames()


@pytest.mark.parametrize("project_name", ["complete", "complete_new"])
@pytest.mark.parametrize(
"project_name", ["complete", "complete_new", "complete_dynamic"]
)
def test_sdist_reproducibility(project_name: str) -> None:
poetry = Factory().create_poetry(project(project_name))

Expand All @@ -328,7 +340,9 @@ def test_sdist_reproducibility(project_name: str) -> None:
assert len(hashes) == 1


@pytest.mark.parametrize("project_name", ["complete", "complete_new"])
@pytest.mark.parametrize(
"project_name", ["complete", "complete_new", "complete_dynamic"]
)
def test_setup_py_context(project_name: str) -> None:
poetry = Factory().create_poetry(project(project_name))

Expand Down
4 changes: 2 additions & 2 deletions tests/masonry/builders/test_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def test_wheel_module() -> None:
assert "module1.py" in z.namelist()


@pytest.mark.parametrize("project", ["complete", "complete_new"])
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
def test_wheel_package(project: str) -> None:
module_path = fixtures_dir / project
WheelBuilder.make(Factory().create_poetry(module_path))
Expand Down Expand Up @@ -231,7 +231,7 @@ def test_wheel_build_script_creates_package() -> None:
shutil.rmtree(module_path / "my_package")


@pytest.mark.parametrize("project", ["complete", "complete_new"])
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
def test_dist_info_file_permissions(project: str) -> None:
module_path = fixtures_dir / project
WheelBuilder.make(Factory().create_poetry(module_path))
Expand Down
16 changes: 8 additions & 8 deletions tests/masonry/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,21 @@ def cwd(directory: str | Path) -> Iterator[None]:
fixtures = Path(__file__).parent / "builders" / "fixtures"


@pytest.mark.parametrize("project", ["complete", "complete_new"])
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
def test_get_requires_for_build_wheel(project: str) -> None:
expected: list[str] = []
with cwd(fixtures / project):
assert api.get_requires_for_build_wheel() == expected


@pytest.mark.parametrize("project", ["complete", "complete_new"])
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
def test_get_requires_for_build_sdist(project: str) -> None:
expected: list[str] = []
with cwd(fixtures / project):
assert api.get_requires_for_build_sdist() == expected


@pytest.mark.parametrize("project", ["complete", "complete_new"])
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
def test_build_wheel(project: str) -> None:
with temporary_directory() as tmp_dir, cwd(fixtures / project):
filename = api.build_wheel(str(tmp_dir))
Expand Down Expand Up @@ -94,7 +94,7 @@ def test_build_wheel_extended() -> None:
validate_wheel_contents(name="extended", version="0.1", path=whl)


@pytest.mark.parametrize("project", ["complete", "complete_new"])
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
def test_build_sdist(project: str) -> None:
with temporary_directory() as tmp_dir, cwd(fixtures / project):
filename = api.build_sdist(str(tmp_dir))
Expand Down Expand Up @@ -131,7 +131,7 @@ def test_build_sdist_with_bad_path_dep_succeeds(caplog: LogCaptureFixture) -> No
assert "does not exist" in record.message


@pytest.mark.parametrize("project", ["complete", "complete_new"])
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
def test_prepare_metadata_for_build_wheel(project: str) -> None:
entry_points = """\
[console_scripts]
Expand Down Expand Up @@ -224,7 +224,7 @@ def test_prepare_metadata_for_build_wheel_with_bad_path_dep_succeeds(
assert "does not exist" in record.message


@pytest.mark.parametrize("project", ["complete", "complete_new"])
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
def test_build_editable_wheel(project: str) -> None:
pkg_dir = fixtures / project
with temporary_directory() as tmp_dir, cwd(pkg_dir):
Expand All @@ -244,7 +244,7 @@ def test_build_editable_wheel(project: str) -> None:
assert z.read("my_package.pth").decode().strip() == pkg_dir.as_posix()


@pytest.mark.parametrize("project", ["complete", "complete_new"])
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
def test_build_wheel_with_metadata_directory(project: str) -> None:
pkg_dir = fixtures / project

Expand Down Expand Up @@ -272,7 +272,7 @@ def test_build_wheel_with_metadata_directory(project: str) -> None:
assert f"{metadata_directory}/CUSTOM" in namelist


@pytest.mark.parametrize("project", ["complete", "complete_new"])
@pytest.mark.parametrize("project", ["complete", "complete_new", "complete_dynamic"])
def test_build_editable_wheel_with_metadata_directory(project: str) -> None:
pkg_dir = fixtures / project

Expand Down
Loading

0 comments on commit 8b66b86

Please sign in to comment.