diff --git a/poetry.lock b/poetry.lock index f1378501177..354f6c14199 100644 --- a/poetry.lock +++ b/poetry.lock @@ -923,13 +923,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "poetry-core" -version = "1.8.1" +version = "1.9.0" description = "Poetry PEP 517 Build Backend" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "poetry_core-1.8.1-py3-none-any.whl", hash = "sha256:194832b24f3283e01c5402eae71a6aae850ecdfe53f50a979c76bf7aa5010ffa"}, - {file = "poetry_core-1.8.1.tar.gz", hash = "sha256:67a76c671da2a70e55047cddda83566035b701f7e463b32a2abfeac6e2a16376"}, + {file = "poetry_core-1.9.0-py3-none-any.whl", hash = "sha256:4e0c9c6ad8cf89956f03b308736d84ea6ddb44089d16f2adc94050108ec1f5a1"}, + {file = "poetry_core-1.9.0.tar.gz", hash = "sha256:fa7a4001eae8aa572ee84f35feb510b321bd652e5cf9293249d62853e1f935a2"}, ] [[package]] @@ -1589,4 +1589,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "074b4ff68b661151ba011c6f5b2cfe4a2f9a4b2e522abc850ad0ac98b88071f2" +content-hash = "43411d93e825e4281de0c03b314fd875a452e885aec636a27e1b7e6d52417da7" diff --git a/pyproject.toml b/pyproject.toml index 447b32e1f1a..773b6906ab8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ Changelog = "https://python-poetry.org/history/" [tool.poetry.dependencies] python = "^3.8" -poetry-core = "1.8.1" +poetry-core = "1.9.0" poetry-plugin-export = "^1.6.0" build = "^1.0.3" cachecontrol = { version = "^0.13.0", extras = ["filecache"] } diff --git a/src/poetry/inspection/info.py b/src/poetry/inspection/info.py index 0c9cfb519d5..9d22961f727 100644 --- a/src/poetry/inspection/info.py +++ b/src/poetry/inspection/info.py @@ -9,6 +9,8 @@ from pathlib import Path from typing import TYPE_CHECKING from typing import Any +from typing import Mapping +from typing import Sequence import pkginfo @@ -31,6 +33,7 @@ from collections.abc import Iterator from packaging.metadata import RawMetadata + from packaging.utils import NormalizedName from poetry.core.packages.project_package import ProjectPackage @@ -71,7 +74,7 @@ def __init__( summary: str | None = None, requires_dist: list[str] | None = None, requires_python: str | None = None, - files: list[dict[str, str]] | None = None, + files: Sequence[Mapping[str, str]] | None = None, yanked: str | bool = False, cache_version: str | None = None, ) -> None: @@ -187,6 +190,7 @@ def to_package( seen_requirements = set() + package_extras: dict[NormalizedName, list[Dependency]] = {} for req in self.requires_dist or []: try: # Attempt to parse the PEP-508 requirement string @@ -214,12 +218,12 @@ def to_package( if dependency.in_extras: # this dependency is required by an extra package for extra in dependency.in_extras: - if extra not in package.extras: + if extra not in package_extras: # this is the first time we encounter this extra for this # package - package.extras[extra] = [] + package_extras[extra] = [] - package.extras[extra].append(dependency) + package_extras[extra].append(dependency) req = dependency.to_pep_508(with_extras=True) @@ -227,6 +231,8 @@ def to_package( package.add_dependency(dependency) seen_requirements.add(req) + package.extras = package_extras + return package @classmethod diff --git a/src/poetry/packages/locker.py b/src/poetry/packages/locker.py index 822e0a59be5..0de62b97f66 100644 --- a/src/poetry/packages/locker.py +++ b/src/poetry/packages/locker.py @@ -31,6 +31,7 @@ if TYPE_CHECKING: + from packaging.utils import NormalizedName from poetry.core.packages.directory_dependency import DirectoryDependency from poetry.core.packages.file_dependency import FileDependency from poetry.core.packages.url_dependency import URLDependency @@ -167,11 +168,13 @@ def locked_repository(self) -> LockfileRepository: package.files = files package.python_versions = info["python-versions"] + + package_extras: dict[NormalizedName, list[Dependency]] = {} extras = info.get("extras", {}) if extras: for name, deps in extras.items(): name = canonicalize_name(name) - package.extras[name] = [] + package_extras[name] = [] for dep in deps: try: @@ -187,7 +190,9 @@ def locked_repository(self) -> LockfileRepository: dependency = Dependency( dep_name, constraint, extras=extras.split(",") ) - package.extras[name].append(dependency) + package_extras[name].append(dependency) + + package.extras = package_extras if "marker" in info: package.marker = parse_marker(info["marker"]) diff --git a/src/poetry/repositories/pypi_repository.py b/src/poetry/repositories/pypi_repository.py index 26a7d497c70..468dc910836 100644 --- a/src/poetry/repositories/pypi_repository.py +++ b/src/poetry/repositories/pypi_repository.py @@ -143,7 +143,6 @@ def _get_release_info( summary=info["summary"], requires_dist=info["requires_dist"], requires_python=info["requires_python"], - files=info.get("files", []), yanked=self._get_yanked(info), cache_version=str(self.CACHE_VERSION), ) @@ -153,12 +152,14 @@ def _get_release_info( except KeyError: version_info = [] + files = info.get("files", []) for file_info in version_info: if file_info["packagetype"] in SUPPORTED_PACKAGE_TYPES: - data.files.append({ + files.append({ "file": file_info["filename"], "hash": "sha256:" + file_info["digests"]["sha256"], }) + data.files = files if self._fallback and data.requires_dist is None: self._log("No dependencies found, downloading archives", level="debug") diff --git a/tests/installation/test_installer.py b/tests/installation/test_installer.py index b903348c4d9..27b4d8a3fc4 100644 --- a/tests/installation/test_installer.py +++ b/tests/installation/test_installer.py @@ -1006,7 +1006,7 @@ def test_run_installs_extras_with_deps_if_requested( with_extras: bool, do_sync: bool, ) -> None: - package.extras[canonicalize_name("foo")] = [get_dependency("C")] + package.extras = {canonicalize_name("foo"): [get_dependency("C")]} package_a = get_package("A", "1.0") package_b = get_package("B", "1.0") package_c = get_package("C", "1.0") @@ -1404,9 +1404,9 @@ def test_run_update_with_locked_extras( }, }) package_a = get_package("A", "1.0") - package_a.extras[canonicalize_name("foo")] = [get_dependency("B")] + package_a.extras = {canonicalize_name("foo"): [get_dependency("B")]} b_dependency = get_dependency("B", "^1.0", optional=True) - b_dependency.in_extras.append(canonicalize_name("foo")) + b_dependency._in_extras = [canonicalize_name("foo")] c_dependency = get_dependency("C", "^1.0") c_dependency.python_versions = "~2.7" package_a.add_dependency(b_dependency) diff --git a/tests/packages/test_locker.py b/tests/packages/test_locker.py index 9699fbd027b..67fd49afb30 100644 --- a/tests/packages/test_locker.py +++ b/tests/packages/test_locker.py @@ -552,7 +552,7 @@ def test_lock_file_should_not_have_mixed_types( Factory.create_dependency("B", {"version": ">=1.0.0", "optional": True}) ) package_a.requires[-1].activate() - package_a.extras[canonicalize_name("foo")] = [get_dependency("B", ">=1.0.0")] + package_a.extras = {canonicalize_name("foo"): [get_dependency("B", ">=1.0.0")]} locker.set_lock_data(root, [package_a]) diff --git a/tests/puzzle/test_provider.py b/tests/puzzle/test_provider.py index ebb7800ec60..9ee1f6fc644 100644 --- a/tests/puzzle/test_provider.py +++ b/tests/puzzle/test_provider.py @@ -770,7 +770,7 @@ def test_complete_package_fetches_optional_vcs_dependency_only_if_requested( ) package = Package("A", "1.0", features=["foo"] if with_extra else []) package.add_dependency(optional_vcs_dependency) - package.extras[canonicalize_name("foo")] = [optional_vcs_dependency] + package.extras = {canonicalize_name("foo"): [optional_vcs_dependency]} repository.add_package(package) spy = mocker.spy(provider, "_search_for_vcs") diff --git a/tests/puzzle/test_solver.py b/tests/puzzle/test_solver.py index 65f013ee3eb..dd77ff01cca 100644 --- a/tests/puzzle/test_solver.py +++ b/tests/puzzle/test_solver.py @@ -449,7 +449,7 @@ def test_solver_solves_optional_and_compatible_packages( solver: Solver, repo: Repository, package: ProjectPackage ) -> None: set_package_python_versions(solver.provider, "~3.4") - package.extras[canonicalize_name("foo")] = [get_dependency("B")] + package.extras = {canonicalize_name("foo"): [get_dependency("B")]} package.add_dependency( Factory.create_dependency("A", {"version": "*", "python": "^3.4"}) ) @@ -563,11 +563,11 @@ def test_solver_returns_extras_only_requested( package_c20 = get_package("C", "2.0") dep10 = get_dependency("C", "1.0", optional=True) - dep10._in_extras.append(canonicalize_name("one")) + dep10._in_extras = [canonicalize_name("one")] dep10.marker = parse_marker("extra == 'one'") dep20 = get_dependency("C", "2.0", optional=True) - dep20._in_extras.append(canonicalize_name("two")) + dep20._in_extras = [canonicalize_name("two")] dep20.marker = parse_marker("extra == 'two'") package_b.extras = { @@ -622,8 +622,7 @@ def test_solver_returns_extras_when_multiple_extras_use_same_dependency( package_c = get_package("C", "1.0") dep = get_dependency("C", "*", optional=True) - dep._in_extras.append(canonicalize_name("one")) - dep._in_extras.append(canonicalize_name("two")) + dep._in_extras = [canonicalize_name("one"), canonicalize_name("two")] package_b.extras = { canonicalize_name("one"): [dep], @@ -675,11 +674,11 @@ def test_solver_returns_extras_only_requested_nested( package_c20 = get_package("C", "2.0") dep10 = get_dependency("C", "1.0", optional=True) - dep10._in_extras.append(canonicalize_name("one")) + dep10._in_extras = [canonicalize_name("one")] dep10.marker = parse_marker("extra == 'one'") dep20 = get_dependency("C", "2.0", optional=True) - dep20._in_extras.append(canonicalize_name("two")) + dep20._in_extras = [canonicalize_name("two")] dep20.marker = parse_marker("extra == 'two'") package_b.extras = { @@ -1075,7 +1074,7 @@ def test_solver_with_dependency_in_both_main_and_dev_dependencies( ) package_a = get_package("A", "1.0") - package_a.extras[canonicalize_name("foo")] = [get_dependency("C")] + package_a.extras = {canonicalize_name("foo"): [get_dependency("C")]} package_a.add_dependency( Factory.create_dependency("C", {"version": "^1.0", "optional": True}) ) @@ -1118,7 +1117,7 @@ def test_solver_with_dependency_in_both_main_and_dev_dependencies_with_one_more_ ) package_a = get_package("A", "1.0") - package_a.extras[canonicalize_name("foo")] = [get_dependency("C")] + package_a.extras = {canonicalize_name("foo"): [get_dependency("C")]} package_a.add_dependency( Factory.create_dependency("C", {"version": "^1.0", "optional": True}) ) @@ -3309,7 +3308,7 @@ def test_direct_dependency_with_extras_from_explicit_and_transitive_dependency( package_lib.add_dependency( Factory.create_dependency("extra", {"version": ">=1.0", "optional": True}) ) - package_lib.extras[canonicalize_name("extra")] = [dep_extra] + package_lib.extras = {canonicalize_name("extra"): [dep_extra]} explicit_repo.add_package(package_lib) # lib only in explicit repo @@ -3380,7 +3379,6 @@ def test_direct_dependency_with_extras_from_explicit_and_transitive_dependency2( package_lib.add_dependency( Factory.create_dependency("extra", {"version": ">=1.0", "optional": True}) ) - package_lib.extras[canonicalize_name("extra")] = [dep_extra] dep_other_extra = get_dependency("other-extra", ">=1.0") package_lib.add_dependency( @@ -3388,7 +3386,10 @@ def test_direct_dependency_with_extras_from_explicit_and_transitive_dependency2( "other-extra", {"version": ">=1.0", "optional": True} ) ) - package_lib.extras[canonicalize_name("other-extra")] = [dep_other_extra] + package_lib.extras = { + canonicalize_name("extra"): [dep_extra], + canonicalize_name("other-extra"): [dep_other_extra], + } explicit_repo.add_package(package_lib) # lib only in explicit repo @@ -3504,7 +3505,9 @@ def test_solver_does_not_loop_indefinitely_on_duplicate_constraints_with_extras( "idna", {"version": ">=2.0.0", "markers": "extra == 'security'"} ) ) - requests.extras[canonicalize_name("security")] = [get_dependency("idna", ">=2.0.0")] + requests.extras = { + canonicalize_name("security"): [get_dependency("idna", ">=2.0.0")] + } idna = get_package("idna", "2.8") repo.add_package(requests) @@ -3940,7 +3943,7 @@ def test_solver_can_resolve_transitive_extras( requests.add_dependency( Factory.create_dependency("PyOpenSSL", {"version": ">=0.14", "optional": True}) ) - requests.extras[canonicalize_name("security")] = [dep] + requests.extras = {canonicalize_name("security"): [dep]} pyota = get_package("PyOTA", "2.1.0") pyota.add_dependency( Factory.create_dependency( @@ -3981,9 +3984,9 @@ def test_solver_can_resolve_for_packages_with_missing_extras( django_anymail.add_dependency( Factory.create_dependency("boto3", {"version": "*", "optional": True}) ) - django_anymail.extras[canonicalize_name("amazon_ses")] = [ - Factory.create_dependency("boto3", "*") - ] + django_anymail.extras = { + canonicalize_name("amazon_ses"): [Factory.create_dependency("boto3", "*")] + } django = get_package("django", "2.2.0") boto3 = get_package("boto3", "1.0.0") requests = get_package("requests", "2.24.0")