Is there a standard way to allow a requirement of a python package to fail in a packages setup script?
I am creating a package similar to Python Social Auth in that it has a number of providers.
Is there a standard way to allow the installation requirements of some of the providers to fail, but still have the package install just fine?
Optional dependencies specified by user at installation time:
You can use the extras_require
parameter to setup()
: http://pythonhosted.org/setuptools/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies
setup(
name="MyProject",
...
extras_require = {
'ProviderX': ["DependencyX1", "DependencyX2"],
'ProviderY': ["DependencyY"],
}
)
With this method, the user can ask to install specific extensions pip install Myproject[ProviderX]
.
Optional dependencies based on existing packages:
In order to automatically detect installed packages, you can build the list of requirements dynamically. For example, you can look at how matplotlib does this (they have many optional backends for plotting amongst others): https://github.com/matplotlib/matplotlib.
Basically, setup.py is just regular python code, so you can run a function which checks for the optional dependencies, and adjust requirements and your package list to be installed accordingly.
The way matplotlib does this is by defining a class for dependencies which it extends for each dependency (in setupExt.py).
class SetupPackage(object):
optional = False
def check(self):
"""
Checks whether the dependencies are met. [...]
"""
pass
def get_packages(self):
"""
Get a list of package names to add to the configuration.
These are added to the `packages` list passed to
`distutils.setup`.
"""
return []
def get_namespace_packages(self):
"""
Get a list of namespace package names to add to the configuration.
These are added to the `namespace_packages` list passed to
`distutils.setup`.
"""
return []
def get_py_modules(self):
"""
Get a list of top-level modules to add to the configuration.
These are added to the `py_modules` list passed to
`distutils.setup`.
"""
return []
...
class Numpy(SetupPackage):
...
It then iterates over each dependency in setup.py, checks whether it should be installed, and accordingly extends each list to be passed to setup()
mpl_packages = [
'Building Matplotlib',
setupext.Six(),
setupext.Dateutil(),
...
good_packages = []
for package in mpl_packages:
[...]
# check and append
if ...
good_packages.append(package)
[...]
for package in good_packages:
if isinstance(package, str):
continue
packages.extend(package.get_packages())
namespace_packages.extend(package.get_namespace_packages())
py_modules.extend(package.get_py_modules())
ext = package.get_extension()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With