If pip finds that this specific dependency isn't installed, I want to either abort the install...
If I understand you correctly, you could check if the proprietary package is installed by simply trying to import a module from that package in your setup.py
, aborting on ImportError
. As an example, let's say your dependency that should abort the installation is numpy
:
from distutils.command.build import build as build_orig
from distutils.errors import DistutilsModuleError
from setuptools import setup
class build(build_orig):
def finalize_options(self):
try:
import numpy
except ImportError:
raise DistutilsModuleError('numpy is not installed. Installation will be aborted.')
super().finalize_options()
setup(
name='spam',
version='0.1',
author='nobody',
author_email='nobody@nowhere.com',
packages=[],
install_requires=[
# all the other dependencies except numpy go here as usual
],
cmdclass={'build': build,},
)
Now, you should distribute your package as source tar because wheels won't invoke setup.py
on installation:
$ python setup.py sdist
Trying to install the built tar when numpy
is missing will result in:
$ pip install dist/spam-0.1.tar.gz
Processing ./dist/spam-0.1.tar.gz
Complete output from command python setup.py egg_info:
running egg_info
creating pip-egg-info/spam.egg-info
writing pip-egg-info/spam.egg-info/PKG-INFO
writing dependency_links to pip-egg-info/spam.egg-info/dependency_links.txt
writing top-level names to pip-egg-info/spam.egg-info/top_level.txt
writing manifest file 'pip-egg-info/spam.egg-info/SOURCES.txt'
reading manifest file 'pip-egg-info/spam.egg-info/SOURCES.txt'
error: numpy is not installed. Installation will be aborted.
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /private/var/folders/_y/2qk6029j4c7bwv0ddk3p96r00000gn/T/pip-s8sqn20t-build/
Note that I could do the import check on top of the setup script:
from setuptools import setup
try:
import numpy
except ImportError:
raise DistutilsModuleError(...)
setup(...)
But in this case, the output won't be formatted and the complete stack trace will be spilled to the stdout, which is too technical and could confuse the user. Instead, I subclass one of the distutils
commands that will be invoked on installation, so that the error output is properly formatted.
Now, for the second part:
...or print a warning and continue with the dependency uninstalled.
This is not possible anymore, since version 7 pip will swallow any output from your setup script. The user will see the output from the setup script only if pip runs in verbose mode, i.e. pip install -v mypkg
. A questionable decision if you ask me.
Nevertheless, here is an example of issuing a warning and an error in your setup script:
from distutils.log import ERROR
class build(build_orig):
def finalize_options(self):
try:
import numpy
except ImportError:
# issue an error and proceed
self.announce('Houston, we have an error!', level=ERROR)
# for warnings, there is a shortcut method
self.warn('I am warning you!')
super().finalize_options()