feu.compat¶
Registry-based package/Python-version compatibility resolution: given a package name and a target environment, find out which versions of that package are known to work.
Concepts¶
Targetidentifies the environment a constraint applies to:python_versionandfree_threaded(always concrete), plus optionalos/arch.Noneonos/archmeans "any" when stored in the registry, and "unspecified" when used as a lookup key.VersionRangeis one contiguous(min, max)span of valid package versions; either bound may beNonefor unbounded. A package/target can have several disjoint ranges (e.g. a package supported1.0-1.10, then unsupported for a stretch, then supported again from2.8onward).CompatRegistrystores package constraints populated byregister_defaults()(the built-inDEFAULT_COMPATtable), discovery, and user calls toregister_compat().
A lookup target matches a stored entry when python_version and
free_threaded are equal, and the stored entry's os/arch are either
None (wildcard) or equal to the lookup target's. When several entries
match, the most specific one (most non-None os/arch) wins.
Discovery¶
discover_compat_targets(pkg_name, targets=DEFAULT_TARGETS) computes
compatibility data from PyPI rather than requiring it to be hand-maintained.
For each release, it parses the actual wheel filenames (via WheelTags /
parse_wheel_filename) and requires_python metadata to determine, per
target (Python version, OS, arch, free-threaded), the range of package
versions that support it.
It is available as a library function for callers who need per-package,
per-platform precision. It also powers the automatically discovered
compatibility data under feu.compat.discovered (see
feu.compat.defaults.DEFAULT_COMPAT for the human-curated counterpart,
which takes precedence when both specify a given package/target): these
modules are regenerated by dev/generate_discovered_compat.py, run on a
schedule by the update-discovered-compat CI workflow
(.github/workflows/update-discovered-compat.yaml).
Usage¶
>>> from feu.compat import Target, find_closest_version, is_valid_version
>>> target = Target(python_version="3.11")
>>> is_valid_version("numpy", "1.23.2", target)
True
>>> find_closest_version("numpy", "0.1.0", target)
'...'
Corrections can be registered on top of the built-in defaults:
>>> from feu.compat import Target, register_compat
>>> from feu.compat.registry import VersionRange
>>> register_compat({"mypkg": {Target(python_version="3.12"): [VersionRange("2.0", None)]}})
API reference¶
feu.compat ¶
Contain a registry-based system for package/target compatibility resolution.
feu.compat.BaseCompatDiscoverer ¶
Bases: ABC
Define the base class for package compatibility target discoverers.
Example
>>> from feu.compat.discoverers import CompatDiscoverer
>>> from feu.compat.target import Target
>>> discoverer = CompatDiscoverer()
>>> compat = discoverer.discover(
... "numpy", targets=(Target(python_version="3.11", os="linux", arch="x86_64"),)
... ) # doctest: +SKIP
feu.compat.BaseCompatDiscoverer.discover
abstractmethod
¶
discover(
pkg_name: str, targets: Sequence[Target]
) -> dict[Target, list[VersionRange]]
Discover the version range compatible with each target.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name to inspect (e.g., |
required |
targets
|
Sequence[Target]
|
The compatibility targets to compute constraints
for. Each target must have concrete (non- |
required |
Returns:
| Type | Description |
|---|---|
dict[Target, list[VersionRange]]
|
A mapping of |
feu.compat.CompatDiscoverer ¶
Bases: BaseCompatDiscoverer
Implement the default compatibility target discoverer, using actual wheel filenames published on PyPI.
Unlike an approach that only inspects the requires_python
metadata, this discoverer parses each release's wheel filenames to
determine whether it shipped a build matching a target's
free-threaded/OS/arch axes, not just its Python version. For
pure-Python wheels (which carry no OS/arch information, and
sometimes no Python-version information either), it falls back to
the requires_python metadata.
Example
>>> from feu.compat.discoverers import CompatDiscoverer
>>> from feu.compat.target import Target
>>> discoverer = CompatDiscoverer()
>>> compat = discoverer.discover(
... "numpy", targets=(Target(python_version="3.11", os="linux", arch="x86_64"),)
... ) # doctest: +SKIP
feu.compat.CompatDiscovererRegistry ¶
Implement a registry that manages and dispatches compatibility discoverers based on package name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_state
|
dict[str, BaseCompatDiscoverer] | None
|
Optional initial mapping of package name to discoverer. If provided, the state is copied to prevent external mutations. |
None
|
Example
>>> from feu.compat.discoverers import CompatDiscovererRegistry, CompatDiscoverer
>>> registry = CompatDiscovererRegistry()
>>> registry.register("my_package", CompatDiscoverer())
>>> registry.has_discoverer("my_package")
True
feu.compat.CompatDiscovererRegistry.find_discoverer ¶
find_discoverer(pkg_name: str) -> BaseCompatDiscoverer
Find the relevant compatibility discoverer for the given package.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name. |
required |
Returns:
| Type | Description |
|---|---|
BaseCompatDiscoverer
|
The compatibility discoverer for the package, or a
|
Example
>>> from feu.compat.discoverers import CompatDiscovererRegistry
>>> registry = CompatDiscovererRegistry()
>>> discoverer = registry.find_discoverer("pydantic")
>>> discoverer
CompatDiscoverer()
feu.compat.CompatDiscovererRegistry.has_discoverer ¶
has_discoverer(pkg_name: str) -> bool
Indicate if a compatibility discoverer is registered for the given package name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Example
>>> from feu.compat.discoverers import CompatDiscovererRegistry
>>> registry = CompatDiscovererRegistry()
>>> registry.has_discoverer("pydantic")
False
feu.compat.CompatDiscovererRegistry.register ¶
register(
pkg_name: str,
discoverer: BaseCompatDiscoverer,
exist_ok: bool = False,
) -> None
Register a compatibility discoverer for a given package.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name. |
required |
discoverer
|
BaseCompatDiscoverer
|
The discoverer used for the given package. |
required |
exist_ok
|
bool
|
If |
False
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
if a discoverer is already registered for the
package name and |
Example
>>> from feu.compat.discoverers import CompatDiscovererRegistry, CompatDiscoverer
>>> registry = CompatDiscovererRegistry()
>>> registry.register("my_package", CompatDiscoverer())
>>> registry.has_discoverer("my_package")
True
feu.compat.CompatDiscovererRegistry.register_many ¶
register_many(
mapping: Mapping[str, BaseCompatDiscoverer],
exist_ok: bool = False,
) -> None
Register multiple compatibility discoverers at once.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mapping
|
Mapping[str, BaseCompatDiscoverer]
|
Mapping of package name to discoverer. |
required |
exist_ok
|
bool
|
If |
False
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
if a discoverer is already registered for any
of the package names and |
Example
>>> from feu.compat.discoverers import CompatDiscovererRegistry, CompatDiscoverer
>>> registry = CompatDiscovererRegistry()
>>> registry.register_many({"my_package": CompatDiscoverer()})
>>> registry.has_discoverer("my_package")
True
feu.compat.CompatRegistry ¶
Manage package version compatibility across different compatibility targets.
The registry maps package name to Target to a list of
VersionRange. A package version is valid for a target if it
falls within any of the registered ranges; an empty list means no
version is valid for that target. A lookup target matches a
stored entry when python_version and free_threaded are
equal, and the stored entry's os/arch are either None
(wildcard) or equal to the lookup target's os/arch. Among
all matching entries, the most specific one (most non-None
os/arch fields) wins; ties are broken by most-recently
registered.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_state
|
dict[str, dict[Target, list[VersionRange]]] | None
|
Optional initial mapping of package constraints. If provided, the state is copied to prevent external mutations. |
None
|
Example
>>> from feu.compat import CompatRegistry, Target
>>> from feu.compat.registry import VersionRange
>>> registry = CompatRegistry()
>>> registry.register(
... pkg_name="numpy",
... target=Target(python_version="3.11"),
... ranges=[VersionRange("1.23.2", "2.4.6")],
... )
>>> registry.is_valid_version("numpy", "2.0.2", Target(python_version="3.11"))
True
feu.compat.CompatRegistry.state
property
¶
state: dict[str, dict[Target, list[VersionRange]]]
The registered package constraints.
feu.compat.CompatRegistry.find_closest_version ¶
find_closest_version(
pkg_name: str, pkg_version: str, target: Target
) -> str
Find the closest valid version for a package.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name to check (e.g., |
required |
pkg_version
|
str
|
The requested package version. |
required |
target
|
Target
|
The compatibility target. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The closest valid version as a string. |
Raises:
| Type | Description |
|---|---|
UnsupportedVersionError
|
If no package version is valid for the given target. |
feu.compat.CompatRegistry.get_config ¶
get_config(
pkg_name: str, target: Target
) -> list[VersionRange]
Get the list of valid version ranges for a package and compatibility target.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name to query (e.g., |
required |
target
|
Target
|
The compatibility target. |
required |
Returns:
| Type | Description |
|---|---|
list[VersionRange]
|
The list of |
list[VersionRange]
|
list if no configuration matches. |
feu.compat.CompatRegistry.get_version_ranges ¶
get_version_ranges(
pkg_name: str, target: Target
) -> list[tuple[Version | None, Version | None]]
Get the valid version ranges as Version objects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name to query (e.g., |
required |
target
|
Target
|
The compatibility target. |
required |
Returns:
| Type | Description |
|---|---|
list[tuple[Version | None, Version | None]]
|
A list of |
list[tuple[Version | None, Version | None]]
|
value being |
Raises:
| Type | Description |
|---|---|
UnsupportedVersionError
|
If no package version is valid for the given target. |
feu.compat.CompatRegistry.is_unsupported ¶
is_unsupported(pkg_name: str, target: Target) -> bool
Indicate if no package version is valid for a target.
This is distinct from a target having no registered
configuration at all: an unconfigured target is treated as
permissive (False), whereas a target explicitly
registered with an empty range list is unsupported
(True).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name to check (e.g., |
required |
target
|
Target
|
The compatibility target. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
given target, |
feu.compat.CompatRegistry.is_valid_version ¶
is_valid_version(
pkg_name: str, pkg_version: str, target: Target
) -> bool
Check if a package version is valid for a target.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name to check (e.g., |
required |
pkg_version
|
str
|
The package version to validate. |
required |
target
|
Target
|
The compatibility target. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
unconfigured, |
bool
|
package version is valid for the given target. |
feu.compat.CompatRegistry.register ¶
register(
pkg_name: str,
target: Target,
*,
ranges: list[VersionRange],
exist_ok: bool = False
) -> None
Register a package configuration for a compatibility target.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name to register (e.g., |
required |
target
|
Target
|
The compatibility target. |
required |
ranges
|
list[VersionRange]
|
The list of valid version ranges for this target. An empty list means no version is valid. |
required |
exist_ok
|
bool
|
If |
False
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If a configuration already exists for the
given package name and target, and |
feu.compat.CompatRegistry.register_many ¶
register_many(
mapping: dict[str, dict[Target, list[VersionRange]]],
exist_ok: bool = False,
) -> None
Register multiple package configurations at once.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mapping
|
dict[str, dict[Target, list[VersionRange]]]
|
Mapping of package name to |
required |
exist_ok
|
bool
|
Forwarded to |
False
|
feu.compat.JaxCompatDiscoverer ¶
Bases: BaseCompatDiscoverer
Implement a specialized compatibility discoverer for jax.
jax itself ships pure-Python wheels, so its own wheel
filenames carry no OS/arch/Python-version information: the
default CompatDiscoverer would (incorrectly) consider every
jax release compatible with every target. In practice, jax
requires jaxlib, whose wheels are platform-specific and are
released in lockstep with matching jax version numbers. This
discoverer therefore only considers a jax release compatible
with a target if the jaxlib release with the same version
number shipped a wheel matching that target's Python
version/free-threaded/OS/arch axes.
Example
>>> from feu.compat.discoverers.jax import JaxCompatDiscoverer
>>> from feu.compat.target import Target
>>> discoverer = JaxCompatDiscoverer()
>>> compat = discoverer.discover(
... "jax", targets=(Target(python_version="3.11", os="linux", arch="x86_64"),)
... ) # doctest: +SKIP
feu.compat.Target
dataclass
¶
Identify the environment a package compatibility constraint applies to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
python_version
|
str
|
The Python version, e.g. |
required |
free_threaded
|
bool
|
|
False
|
os
|
str | None
|
The operating system, e.g. |
None
|
arch
|
str | None
|
The CPU architecture, e.g. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
if |
Example
>>> from feu.compat.target import Target
>>> Target(python_version="3.14", free_threaded=True, os="linux", arch="x86_64")
Target(python_version='3.14', free_threaded=True, os='linux', arch='x86_64')
feu.compat.UnsupportedVersionError ¶
Bases: Exception
Raised when no package version is compatible with a given target.
feu.compat.VersionRange ¶
Bases: NamedTuple
Represent one contiguous range of valid package versions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min
|
The minimum valid package version, or |
required | |
max
|
The maximum valid package version, or |
required |
feu.compat.WheelTags
dataclass
¶
Compatibility-relevant tags extracted from a wheel filename.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
python_version
|
str | None
|
The CPython version, e.g. |
required |
free_threaded
|
bool
|
|
required |
os
|
str | None
|
The operating system, e.g. |
required |
arch
|
str | None
|
The CPU architecture, e.g. |
required |
abi3
|
bool
|
|
False
|
feu.compat.discover_compat_targets ¶
discover_compat_targets(
pkg_name: str,
targets: Sequence[Target] = DEFAULT_TARGETS,
) -> dict[Target, list[VersionRange]]
Discover the version range compatible with each target.
Uses the compatibility discoverer registered for pkg_name in
the default global registry if one exists, otherwise falls back to
the default CompatDiscoverer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name to inspect (e.g., |
required |
targets
|
Sequence[Target]
|
The compatibility targets to compute constraints for.
Each target must have concrete (non- |
DEFAULT_TARGETS
|
Returns:
| Type | Description |
|---|---|
dict[Target, list[VersionRange]]
|
A mapping of |
Example
>>> from feu.compat import discover_compat_targets
>>> compat = discover_compat_targets("numpy") # doctest: +SKIP
feu.compat.find_closest_version ¶
find_closest_version(
pkg_name: str, pkg_version: str, target: Target
) -> str
Find the closest valid version for a package using the default registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name to check (e.g., |
required |
pkg_version
|
str
|
The requested package version. |
required |
target
|
Target
|
The compatibility target. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The closest valid version as a string. |
Example
>>> from feu.compat import find_closest_version, Target
>>> find_closest_version(
... pkg_name="numpy", pkg_version="2.0.2", target=Target(python_version="3.11")
... )
'2.0.2'
feu.compat.get_default_registry ¶
get_default_registry() -> CompatRegistry
Return the default global compatibility registry.
The registry is created on the first call and reused on all subsequent calls (singleton pattern).
Returns:
| Type | Description |
|---|---|
CompatRegistry
|
A singleton |
CompatRegistry
|
package version constraints. |
Example
>>> from feu.compat import get_default_registry, Target
>>> registry = get_default_registry()
>>> registry.is_valid_version("numpy", "2.0.2", Target(python_version="3.11"))
True
feu.compat.is_valid_version ¶
is_valid_version(
pkg_name: str, pkg_version: str, target: Target
) -> bool
Check if a package version is valid for a target using the default registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg_name
|
str
|
The package name to check (e.g., |
required |
pkg_version
|
str
|
The package version to validate. |
required |
target
|
Target
|
The compatibility target. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Example
>>> from feu.compat import is_valid_version, Target
>>> is_valid_version(
... pkg_name="numpy", pkg_version="2.0.2", target=Target(python_version="3.11")
... )
True
feu.compat.parse_wheel_filename ¶
parse_wheel_filename(filename: str) -> list[WheelTags]
Parse a PEP 427 wheel filename into compatibility tags.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename
|
str
|
The wheel filename, e.g.
|
required |
Returns:
| Type | Description |
|---|---|
list[WheelTags]
|
A list of |
Example
>>> from feu.compat.wheel_tags import parse_wheel_filename
>>> parse_wheel_filename("numpy-2.3.0-cp312-cp312-macosx_11_0_arm64.whl")
[WheelTags(python_version='3.12', free_threaded=False, os='macos', arch='arm64', abi3=False)]
feu.compat.register_compat ¶
register_compat(
mapping: dict[str, dict[Target, list[VersionRange]]],
exist_ok: bool = False,
) -> None
Register custom package configurations into the default global registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mapping
|
dict[str, dict[Target, list[VersionRange]]]
|
Mapping of package name to |
required |
exist_ok
|
bool
|
If |
False
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If any entry is already registered and
|
Example
>>> from feu.compat import register_compat, Target, VersionRange
>>> register_compat(
... {"my_package": {Target(python_version="3.11"): [VersionRange("1.0.0", None)]}}
... )
feu.compat.resolve_target ¶
resolve_target(
python_version: str | None = None,
free_threaded: bool | None = None,
os: str | None = None,
arch: str | None = None,
) -> Target
Resolve a Target from optional, possibly partial inputs.
If python_version ends with t, the target is a
free-threaded build. In that case, free_threaded=False is
invalid because it contradicts the t suffix. Any unspecified
argument falls back to the current interpreter/environment value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
python_version
|
str | None
|
The Python version, e.g. |
None
|
free_threaded
|
bool | None
|
Whether the target is a free-threaded build.
If not provided, it is inferred from |
None
|
os
|
str | None
|
The target OS. If not provided, the current OS is used. |
None
|
arch
|
str | None
|
The target CPU architecture. If not provided, the current architecture is used. |
None
|
Returns:
| Type | Description |
|---|---|
Target
|
The resolved target. |
Raises:
| Type | Description |
|---|---|
ValueError
|
if |
Example
>>> from feu.compat.target import resolve_target
>>> resolve_target(python_version="3.14t", os="linux", arch="x86_64")
Target(python_version='3.14', free_threaded=True, os='linux', arch='x86_64')
feu.compat.show_compat_targets ¶
show_compat_targets(
compat: dict[Target, list[VersionRange]],
pkg_name: str | None = None,
) -> None
Print the output of discover_compat_targets as a table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
compat
|
dict[Target, list[VersionRange]]
|
The mapping of |
required |
pkg_name
|
str | None
|
The package name to show in the table title, if any. |
None
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
if the |
Example
>>> from feu.compat import discover_compat_targets, show_compat_targets
>>> compat = discover_compat_targets("numpy") # doctest: +SKIP
>>> show_compat_targets(compat, pkg_name="numpy") # doctest: +SKIP