Skip to content

Commit d8a63c7

Browse files
committed
move export code into export plugin
1 parent 35281d9 commit d8a63c7

File tree

3 files changed

+7
-184
lines changed

3 files changed

+7
-184
lines changed

Diff for: poetry.lock

+6-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ generate-setup-file = false
4545
python = "^3.7"
4646

4747
poetry-core = "^1.1.0b3"
48-
poetry-plugin-export = "^1.0.5"
48+
poetry-plugin-export = "^1.0.6"
4949
cachecontrol = { version = "^0.12.9", extras = ["filecache"] }
5050
cachy = "^0.3.0"
5151
cleo = "^1.0.0a5"

Diff for: src/poetry/packages/locker.py

-178
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import os
66
import re
77

8-
from copy import deepcopy
98
from hashlib import sha256
109
from pathlib import Path
1110
from typing import TYPE_CHECKING
@@ -27,20 +26,12 @@
2726
from tomlkit.exceptions import TOMLKitError
2827
from tomlkit.items import Array
2928

30-
from poetry.packages import DependencyPackage
31-
from poetry.utils.extras import get_extra_package_names
32-
3329

3430
if TYPE_CHECKING:
35-
from collections.abc import Iterable
36-
from collections.abc import Iterator
37-
from collections.abc import Sequence
38-
3931
from poetry.core.packages.directory_dependency import DirectoryDependency
4032
from poetry.core.packages.file_dependency import FileDependency
4133
from poetry.core.packages.url_dependency import URLDependency
4234
from poetry.core.packages.vcs_dependency import VCSDependency
43-
from poetry.core.version.markers import BaseMarker
4435
from tomlkit.items import Table
4536
from tomlkit.toml_document import TOMLDocument
4637

@@ -206,175 +197,6 @@ def locked_repository(self) -> Repository:
206197

207198
return packages
208199

209-
@staticmethod
210-
def __get_locked_package(
211-
dependency: Dependency,
212-
packages_by_name: dict[str, list[Package]],
213-
decided: dict[Package, Dependency] | None = None,
214-
) -> Package | None:
215-
"""
216-
Internal helper to identify corresponding locked package using dependency
217-
version constraints.
218-
"""
219-
decided = decided or {}
220-
221-
# Get the packages that are consistent with this dependency.
222-
packages = [
223-
package
224-
for package in packages_by_name.get(dependency.name, [])
225-
if package.python_constraint.allows_all(dependency.python_constraint)
226-
and dependency.constraint.allows(package.version)
227-
]
228-
229-
# If we've previously made a choice that is compatible with the current
230-
# requirement, stick with it.
231-
for package in packages:
232-
old_decision = decided.get(package)
233-
if (
234-
old_decision is not None
235-
and not old_decision.marker.intersect(dependency.marker).is_empty()
236-
):
237-
return package
238-
239-
return next(iter(packages), None)
240-
241-
@classmethod
242-
def __walk_dependencies(
243-
cls,
244-
dependencies: list[Dependency],
245-
packages_by_name: dict[str, list[Package]],
246-
) -> dict[Package, Dependency]:
247-
nested_dependencies: dict[Package, Dependency] = {}
248-
249-
visited: set[tuple[Dependency, BaseMarker]] = set()
250-
while dependencies:
251-
requirement = dependencies.pop(0)
252-
if (requirement, requirement.marker) in visited:
253-
continue
254-
visited.add((requirement, requirement.marker))
255-
256-
locked_package = cls.__get_locked_package(
257-
requirement, packages_by_name, nested_dependencies
258-
)
259-
260-
if not locked_package:
261-
raise RuntimeError(f"Dependency walk failed at {requirement}")
262-
263-
if requirement.extras:
264-
locked_package = locked_package.with_features(requirement.extras)
265-
266-
# create dependency from locked package to retain dependency metadata
267-
# if this is not done, we can end-up with incorrect nested dependencies
268-
constraint = requirement.constraint
269-
marker = requirement.marker
270-
requirement = locked_package.to_dependency()
271-
requirement.marker = requirement.marker.intersect(marker)
272-
273-
requirement.constraint = constraint
274-
275-
for require in locked_package.requires:
276-
if require.is_optional() and not any(
277-
require in locked_package.extras[feature]
278-
for feature in locked_package.features
279-
):
280-
continue
281-
282-
require = deepcopy(require)
283-
require.marker = require.marker.intersect(
284-
requirement.marker.without_extras()
285-
)
286-
if not require.marker.is_empty():
287-
dependencies.append(require)
288-
289-
key = locked_package
290-
if key not in nested_dependencies:
291-
nested_dependencies[key] = requirement
292-
else:
293-
nested_dependencies[key].marker = nested_dependencies[key].marker.union(
294-
requirement.marker
295-
)
296-
297-
return nested_dependencies
298-
299-
@classmethod
300-
def get_project_dependencies(
301-
cls,
302-
project_requires: list[Dependency],
303-
locked_packages: list[Package],
304-
) -> Iterable[tuple[Package, Dependency]]:
305-
# group packages entries by name, this is required because requirement might use
306-
# different constraints.
307-
packages_by_name: dict[str, list[Package]] = {}
308-
for pkg in locked_packages:
309-
if pkg.name not in packages_by_name:
310-
packages_by_name[pkg.name] = []
311-
packages_by_name[pkg.name].append(pkg)
312-
313-
# Put higher versions first so that we prefer them.
314-
for packages in packages_by_name.values():
315-
packages.sort(
316-
key=lambda package: package.version,
317-
reverse=True,
318-
)
319-
320-
nested_dependencies = cls.__walk_dependencies(
321-
dependencies=project_requires,
322-
packages_by_name=packages_by_name,
323-
)
324-
325-
return nested_dependencies.items()
326-
327-
def get_project_dependency_packages(
328-
self,
329-
project_requires: list[Dependency],
330-
project_python_marker: BaseMarker | None = None,
331-
extras: bool | Sequence[str] | None = None,
332-
) -> Iterator[DependencyPackage]:
333-
# Apply the project python marker to all requirements.
334-
if project_python_marker is not None:
335-
marked_requires: list[Dependency] = []
336-
for require in project_requires:
337-
require = deepcopy(require)
338-
require.marker = require.marker.intersect(project_python_marker)
339-
marked_requires.append(require)
340-
project_requires = marked_requires
341-
342-
repository = self.locked_repository()
343-
344-
# Build a set of all packages required by our selected extras
345-
extra_package_names: set[str] | None = None
346-
347-
if extras is not True:
348-
extra_package_names = set(
349-
get_extra_package_names(
350-
repository.packages,
351-
self.lock_data.get("extras", {}),
352-
extras or (),
353-
)
354-
)
355-
356-
# If a package is optional and we haven't opted in to it, do not select
357-
selected = []
358-
for dependency in project_requires:
359-
try:
360-
package = repository.find_packages(dependency=dependency)[0]
361-
except IndexError:
362-
continue
363-
364-
if extra_package_names is not None and (
365-
package.optional and package.name not in extra_package_names
366-
):
367-
# a package is locked as optional, but is not activated via extras
368-
continue
369-
370-
selected.append(dependency)
371-
372-
for package, dependency in self.get_project_dependencies(
373-
project_requires=selected,
374-
locked_packages=repository.packages,
375-
):
376-
yield DependencyPackage(dependency=dependency, package=package)
377-
378200
def set_lock_data(self, root: Package, packages: list[Package]) -> bool:
379201
files: dict[str, Any] = table()
380202
package_specs = self._lock_packages(packages)

0 commit comments

Comments
 (0)