| Server IP : 85.214.239.14 / Your IP : 216.73.216.27 Web Server : Apache/2.4.65 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 8.2.29 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/2/root/usr/share/doc/python3-resolvelib/examples/ |
Upload File : |
"""A provider that handles packages with "extras".
Python package dependencies can include "extras", which are additional
dependencies that are installed "on demand". For instance, project X could
have an additional set of dependencies if PDF generation features are needed.
These can be defined for an extra "pdf" and requested on install as X[pdf].
The basic resolvelib algorithm cannot handle extras, as it builds a dependency
graph which needs to be static - the edges (dependencies) from a node
(candidate) must be fixed. Extras break this assumption.
To model projects with extras, we define a candidate as being a project with a
specific set of dependencies. This introduces a problem, as the resolver could
produce a solution that demands version 1.0 of X[foo] and version 2.0 of
X[bar]. This is impossible, as there is actually only one project X to be
installed. To address this, we inject an additional dependency for every
candidate with an extra - X[foo] version v depends on X version v. By doing
this, we constrain the solution to require a unique version of X.
"""
from resolvelib.providers import AbstractProvider
class ExtrasProvider(AbstractProvider):
"""A provider that handles extras."""
def get_extras_for(self, requirement_or_candidate):
"""Given a requirement or candidate, return its extras.
The extras should be a hashable value.
"""
raise NotImplementedError
def get_base_requirement(self, candidate):
"""Given a candidate, return a requirement that specifies that
project/version.
"""
raise NotImplementedError
def identify(self, requirement_or_candidate):
base = super(ExtrasProvider, self).identify(requirement_or_candidate)
extras = self.get_extras_for(requirement_or_candidate)
if extras:
return (base, extras)
else:
return base
def get_dependencies(self, candidate):
deps = super(ExtrasProvider, self).get_dependencies(candidate)
if candidate.extras:
req = self.get_base_requirement(candidate)
deps.append(req)
return deps