Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/poetry_plugin_export/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@


if TYPE_CHECKING:
from collections.abc import Collection
from pathlib import Path

from packaging.utils import NormalizedName
Expand All @@ -40,14 +41,14 @@ def __init__(self, poetry: Poetry, io: IO) -> None:
self._with_hashes = True
self._with_credentials = False
self._with_urls = True
self._extras: bool | list[NormalizedName] | None = []
self._extras: Collection[NormalizedName] = ()
self._groups: Iterable[str] = [MAIN_GROUP]

@classmethod
def is_format_supported(cls, fmt: str) -> bool:
return fmt in cls.EXPORT_METHODS

def with_extras(self, extras: bool | list[NormalizedName] | None) -> Exporter:
def with_extras(self, extras: Collection[NormalizedName]) -> Exporter:
self._extras = extras

return self
Expand Down
35 changes: 14 additions & 21 deletions src/poetry_plugin_export/walker.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@


if TYPE_CHECKING:
from collections.abc import Collection
from collections.abc import Iterable
from collections.abc import Iterator
from collections.abc import Sequence

from packaging.utils import NormalizedName
from poetry.core.packages.dependency import Dependency
Expand Down Expand Up @@ -53,7 +53,7 @@ def get_project_dependency_packages(
locker: Locker,
project_requires: list[Dependency],
project_python_marker: BaseMarker | None = None,
extras: bool | Sequence[NormalizedName] | None = None,
extras: Collection[NormalizedName] = (),
) -> Iterator[DependencyPackage]:
# Apply the project python marker to all requirements.
if project_python_marker is not None:
Expand All @@ -67,22 +67,17 @@ def get_project_dependency_packages(
repository = locker.locked_repository()

# Build a set of all packages required by our selected extras
extra_package_names: set[str] | None = None

if extras is not True:
locked_extras = {
canonicalize_name(extra): [
canonicalize_name(dependency) for dependency in dependencies
]
for extra, dependencies in locker.lock_data.get("extras", {}).items()
}
extra_package_names = set(
get_extra_package_names(
repository.packages,
locked_extras,
extras or (),
)
)
locked_extras = {
canonicalize_name(extra): [
canonicalize_name(dependency) for dependency in dependencies
]
for extra, dependencies in locker.lock_data.get("extras", {}).items()
}
extra_package_names = get_extra_package_names(
repository.packages,
locked_extras,
extras,
)

# If a package is optional and we haven't opted in to it, do not select
selected = []
Expand All @@ -92,9 +87,7 @@ def get_project_dependency_packages(
except IndexError:
continue

if extra_package_names is not None and (
package.optional and package.name not in extra_package_names
):
if package.optional and package.name not in extra_package_names:
# a package is locked as optional, but is not activated via extras
continue

Expand Down
19 changes: 2 additions & 17 deletions tests/test_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@


if TYPE_CHECKING:
from collections.abc import Collection
from pathlib import Path

from packaging.utils import NormalizedName
Expand Down Expand Up @@ -889,22 +890,6 @@ def test_exporter_exports_requirements_txt_without_optional_packages(
@pytest.mark.parametrize(
["extras", "lines"],
[
(
None,
[f"foo==1.2.3 ; {MARKER_PY}"],
),
(
False,
[f"foo==1.2.3 ; {MARKER_PY}"],
),
(
True,
[
f"bar==4.5.6 ; {MARKER_PY}",
f"foo==1.2.3 ; {MARKER_PY}",
f"spam==0.1.0 ; {MARKER_PY}",
],
),
(
["feature-bar"],
[
Expand All @@ -918,7 +903,7 @@ def test_exporter_exports_requirements_txt_without_optional_packages(
def test_exporter_exports_requirements_txt_with_optional_packages(
tmp_path: Path,
poetry: Poetry,
extras: bool | list[NormalizedName] | None,
extras: Collection[NormalizedName],
lines: list[str],
) -> None:
poetry.locker.mock_lock_data( # type: ignore[attr-defined]
Expand Down