|
5 | 5 | import os
|
6 | 6 | import re
|
7 | 7 |
|
8 |
| -from copy import deepcopy |
9 | 8 | from hashlib import sha256
|
10 | 9 | from pathlib import Path
|
11 | 10 | from typing import TYPE_CHECKING
|
|
27 | 26 | from tomlkit.exceptions import TOMLKitError
|
28 | 27 | from tomlkit.items import Array
|
29 | 28 |
|
30 |
| -from poetry.packages import DependencyPackage |
31 |
| -from poetry.utils.extras import get_extra_package_names |
32 |
| - |
33 | 29 |
|
34 | 30 | if TYPE_CHECKING:
|
35 |
| - from collections.abc import Iterable |
36 |
| - from collections.abc import Iterator |
37 |
| - from collections.abc import Sequence |
38 |
| - |
39 | 31 | from poetry.core.packages.directory_dependency import DirectoryDependency
|
40 | 32 | from poetry.core.packages.file_dependency import FileDependency
|
41 | 33 | from poetry.core.packages.url_dependency import URLDependency
|
42 | 34 | from poetry.core.packages.vcs_dependency import VCSDependency
|
43 |
| - from poetry.core.version.markers import BaseMarker |
44 | 35 | from tomlkit.items import Table
|
45 | 36 | from tomlkit.toml_document import TOMLDocument
|
46 | 37 |
|
@@ -206,175 +197,6 @@ def locked_repository(self) -> Repository:
|
206 | 197 |
|
207 | 198 | return packages
|
208 | 199 |
|
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 |
| - |
378 | 200 | def set_lock_data(self, root: Package, packages: list[Package]) -> bool:
|
379 | 201 | files: dict[str, Any] = table()
|
380 | 202 | package_specs = self._lock_packages(packages)
|
|
0 commit comments