Commit a7fef27e by David Hotham Committed by Bjorn Neergaard

direct access for performance

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