Install & Compatibility
Where this runs
tested against v1.2.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.018s · 17.9MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.6s · import 0.016s · 18MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Resolver
✓ from resolvelib import Resolver
The Resolver class is the core component for initiating the dependency resolution process.
BaseReporter
✓ from resolvelib.reporters import BaseReporter
BaseReporter provides a default implementation for reporting resolution progress. Custom reporters can inherit from this class.
Provider (interface)
✓ import resolvelib.providers
While not directly imported as a class, the provider interface needs to be implemented by a custom class. Referencing `resolvelib.providers` reminds users where the interface specification is described.
This quickstart demonstrates the core usage of `resolvelib`. It involves defining custom `Package` and `Requirement` objects, then implementing a `Provider` class to teach the resolver how to find candidates, handle dependencies, and determine preferences. Finally, a `Resolver` instance is created and used to find a consistent set of packages based on the initial requirements.
import resolvelib
from resolvelib.reporters import BaseReporter
import os
# Define simple data structures for our 'packages' and 'requirements'
# In a real scenario, these would be richer objects (e.g., Package(name, version), Requirement(package_name, specifier))
class MyPackage:
def __init__(self, name, version):
self.name = name
self.version = version
def __repr__(self):
return f'{self.name}=={self.version}'
def __hash__(self):
return hash((self.name, self.version))
def __eq__(self, other):
return isinstance(other, MyPackage) and self.name == other.name and self.version == other.version
class MyRequirement:
def __init__(self, name, specifier):
self.name = name
self.specifier = specifier # e.g., '>=1.0', '<2.0'
def __repr__(self):
return f'{self.name}{self.specifier}'
def __hash__(self):
return hash((self.name, self.specifier))
def __eq__(self, other):
return isinstance(other, MyRequirement) and self.name == other.name and self.specifier == other.specifier
# Implement the Provider interface
class MyProvider:
def get_base_requirement(self, identifier):
# For this simple example, we assume identifier is the package name
# and we don't have a 'base' requirement beyond the initial ones.
return None
def identify(self, requirement_or_candidate):
return requirement_or_candidate.name
def get_preference(self, identifier, resolutions, candidates, information):
# Prefer higher versions
return len(candidates) + 1 # Dummy preference, real logic would sort candidates
def get_dependencies(self, candidate):
# Define dependencies for candidates
if candidate.name == 'A' and candidate.version == '1.0':
return [MyRequirement('B', '>=1.0')]
if candidate.name == 'B' and candidate.version == '1.0':
return [MyRequirement('C', '>=1.0')]
return []
def get_candidates(self, requirement):
# Return available candidates for a given requirement
if requirement.name == 'A':
yield MyPackage('A', '1.0')
yield MyPackage('A', '2.0')
elif requirement.name == 'B':
yield MyPackage('B', '1.0')
yield MyPackage('B', '1.1')
elif requirement.name == 'C':
yield MyPackage('C', '1.0')
yield MyPackage('C', '1.2')
else:
return []
def is_satisfied_by(self, requirement, candidate):
# In a real scenario, this would check if candidate.version satisfies requirement.specifier
# For simplicity, we assume any candidate with the correct name satisfies a basic requirement
return requirement.name == candidate.name
# Create an instance of the provider and reporter
provider = MyProvider()
reporter = BaseReporter()
# Create the resolver
resolver = resolvelib.Resolver(provider, reporter)
# Define the initial requirements
requirements = [MyRequirement('A', '>=1.0')]
# Kick off the resolution process
try:
result = resolver.resolve(requirements)
print("Resolution successful:")
for candidate in result.graph.iter_network_linear():
if isinstance(candidate, MyPackage):
print(f" - {candidate}")
except resolvelib.ResolutionImpossible as e:
print(f"Resolution failed: {e}")
# Example of getting an auth key, though not directly used by resolvelib
api_key = os.environ.get('RESOLVELIB_API_KEY', 'your_default_or_mock_key')
if api_key == 'your_default_or_mock_key':
print("\nNote: For real-world use with external registries, an API key might be passed via Provider.")
else:
print(f"\nUsing API Key (first 5 chars): {api_key[:5]}...")
Debug
Known issues
breakingVersion 0.7.0 (April 2021) introduced breaking changes to the `Provider` interface. Users upgrading from versions prior to 0.7.0 will likely need to update their custom Provider implementations.fixReview the `resolvelib` documentation and changelog for 0.7.0 to identify the updated `Provider` methods and adjust your implementation accordingly.
affects: <0.7.0 to >=0.7.0
breakingVersion 1.0.0 (March 2023) changed the return type of `Resolver.resolve()`. It now returns a `namedtuple` with public attributes instead of an internal `Resolution` object. Code directly accessing internal attributes of the `Resolution` object will break.fixUpdate code to access the new public attributes of the returned `namedtuple` from `Resolver.resolve()`. Consult the changelog or examples for the correct attribute names.
affects: <1.0.0 to >=1.0.0
gotchaComplex dependency graphs can sometimes lead to `pip._vendor.resolvelib.resolvers.ResolutionTooDeep: 200000` errors or extremely long resolution times, especially when `resolvelib` is vendored within tools like `pip`. This can be due to intricate backtracking logic and optimization issues within the resolver.fixSimplify your dependency constraints, ensure your `pip` is up-to-date (which often includes `resolvelib` fixes), and, if providing a custom `Provider`, consider optimizing `get_preference` and dependency reporting to reduce the search space.
affects: All versions, more pronounced in highly complex scenarios or older `pip` versions.
gotcha`resolvelib` is a low-level building block. It requires users to implement a custom `Provider` interface to define how it interacts with their specific package ecosystem (e.g., how to find candidates, determine dependencies, and evaluate satisfaction). It's not an out-of-the-box solution for a specific package manager.fixThoroughly understand the `Provider` interface documented in `resolvelib`'s source or examples. Your custom `Provider` must correctly implement methods like `identify`, `get_candidates`, `get_dependencies`, and `is_satisfied_by`.
affects: All versions
Errors
Common errors & fixes
resolvelib.resolvers.ResolutionImpossible: There are conflicting requirements:
The set of requirements provided to the resolver contains dependencies that cannot be simultaneously satisfied by any available candidate packages.
fixExamine the detailed conflict message provided by the exception to identify the specific packages and versions causing the conflict, then adjust the initial requirements or available candidates accordingly.
TypeError: 'NoneType' object is not iterable
A custom `Provider` method (e.g., `get_dependencies`, `find_matches`) incorrectly returned `None` when an empty iterable (like an empty list `[]` or tuple `()`) was expected.
fixEnsure all methods in the custom `Provider` that are expected to return collections (like dependencies or matches) return an empty list `[]` or another empty iterable, rather than `None`, when there are no items to return.
NotImplementedError: Method 'get_dependencies' must be implemented in a subclass.
The custom `Provider` class inheriting from `resolvelib.AbstractProvider` has not provided an implementation for one of its abstract methods.
fixImplement all abstract methods (e.g., `get_base_requirement`, `identify_requirement`, `identify_candidate`, `get_preference`, `find_matches`, `is_satisfied_by`, `get_dependencies`) in your custom `Provider` subclass.
ModuleNotFoundError: No module named 'resolvelib'
The `resolvelib` library is not installed in the Python environment where the code is being executed, or the environment is not correctly activated.
fixInstall the package using pip: `pip install resolvelib`. If using a virtual environment, ensure it is activated before installation.
Upgrade
Version history
1.2.1latest on PyPI · released Oct 11, 2025
Audit
Dependencies
No dependency data recorded yet.