How to obtain arguments passed to setup.py from pip with '--install-option'?
Solution 1:
You need to extend the install command with a custom command of your own. In the run
method you can expose the value of the option to setup.py
(in my example I use a global variable).
from setuptools.command.install import install
class InstallCommand(install):
user_options = install.user_options + [
('someopt', None, None), # a 'flag' option
#('someval=', None, None) # an option that takes a value
]
def initialize_options(self):
install.initialize_options(self)
self.someopt = None
#self.someval = None
def finalize_options(self):
#print("value of someopt is", self.someopt)
install.finalize_options(self)
def run(self):
global someopt
someopt = self.someopt # will be 1 or None
install.run(self)
Register the custom install command with the setup
function.
setup(
cmdclass={
'install': InstallCommand,
},
:
It seems that the order of your arguments is off
pip install /path/to/my/local/package --install-option="--someopt"
Solution 2:
For consistency, you can add an option to both setup.py install
and setup.py develop
(aka pip install -e
): (building off Ronen Botzer's answer)
from setuptools import setup
from setuptools.command.install import install
from setuptools.command.develop import develop
class CommandMixin(object):
user_options = [
('someopt', None, 'a flag option'),
('someval=', None, 'an option that takes a value')
]
def initialize_options(self):
super().initialize_options()
# Initialize options
self.someopt = None
self.someval = 0
def finalize_options(self):
# Validate options
if self.someval < 0:
raise ValueError("Illegal someval!")
super().finalize_options()
def run(self):
# Use options
global someopt
someopt = self.someopt # will be 1 or None
super().run()
class InstallCommand(CommandMixin, install):
user_options = getattr(install, 'user_options', []) + CommandMixin.user_options
class DevelopCommand(CommandMixin, develop):
user_options = getattr(develop, 'user_options', []) + CommandMixin.user_options
setup(
...,
cmdclass={
'install': InstallCommand,
'develop': DevelopCommand,
}
Then you can pass options to pip like:
pip install --install-option="--someval=1" --install-option="--someopt" .
Or in develop mode:
pip install -e --install-option="--someval=1" .
Solution 3:
It works well and also documented.
from setuptools.command.install import install
class InstallCommand(install):
user_options = install.user_options + [
('engine=', None, '<description for this custom option>'),
]
def initialize_options(self):
install.initialize_options(self)
self.engine = None
def finalize_options(self):
print("value of engine is", self.engine)
install.finalize_options(self)
def run(self):
print(self.engine)
install.run(self)
setup(
...
cmdclass={'install': InstallCommand}
...
)
One of common mistakes is to pass setup
options to pip like you pass it to setup
directly. Use options from pip like that:
pip install . --install-option="--engine=rabbitmq"
But this way is a wrong way:
pip install . --install-option="--engine rabbitmq"
Absence of equal sign causes well known error:
error: option --engines rabbitmq not recognized