Skip to content

Install

feu.install

Contain package installers.

feu.install.BaseInstaller

Bases: ABC

Define the base class to implement a package installer.

A concrete installer must implement equal, install, and instantiate_with_arguments. Installers are registered by name in InstallerRegistry.

Example
>>> from feu.install.pip import PipInstaller
>>> from feu.utils.package import PackageSpec
>>> installer = PipInstaller()
>>> installer
PipInstaller(arguments='')
>>> installer.install(PackageSpec(name="pandas", version="2.2.2"))  # doctest: +SKIP

feu.install.BaseInstaller.equal abstractmethod

equal(other: Any) -> bool

Indicate if two installers are equal or not.

Parameters:

Name Type Description Default
other Any

The other object to compare.

required

Returns:

Type Description
bool

True if the two installers are equal, otherwise False.

Example
>>> from feu.install.pip import PipInstaller
>>> from feu.utils.package import PackageSpec
>>> obj1 = PipInstaller()
>>> obj2 = PipInstaller()
>>> obj3 = PipInstaller("-U")
>>> obj1.equal(obj2)
True
>>> obj1.equal(obj3)
False

feu.install.BaseInstaller.install abstractmethod

install(package: PackageSpec) -> None

Install the given package.

Parameters:

Name Type Description Default
package PackageSpec

The package specification of the package to install.

required
Example
>>> from feu.install.pip import PipInstaller
>>> from feu.utils.package import PackageSpec
>>> installer = PipInstaller()
>>> installer.install(PackageSpec(name="pandas", version="2.2.2"))  # doctest: +SKIP

feu.install.BaseInstaller.instantiate_with_arguments abstractmethod classmethod

instantiate_with_arguments(arguments: str) -> Self

Instantiate an installer instance with custom arguments.

Parameters:

Name Type Description Default
arguments str

The installer arguments.

required

Returns:

Type Description
Self

An instantiated installer.

Example
>>> from feu.install.pip import PipInstaller
>>> installer = PipInstaller.instantiate_with_arguments("-U")
>>> installer
PipInstaller(arguments='-U')

feu.install.InstallResult

Bases: NamedTuple

Represent the outcome of installing multiple versions of a package.

Parameters:

Name Type Description Default
installed

The versions that were installed successfully.

required
failed

The versions for which the installation failed.

required

feu.install.InstallerRegistry

Implement the main installer registry.

The registry maps an installer name to an installer class. It is shared by the whole process. The installers "pip", "pipx" and "uv" are registered by default.

Example
>>> from feu.install import InstallerRegistry
>>> InstallerRegistry.has_installer("uv")
True

feu.install.InstallerRegistry.add_installer classmethod

add_installer(
    name: str,
    installer: type[BaseInstaller],
    exist_ok: bool = False,
) -> None

Add an installer class for a given installer name.

Parameters:

Name Type Description Default
name str

The installer name e.g. "pip" or "uv".

required
installer type[BaseInstaller]

The installer class used for the given name.

required
exist_ok bool

If False, RuntimeError is raised if the installer already exists. This parameter should be set to True to overwrite the installer for a name.

False

Raises:

Type Description
RuntimeError

if an installer is already registered for the name and exist_ok=False.

Example
>>> from feu.install import InstallerRegistry
>>> from feu.install.pip import PipInstaller
>>> InstallerRegistry.add_installer("pip", PipInstaller, exist_ok=True)

feu.install.InstallerRegistry.has_installer classmethod

has_installer(name: str) -> bool

Indicate if an installer is registered for the given name.

Parameters:

Name Type Description Default
name str

The installer name.

required

Returns:

Type Description
bool

True if an installer is registered, otherwise False.

Example
>>> from feu.install import InstallerRegistry
>>> InstallerRegistry.has_installer("pip")
True

feu.install.InstallerRegistry.install classmethod

install(
    installer: InstallerSpec, package: PackageSpec
) -> None

Install a package and associated packages by using the specified installer.

Parameters:

Name Type Description Default
installer InstallerSpec

The installer specification.

required
package PackageSpec

The package specification.

required

Raises:

Type Description
RuntimeError

if no installer is registered for the given installer name.

Example
>>> from feu.install import InstallerRegistry
>>> from feu.utils.installer import InstallerSpec
>>> from feu.utils.package import PackageSpec
>>> InstallerRegistry.install(
...     installer=InstallerSpec("pip"), package=PackageSpec(name="pandas", version="2.2.2")
... )  # doctest: +SKIP

feu.install.get_available_installers cached

get_available_installers() -> tuple[str, ...]

Get the available installers.

The result is cached.

Returns:

Type Description
tuple[str, ...]

The names of the installers found on the PATH, among "pip", "pipx" and "uv".

Example
>>> from feu.install import get_available_installers
>>> get_available_installers()
(...)

feu.install.get_installable_versions

get_installable_versions(
    pkg_name: str,
    target: Target,
    start_date: date | str | None = None,
) -> list[str]

Get the stable package versions compatible with a target.

Parameters:

Name Type Description Default
pkg_name str

The package name to inspect (e.g., "numpy").

required
target Target

The compatibility target.

required
start_date date | str | None

If specified, only the versions released on or after this date are considered. The date can be a date object or an ISO 8601 formatted string e.g. '2024-01-01'.

None

Returns:

Type Description
list[str]

The stable versions of the package that are valid for the given target. The versions are in the order returned by fetch_pypi_versions (sorted as strings), so use sort_versions to sort them by version.

Example
>>> from feu.compat import Target
>>> from feu.install import get_installable_versions
>>> versions = get_installable_versions(
...     "numpy", target=Target(python_version="3.11")
... )  # doctest: +SKIP

feu.install.install_all_versions

install_all_versions(
    installer: InstallerSpec,
    package: str,
    target: Target,
    start_date: date | str | None = None,
) -> InstallResult

Install all the versions of a package that are compatible with a target, one after the other.

A failure to install one version does not stop the installation of the remaining versions. The failure is logged.

Parameters:

Name Type Description Default
installer InstallerSpec

The installer specification.

required
package str

The package to install, optionally with extras e.g. "pandas[performance]".

required
target Target

The compatibility target.

required
start_date date | str | None

If specified, only the versions released on or after this date are installed. The date can be a date object or an ISO 8601 formatted string e.g. '2024-01-01'.

None

Returns:

Type Description
InstallResult

The versions that were installed successfully and the versions for which the installation failed.

Example
>>> from feu.compat import Target
>>> from feu.install import install_all_versions
>>> from feu.utils.installer import InstallerSpec
>>> result = install_all_versions(
...     installer=InstallerSpec("pip"),
...     package="pandas[performance]",
...     target=Target(python_version="3.11"),
... )  # doctest: +SKIP

feu.install.install_package

install_package(
    installer: InstallerSpec, package: PackageSpec
) -> None

Install a package with the specified installer.

The package is installed as specified, without any version compatibility check. Use install_package_closest_version to install the closest compatible version.

Parameters:

Name Type Description Default
installer InstallerSpec

The installer specification.

required
package PackageSpec

The package specification.

required

Raises:

Type Description
RuntimeError

If no installer is registered for the installer name.

CalledProcessError

If the installation command fails.

Example
>>> from feu.install import install_package
>>> from feu.utils.installer import InstallerSpec
>>> from feu.utils.package import PackageSpec
>>> install_package(
...     installer=InstallerSpec("pip"), package=PackageSpec(name="pandas", version="2.2.2")
... )  # doctest: +SKIP

feu.install.install_package_closest_version

install_package_closest_version(
    installer: InstallerSpec, package: PackageSpec
) -> None

Install a package and associated packages by using the specified installer.

This function finds the closest valid version if the specified version is not compatible with the current Python version (the OS and the CPU architecture are not considered). A wildcard version (e.g. '2.12.*') cannot be checked against the compatibility registry, so the package is installed as specified.

Parameters:

Name Type Description Default
installer InstallerSpec

The installer specification.

required
package PackageSpec

The package specification.

required

Raises:

Type Description
RuntimeError

If no package version is specified, or if no installer is registered for the installer name.

UnsupportedVersionError

If no version of the package is valid for the current Python version.

CalledProcessError

If the installation command fails.

Example
>>> from feu.install import install_package_closest_version
>>> from feu.utils.installer import InstallerSpec
>>> from feu.utils.package import PackageSpec
>>> install_package_closest_version(
...     installer=InstallerSpec("pip"), package=PackageSpec(name="pandas", version="2.2.2")
... )  # doctest: +SKIP

feu.install.install_packages_all_versions

install_packages_all_versions(
    installer: InstallerSpec,
    packages: Sequence[str],
    target: Target,
    start_date: date | str | None = None,
) -> dict[str, InstallResult]

Install all the versions of each package in a list that are compatible with a target.

A failure to install one version of one package does not stop the installation of the remaining versions or packages.

Parameters:

Name Type Description Default
installer InstallerSpec

The installer specification.

required
packages Sequence[str]

The packages to install, optionally with extras e.g. "pandas[performance]".

required
target Target

The compatibility target.

required
start_date date | str | None

If specified, only the versions released on or after this date are installed. The date can be a date object or an ISO 8601 formatted string e.g. '2024-01-01'.

None

Returns:

Type Description
dict[str, InstallResult]

A mapping of package to the versions that were installed successfully and the versions for which the installation failed.

Example
>>> from feu.compat import Target
>>> from feu.install import install_packages_all_versions
>>> from feu.utils.installer import InstallerSpec
>>> results = install_packages_all_versions(
...     installer=InstallerSpec("pip"),
...     packages=["numpy", "pandas[performance]"],
...     target=Target(python_version="3.11"),
... )  # doctest: +SKIP

feu.install.is_pip_available cached

is_pip_available() -> bool

Check if pip is available.

The result is cached.

Returns:

Type Description
bool

True if pip is available, otherwise False.

Example
>>> from feu.install import is_pip_available
>>> is_pip_available()

feu.install.is_pipx_available cached

is_pipx_available() -> bool

Check if pipx is available.

The result is cached.

Returns:

Type Description
bool

True if pipx is available, otherwise False.

Example
>>> from feu.install import is_pipx_available
>>> is_pipx_available()

feu.install.is_uv_available cached

is_uv_available() -> bool

Check if uv is available.

The result is cached.

Returns:

Type Description
bool

True if uv is available, otherwise False.

Example
>>> from feu.install import is_uv_available
>>> is_uv_available()

feu.install.pip

Contain functionalities to install packages with pip or compatible package installers.

feu.install.pip.PipInstaller

Bases: BasePipInstaller

Implement a pip package installer.

The package dependencies are resolved first, and then installed with a single pip install command.

Parameters:

Name Type Description Default
arguments str

Optional arguments to pass to pip install, e.g. "--upgrade". Leading and trailing whitespace is removed.

''
Example
>>> from feu.install.pip import PipInstaller
>>> from feu.utils.package import PackageSpec
>>> installer = PipInstaller()
>>> installer
PipInstaller(arguments='')
>>> installer.install(PackageSpec(name="pandas", version="2.2.2"))  # doctest: +SKIP

feu.install.pip.PipxInstaller

Bases: BasePipInstaller

Implement a pipx package installer.

The package dependencies are resolved first, and then installed with a single pipx install command.

Parameters:

Name Type Description Default
arguments str

Optional arguments to pass to pipx install, e.g. "--upgrade". Leading and trailing whitespace is removed.

''
Example
>>> from feu.install.pip import PipxInstaller
>>> from feu.utils.package import PackageSpec
>>> installer = PipxInstaller()
>>> installer
PipxInstaller(arguments='')
>>> installer.install(PackageSpec(name="pandas", version="2.2.2"))  # doctest: +SKIP

feu.install.pip.UvInstaller

Bases: BasePipInstaller

Implement a uv package installer.

The package dependencies are resolved first, and then installed with a single uv pip install command.

Parameters:

Name Type Description Default
arguments str

Optional arguments to pass to uv pip install, e.g. "--upgrade". Leading and trailing whitespace is removed.

''
Example
>>> from feu.install.pip import UvInstaller
>>> from feu.utils.package import PackageSpec
>>> installer = UvInstaller()
>>> installer
UvInstaller(arguments='')
>>> installer.install(PackageSpec(name="pandas", version="2.2.2"))  # doctest: +SKIP

feu.install.pip.installer

Define the pip compatible installers.

feu.install.pip.installer.BasePipInstaller

Bases: BaseInstaller

Define an intermediate base class to implement pip compatible package installer.

Parameters:

Name Type Description Default
arguments str

Optional arguments to pass to the package installer. The valid arguments depend on the package installer.

''
Example
>>> from feu.install.pip.installer import BasePipInstaller
>>> from feu.utils.package import PackageSpec, PackageDependency
>>> class MyInstaller(BasePipInstaller):
...     def _generate_command(self, deps, args):
...         return f"echo Installing {', '.join(map(str, deps))} with args: {args}"
...
>>> installer = MyInstaller(arguments="--verbose")
>>> installer
MyInstaller(arguments='--verbose')
>>> installer.install(PackageSpec(name="pandas", version="2.2.2"))  # doctest: +SKIP

feu.install.pip.installer.PipInstaller

Bases: BasePipInstaller

Implement a pip package installer.

The package dependencies are resolved first, and then installed with a single pip install command.

Parameters:

Name Type Description Default
arguments str

Optional arguments to pass to pip install, e.g. "--upgrade". Leading and trailing whitespace is removed.

''
Example
>>> from feu.install.pip import PipInstaller
>>> from feu.utils.package import PackageSpec
>>> installer = PipInstaller()
>>> installer
PipInstaller(arguments='')
>>> installer.install(PackageSpec(name="pandas", version="2.2.2"))  # doctest: +SKIP

feu.install.pip.installer.PipxInstaller

Bases: BasePipInstaller

Implement a pipx package installer.

The package dependencies are resolved first, and then installed with a single pipx install command.

Parameters:

Name Type Description Default
arguments str

Optional arguments to pass to pipx install, e.g. "--upgrade". Leading and trailing whitespace is removed.

''
Example
>>> from feu.install.pip import PipxInstaller
>>> from feu.utils.package import PackageSpec
>>> installer = PipxInstaller()
>>> installer
PipxInstaller(arguments='')
>>> installer.install(PackageSpec(name="pandas", version="2.2.2"))  # doctest: +SKIP

feu.install.pip.installer.UvInstaller

Bases: BasePipInstaller

Implement a uv package installer.

The package dependencies are resolved first, and then installed with a single uv pip install command.

Parameters:

Name Type Description Default
arguments str

Optional arguments to pass to uv pip install, e.g. "--upgrade". Leading and trailing whitespace is removed.

''
Example
>>> from feu.install.pip import UvInstaller
>>> from feu.utils.package import PackageSpec
>>> installer = UvInstaller()
>>> installer
UvInstaller(arguments='')
>>> installer.install(PackageSpec(name="pandas", version="2.2.2"))  # doctest: +SKIP

feu.install.pip.resolver

Contain pip compatible package dependency resolvers.

feu.install.pip.resolver.BaseDependencyResolver

Bases: ABC

Define the base class for pip-compatible package dependency resolvers.

Example
>>> from feu.install.pip.resolver import DependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = DependencyResolver()
>>> resolver
DependencyResolver()
>>> deps = resolver.resolve(PackageSpec(name="my_package", version="1.2.3"))
>>> deps
[PackageDependency(name='my_package', version_specifiers=['==1.2.3'], extras=None)]

feu.install.pip.resolver.BaseDependencyResolver.equal abstractmethod

equal(other: Any) -> bool

Indicate if two dependency resolvers are equal or not.

Parameters:

Name Type Description Default
other Any

The other object to compare.

required

Returns:

Type Description
bool

True if the two dependency resolvers are equal, otherwise False.

Example
>>> from feu.install.pip.resolver import DependencyResolver, TorchDependencyResolver
>>> from feu.utils.package import PackageSpec
>>> obj1 = DependencyResolver()
>>> obj2 = DependencyResolver()
>>> obj3 = TorchDependencyResolver()
>>> obj1.equal(obj2)
True
>>> obj1.equal(obj3)
False

feu.install.pip.resolver.BaseDependencyResolver.resolve abstractmethod

resolve(package: PackageSpec) -> list[PackageDependency]

Find the dependency packages to install a specific package.

Parameters:

Name Type Description Default
package PackageSpec

The target package to install.

required

Returns:

Type Description
list[PackageDependency]

The list of package dependencies.

Example
>>> from feu.install.pip.resolver import DependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = DependencyResolver()
>>> deps = resolver.resolve(PackageSpec(name="my_package", version="1.2.3"))
>>> deps
[PackageDependency(name='my_package', version_specifiers=['==1.2.3'], extras=None)]

feu.install.pip.resolver.DependencyResolver

Bases: BaseDependencyResolver

Define the default package dependency resolver.

Example
>>> from feu.install.pip.resolver import DependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = DependencyResolver()
>>> resolver
DependencyResolver()
>>> deps = resolver.resolve(PackageSpec(name="my_package", version="1.2.3"))
>>> deps
[PackageDependency(name='my_package', version_specifiers=['==1.2.3'], extras=None)]

feu.install.pip.resolver.DependencyResolverRegistry

Implement the main dependency resolver registry.

The dependency resolvers are indexed by name.

feu.install.pip.resolver.DependencyResolverRegistry.add_resolver classmethod

add_resolver(
    package: PackageSpec,
    resolver: BaseDependencyResolver,
    exist_ok: bool = False,
) -> None

Add a dependency resolver for a given package.

Parameters:

Name Type Description Default
package PackageSpec

The package specification.

required
resolver BaseDependencyResolver

The resolver used for the given package.

required
exist_ok bool

If False, RuntimeError is raised if the package already exists. This parameter should be set to True to overwrite the resolver for a package.

False

Raises:

Type Description
RuntimeError

if a dependency resolver is already registered for the package name and exist_ok=False.

Example
>>> from feu.install.pip.resolver import (
...     DependencyResolverRegistry,
...     TorchDependencyResolver,
... )
>>> from feu.utils.package import PackageSpec
>>> DependencyResolverRegistry.add_resolver(
...     PackageSpec("torch"), TorchDependencyResolver(), exist_ok=True
... )

feu.install.pip.resolver.DependencyResolverRegistry.find_resolver classmethod

find_resolver(
    package: PackageSpec,
) -> BaseDependencyResolver

Find the relevant dependency resolver for the given package.

Parameters:

Name Type Description Default
package PackageSpec

The package specification.

required

Returns:

Type Description
BaseDependencyResolver

The dependency resolver for the package.

Example
>>> from feu.install.pip.resolver import DependencyResolverRegistry
>>> from feu.utils.package import PackageSpec
>>> resolver = DependencyResolverRegistry.find_resolver(PackageSpec("torch"))
>>> resolver
TorchDependencyResolver(min_version=2.3.0)

feu.install.pip.resolver.DependencyResolverRegistry.has_resolver classmethod

has_resolver(package: PackageSpec) -> bool

Indicate if a dependency resolver is registered for the given package specification.

Parameters:

Name Type Description Default
package PackageSpec

The package specification.

required

Returns:

Type Description
bool

True if a dependency resolver is registered, otherwise False.

Example
>>> from feu.install.pip.resolver import DependencyResolverRegistry
>>> from feu.utils.package import PackageSpec
>>> DependencyResolverRegistry.has_resolver(PackageSpec("torch"))
True

feu.install.pip.resolver.JaxDependencyResolver

Bases: DependencyResolver

Implement the jax dependency resolver.

numpy 2.0 support was added in jax 0.4.26.

Example
>>> from feu.install.pip.resolver import JaxDependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = JaxDependencyResolver()
>>> resolver
JaxDependencyResolver()
>>> deps = resolver.resolve(PackageSpec(name="jax", version="0.4.26"))
>>> deps
[PackageDependency(name='jax', version_specifiers=['==0.4.26'], extras=None),
 PackageDependency(name='jaxlib', version_specifiers=['==0.4.26'], extras=None)]
>>> deps = resolver.resolve(PackageSpec(name="jax", version="0.4.25"))
>>> deps
[PackageDependency(name='jax', version_specifiers=['==0.4.25'], extras=None),
 PackageDependency(name='jaxlib', version_specifiers=['==0.4.25'], extras=None),
 PackageDependency(name='numpy', version_specifiers=['<2.0.0'], extras=None)]

feu.install.pip.resolver.MatplotlibDependencyResolver

Bases: Numpy2DependencyResolver

Implement the matplotlib dependency resolver.

numpy 2.0 support was added in matplotlib 3.8.4.

Example
>>> from feu.install.pip.resolver import MatplotlibDependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = MatplotlibDependencyResolver()
>>> resolver
MatplotlibDependencyResolver(min_version=3.8.4)
>>> deps = resolver.resolve(PackageSpec(name="matplotlib", version="3.8.4"))
>>> deps
[PackageDependency(name='matplotlib', version_specifiers=['==3.8.4'], extras=None)]
>>> deps = resolver.resolve(PackageSpec(name="matplotlib", version="3.8.3"))
>>> deps
[PackageDependency(name='matplotlib', version_specifiers=['==3.8.3'], extras=None),
 PackageDependency(name='numpy', version_specifiers=['<2.0.0'], extras=None)]

feu.install.pip.resolver.Numpy2DependencyResolver

Bases: DependencyResolver

Define a dependency resolver to work with packages that did not pin numpy<2.0 and are not fully compatible with numpy 2.0.

https://github.com/numpy/numpy/issues/26191 indicates the packages that are compatible with numpy 2.0.

Parameters:

Name Type Description Default
min_version str

The first version that is fully compatible with numpy 2.0.

required
Example
>>> from feu.install.pip.resolver import Numpy2DependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = Numpy2DependencyResolver(min_version="1.2.3")
>>> resolver
Numpy2DependencyResolver(min_version=1.2.3)
>>> deps = resolver.resolve(PackageSpec(name="my_package", version="1.2.3"))
>>> deps
[PackageDependency(name='my_package', version_specifiers=['==1.2.3'], extras=None)]
>>> deps = resolver.resolve(PackageSpec(name="my_package", version="1.2.2"))
>>> deps
[PackageDependency(name='my_package', version_specifiers=['==1.2.2'], extras=None),
 PackageDependency(name='numpy', version_specifiers=['<2.0.0'], extras=None)]

feu.install.pip.resolver.PandasDependencyResolver

Bases: Numpy2DependencyResolver

Implement the pandas dependency resolver.

numpy 2.0 support was added in pandas 2.2.2.

Example
>>> from feu.install.pip.resolver import PandasDependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = PandasDependencyResolver()
>>> resolver
PandasDependencyResolver(min_version=2.2.2)
>>> deps = resolver.resolve(PackageSpec(name="pandas", version="2.2.2"))
>>> deps
[PackageDependency(name='pandas', version_specifiers=['==2.2.2'], extras=None)]
>>> deps = resolver.resolve(PackageSpec(name="pandas", version="2.2.1"))
>>> deps
[PackageDependency(name='pandas', version_specifiers=['==2.2.1'], extras=None),
 PackageDependency(name='numpy', version_specifiers=['<2.0.0'], extras=None)]

feu.install.pip.resolver.PyarrowDependencyResolver

Bases: Numpy2DependencyResolver

Implement the pyarrow dependency resolver.

numpy 2.0 support was added in pyarrow 16.0.

Example
>>> from feu.install.pip.resolver import PyarrowDependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = PyarrowDependencyResolver()
>>> resolver
PyarrowDependencyResolver(min_version=16.0)
>>> deps = resolver.resolve(PackageSpec(name="pyarrow", version="16.0"))
>>> deps
[PackageDependency(name='pyarrow', version_specifiers=['==16.0'], extras=None)]
>>> deps = resolver.resolve(PackageSpec(name="pyarrow", version="15.0"))
>>> deps
[PackageDependency(name='pyarrow', version_specifiers=['==15.0'], extras=None),
 PackageDependency(name='numpy', version_specifiers=['<2.0.0'], extras=None)]

feu.install.pip.resolver.ScipyDependencyResolver

Bases: Numpy2DependencyResolver

Implement the scipy dependency resolver.

numpy 2.0 support was added in scipy 1.13.0.

Example
>>> from feu.install.pip.resolver import ScipyDependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = ScipyDependencyResolver()
>>> resolver
ScipyDependencyResolver(min_version=1.13.0)
>>> deps = resolver.resolve(PackageSpec(name="scipy", version="1.13.0"))
>>> deps
[PackageDependency(name='scipy', version_specifiers=['==1.13.0'], extras=None)]
>>> deps = resolver.resolve(PackageSpec(name="scipy", version="1.12.0"))
>>> deps
[PackageDependency(name='scipy', version_specifiers=['==1.12.0'], extras=None),
 PackageDependency(name='numpy', version_specifiers=['<2.0.0'], extras=None)]

feu.install.pip.resolver.SklearnDependencyResolver

Bases: Numpy2DependencyResolver

Implement the scikit-learn dependency resolver.

numpy 2.0 support was added in scikit-learn 1.4.2.

Example
>>> from feu.install.pip.resolver import SklearnDependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = SklearnDependencyResolver()
>>> resolver
SklearnDependencyResolver(min_version=1.4.2)
>>> deps = resolver.resolve(PackageSpec(name="scikit-learn", version="1.4.2"))
>>> deps
[PackageDependency(name='scikit-learn', version_specifiers=['==1.4.2'], extras=None)]
>>> deps = resolver.resolve(PackageSpec(name="scikit-learn", version="1.4.1"))
>>> deps
[PackageDependency(name='scikit-learn', version_specifiers=['==1.4.1'], extras=None),
 PackageDependency(name='numpy', version_specifiers=['<2.0.0'], extras=None)]

feu.install.pip.resolver.TorchDependencyResolver

Bases: Numpy2DependencyResolver

Implement the torch dependency resolver.

numpy 2.0 support was added in torch 2.3.0.

Example
>>> from feu.install.pip.resolver import TorchDependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = TorchDependencyResolver()
>>> resolver
TorchDependencyResolver(min_version=2.3.0)
>>> deps = resolver.resolve(PackageSpec(name="torch", version="2.3.0"))
>>> deps
[PackageDependency(name='torch', version_specifiers=['==2.3.0'], extras=None)]
>>> deps = resolver.resolve(PackageSpec(name="torch", version="2.2.0"))
>>> deps
[PackageDependency(name='torch', version_specifiers=['==2.2.0'], extras=None),
 PackageDependency(name='numpy', version_specifiers=['<2.0.0'], extras=None)]

feu.install.pip.resolver.XarrayDependencyResolver

Bases: Numpy2DependencyResolver

Implement the xarray dependency resolver.

numpy 2.0 support was added in xarray 2024.6.0.

Example
>>> from feu.install.pip.resolver import XarrayDependencyResolver
>>> from feu.utils.package import PackageSpec
>>> resolver = XarrayDependencyResolver()
>>> resolver
XarrayDependencyResolver(min_version=2024.6.0)
>>> deps = resolver.resolve(PackageSpec(name="xarray", version="2024.6.0"))
>>> deps
[PackageDependency(name='xarray', version_specifiers=['==2024.6.0'], extras=None)]
>>> deps = resolver.resolve(PackageSpec(name="xarray", version="2024.5.0"))
>>> deps
[PackageDependency(name='xarray', version_specifiers=['==2024.5.0'], extras=None),
 PackageDependency(name='numpy', version_specifiers=['<2.0.0'], extras=None)]

feu.install.utils

Contain utility functions to install packages.

feu.install.utils.InstallResult

Bases: NamedTuple

Represent the outcome of installing multiple versions of a package.

Parameters:

Name Type Description Default
installed

The versions that were installed successfully.

required
failed

The versions for which the installation failed.

required

feu.install.utils.get_available_installers cached

get_available_installers() -> tuple[str, ...]

Get the available installers.

The result is cached.

Returns:

Type Description
tuple[str, ...]

The names of the installers found on the PATH, among "pip", "pipx" and "uv".

Example
>>> from feu.install import get_available_installers
>>> get_available_installers()
(...)

feu.install.utils.get_installable_versions

get_installable_versions(
    pkg_name: str,
    target: Target,
    start_date: date | str | None = None,
) -> list[str]

Get the stable package versions compatible with a target.

Parameters:

Name Type Description Default
pkg_name str

The package name to inspect (e.g., "numpy").

required
target Target

The compatibility target.

required
start_date date | str | None

If specified, only the versions released on or after this date are considered. The date can be a date object or an ISO 8601 formatted string e.g. '2024-01-01'.

None

Returns:

Type Description
list[str]

The stable versions of the package that are valid for the given target. The versions are in the order returned by fetch_pypi_versions (sorted as strings), so use sort_versions to sort them by version.

Example
>>> from feu.compat import Target
>>> from feu.install import get_installable_versions
>>> versions = get_installable_versions(
...     "numpy", target=Target(python_version="3.11")
... )  # doctest: +SKIP

feu.install.utils.install_all_versions

install_all_versions(
    installer: InstallerSpec,
    package: str,
    target: Target,
    start_date: date | str | None = None,
) -> InstallResult

Install all the versions of a package that are compatible with a target, one after the other.

A failure to install one version does not stop the installation of the remaining versions. The failure is logged.

Parameters:

Name Type Description Default
installer InstallerSpec

The installer specification.

required
package str

The package to install, optionally with extras e.g. "pandas[performance]".

required
target Target

The compatibility target.

required
start_date date | str | None

If specified, only the versions released on or after this date are installed. The date can be a date object or an ISO 8601 formatted string e.g. '2024-01-01'.

None

Returns:

Type Description
InstallResult

The versions that were installed successfully and the versions for which the installation failed.

Example
>>> from feu.compat import Target
>>> from feu.install import install_all_versions
>>> from feu.utils.installer import InstallerSpec
>>> result = install_all_versions(
...     installer=InstallerSpec("pip"),
...     package="pandas[performance]",
...     target=Target(python_version="3.11"),
... )  # doctest: +SKIP

feu.install.utils.install_package

install_package(
    installer: InstallerSpec, package: PackageSpec
) -> None

Install a package with the specified installer.

The package is installed as specified, without any version compatibility check. Use install_package_closest_version to install the closest compatible version.

Parameters:

Name Type Description Default
installer InstallerSpec

The installer specification.

required
package PackageSpec

The package specification.

required

Raises:

Type Description
RuntimeError

If no installer is registered for the installer name.

CalledProcessError

If the installation command fails.

Example
>>> from feu.install import install_package
>>> from feu.utils.installer import InstallerSpec
>>> from feu.utils.package import PackageSpec
>>> install_package(
...     installer=InstallerSpec("pip"), package=PackageSpec(name="pandas", version="2.2.2")
... )  # doctest: +SKIP

feu.install.utils.install_package_closest_version

install_package_closest_version(
    installer: InstallerSpec, package: PackageSpec
) -> None

Install a package and associated packages by using the specified installer.

This function finds the closest valid version if the specified version is not compatible with the current Python version (the OS and the CPU architecture are not considered). A wildcard version (e.g. '2.12.*') cannot be checked against the compatibility registry, so the package is installed as specified.

Parameters:

Name Type Description Default
installer InstallerSpec

The installer specification.

required
package PackageSpec

The package specification.

required

Raises:

Type Description
RuntimeError

If no package version is specified, or if no installer is registered for the installer name.

UnsupportedVersionError

If no version of the package is valid for the current Python version.

CalledProcessError

If the installation command fails.

Example
>>> from feu.install import install_package_closest_version
>>> from feu.utils.installer import InstallerSpec
>>> from feu.utils.package import PackageSpec
>>> install_package_closest_version(
...     installer=InstallerSpec("pip"), package=PackageSpec(name="pandas", version="2.2.2")
... )  # doctest: +SKIP

feu.install.utils.install_packages_all_versions

install_packages_all_versions(
    installer: InstallerSpec,
    packages: Sequence[str],
    target: Target,
    start_date: date | str | None = None,
) -> dict[str, InstallResult]

Install all the versions of each package in a list that are compatible with a target.

A failure to install one version of one package does not stop the installation of the remaining versions or packages.

Parameters:

Name Type Description Default
installer InstallerSpec

The installer specification.

required
packages Sequence[str]

The packages to install, optionally with extras e.g. "pandas[performance]".

required
target Target

The compatibility target.

required
start_date date | str | None

If specified, only the versions released on or after this date are installed. The date can be a date object or an ISO 8601 formatted string e.g. '2024-01-01'.

None

Returns:

Type Description
dict[str, InstallResult]

A mapping of package to the versions that were installed successfully and the versions for which the installation failed.

Example
>>> from feu.compat import Target
>>> from feu.install import install_packages_all_versions
>>> from feu.utils.installer import InstallerSpec
>>> results = install_packages_all_versions(
...     installer=InstallerSpec("pip"),
...     packages=["numpy", "pandas[performance]"],
...     target=Target(python_version="3.11"),
... )  # doctest: +SKIP

feu.install.utils.is_pip_available cached

is_pip_available() -> bool

Check if pip is available.

The result is cached.

Returns:

Type Description
bool

True if pip is available, otherwise False.

Example
>>> from feu.install import is_pip_available
>>> is_pip_available()

feu.install.utils.is_pipx_available cached

is_pipx_available() -> bool

Check if pipx is available.

The result is cached.

Returns:

Type Description
bool

True if pipx is available, otherwise False.

Example
>>> from feu.install import is_pipx_available
>>> is_pipx_available()

feu.install.utils.is_uv_available cached

is_uv_available() -> bool

Check if uv is available.

The result is cached.

Returns:

Type Description
bool

True if uv is available, otherwise False.

Example
>>> from feu.install import is_uv_available
>>> is_uv_available()