Commit a7fef27e by David Hotham Committed by Bjorn Neergaard

direct access for performance

parent c5ce4d03
......@@ -61,7 +61,9 @@ class DependencyCache:
if packages is None:
packages = self.provider.search_for(dependency)
else:
packages = [p for p in packages if dependency.constraint.allows(p.version)]
packages = [
p for p in packages if dependency.constraint.allows(p.package.version)
]
self.cache[key] = packages
......@@ -427,7 +429,12 @@ class VersionSolver:
locked = self._get_locked(dependency, allow_similar=True)
if locked is not None:
package = next(
(p for p in packages if p.version == locked.version), None
(
p
for p in packages
if p.package.version == locked.package.version
),
None,
)
if package is None:
with suppress(IndexError):
......@@ -465,7 +472,8 @@ class VersionSolver:
if not conflict:
self._solution.decide(package.package)
self._log(
f"selecting {package.complete_name} ({package.full_pretty_version})"
f"selecting {package.package.complete_name}"
f" ({package.package.full_pretty_version})"
)
complete_name = dependency.complete_name
......@@ -507,13 +515,14 @@ class VersionSolver:
return None
locked = self._locked.get(dependency.name, [])
for package in locked:
if (allow_similar or dependency.is_same_package_as(package.package)) and (
for dependency_package in locked:
package = dependency_package.package
if (allow_similar or dependency.is_same_package_as(package)) and (
dependency.constraint.allows(package.version)
or package.is_prerelease()
and dependency.constraint.allows(package.version.next_patch())
):
return DependencyPackage(dependency, package.package)
return DependencyPackage(dependency, package)
return None
def _log(self, text: str) -> None:
......
from __future__ import annotations
from typing import TYPE_CHECKING
from typing import Any
if TYPE_CHECKING:
......@@ -31,15 +30,6 @@ class DependencyPackage:
def without_features(self) -> DependencyPackage:
return self.with_features([])
def __getattr__(self, name: str) -> Any:
return getattr(self._package, name)
def __setattr__(self, key: str, value: Any) -> None:
if key in {"_dependency", "_package"}:
return super().__setattr__(key, value)
setattr(self._package, key, value)
def __str__(self) -> str:
return str(self._package)
......
......@@ -426,7 +426,7 @@ class Provider:
return _dependencies
def incompatibilities_for(
self, package: DependencyPackage
self, dependency_package: DependencyPackage
) -> list[Incompatibility]:
"""
Returns incompatibilities that encapsulate a given package's dependencies,
......@@ -437,6 +437,7 @@ class Provider:
won't return incompatibilities that have already been returned by a
previous call to _incompatibilities_for().
"""
package = dependency_package.package
if package.is_root():
dependencies = package.all_requires
else:
......@@ -444,7 +445,7 @@ class Provider:
if not package.python_constraint.allows_all(self._python_constraint):
transitive_python_constraint = get_python_constraint_from_marker(
package.dependency.transitive_marker
dependency_package.dependency.transitive_marker
)
intersection = package.python_constraint.intersect(
transitive_python_constraint
......@@ -457,7 +458,7 @@ class Provider:
if (
transitive_python_constraint.is_any()
or self._python_constraint.intersect(
package.dependency.python_constraint
dependency_package.dependency.python_constraint
).is_empty()
or intersection.is_empty()
or not difference.is_empty()
......@@ -478,7 +479,9 @@ class Provider:
and self._python_constraint.allows_any(dep.python_constraint)
and (not self._env or dep.marker.validate(self._env.marker_env))
]
dependencies = self._get_dependencies_with_overrides(_dependencies, package)
dependencies = self._get_dependencies_with_overrides(
_dependencies, dependency_package
)
return [
Incompatibility(
......@@ -489,10 +492,10 @@ class Provider:
]
def complete_package(self, package: DependencyPackage) -> DependencyPackage:
if package.is_root():
if package.package.is_root():
package = package.clone()
requires = package.all_requires
elif not package.is_root() and package.source_type not in {
requires = package.package.all_requires
elif not package.package.is_root() and package.package.source_type not in {
"directory",
"file",
"url",
......@@ -502,8 +505,8 @@ class Provider:
package = DependencyPackage(
package.dependency,
self._pool.package(
package.name,
package.version.text,
package.package.name,
package.package.version.text,
extras=list(package.dependency.extras),
repository=package.dependency.source_name,
),
......@@ -521,9 +524,9 @@ class Provider:
)
except StopIteration:
raise e from e
requires = package.requires
requires = package.package.requires
else:
requires = package.requires
requires = package.package.requires
if self._load_deferred:
# Retrieving constraints for deferred dependencies
......@@ -540,13 +543,13 @@ class Provider:
if package.dependency.extras:
for extra in package.dependency.extras:
extra = safe_extra(extra)
if extra not in package.extras:
if extra not in package.package.extras:
continue
optional_dependencies += [d.name for d in package.extras[extra]]
optional_dependencies += [d.name for d in package.package.extras[extra]]
package = package.with_features(list(package.dependency.extras))
_dependencies.append(package.without_features().to_dependency())
_dependencies.append(package.package.without_features().to_dependency())
for dep in requires:
if not self._python_constraint.allows_any(dep.python_constraint):
......@@ -558,7 +561,7 @@ class Provider:
if self._env and not dep.marker.validate(self._env.marker_env):
continue
if not package.is_root() and (
if not package.package.is_root() and (
(dep.is_optional() and dep.name not in optional_dependencies)
or (
dep.in_extras
......@@ -764,11 +767,11 @@ class Provider:
clean_dependencies.append(dep)
package = DependencyPackage(
package.dependency, package.with_dependency_groups([], only=True)
package.dependency, package.package.with_dependency_groups([], only=True)
)
for dep in clean_dependencies:
package.add_dependency(dep)
package.package.add_dependency(dep)
return package
......
......@@ -106,16 +106,19 @@ def test_solver_dependency_cache_respects_subdirectories(
package_one = packages_one[0]
package_one_copy = packages_one_copy[0]
assert package_one.package.name == package_one_copy.name
assert package_one.package.name == package_one_copy.package.name
assert package_one.package.version.text == package_one_copy.package.version.text
assert package_one.package.source_type == package_one_copy.source_type == "git"
assert (
package_one.package.source_type == package_one_copy.package.source_type == "git"
)
assert (
package_one.package.source_resolved_reference
== package_one_copy.source_resolved_reference
== package_one_copy.package.source_resolved_reference
== "9cf87a285a2d3fbb0b9fa621997b3acc3631ed24"
)
assert (
package_one.package.source_subdirectory != package_one_copy.source_subdirectory
package_one.package.source_subdirectory
!= package_one_copy.package.source_subdirectory
)
assert package_one.package.source_subdirectory == "one"
assert package_one_copy.package.source_subdirectory == "one-copy"
......
......@@ -1448,9 +1448,9 @@ def test_solver_duplicate_dependencies_different_sources_types_are_preserved(
DependencyPackage(package.to_dependency(), package)
)
assert len(complete_package.all_requires) == 2
assert len(complete_package.package.all_requires) == 2
pypi, git = complete_package.all_requires
pypi, git = complete_package.package.all_requires
assert isinstance(pypi, Dependency)
assert pypi == dependency_pypi
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment