17

In some cases setup.py needs to import some extra modules, e.g.:

from setuptools import setup
import foo

setup(
    # e.g. a keyword uses `foo`
    version=foo.generate_version()
)

If foo is not installed, the execution of setup.py will fail because of ImportError.

I have tried to use setup_requires, e.g. setup_requires=['foo'], but it doesn’t help.

So how to specify this kind of dependencies?

TitanSnow
  • 265
  • 2
  • 6
  • 1
    Using `setup_requires` is correct, however you can't import packages listed in `setup_requires` on top of the setup script. What do you need the import for? If you import `foo` to assemble input args for `setup()` function, then you have no chance to manage this dependency in the setup script; otherwise, overriding commands should be the answer. Show your setup script. – hoefling Apr 08 '18 at 19:23

5 Answers5

8

pyproject.toml allows to specify custom build tooling:

[build-system]
requires = [..., foo, ...]
build-backend = "setuptools.build_meta"
Tosha
  • 998
  • 1
  • 10
  • 22
6

I have thought out a trick — call pip to install the dependencies in setup.py

import pip
pip.main(['install', 'foo', 'bar'])    # call pip to install them

# Now I can import foo & bar
import foo, bar
from setuptools import setup

setup(
    ...
)
TitanSnow
  • 265
  • 2
  • 6
5

Dependencies needed in setup.py cannot be specified in the very setup.py. You have to install them before running python setup.py:

pip install -r requirements.txt
python setup.py install
phd
  • 82,685
  • 13
  • 120
  • 165
2

Like @Tosha answered, pyproject.toml is your friend.

Here is an example from my project which uses jinja2:

setup.py: # Simplified - removed all actual code

import jinja2
from setuptools import setup

setup(name='test')

Building with: python -m build --wheel will break:

* Creating venv isolated environment...
* Installing packages in isolated environment... (setuptools >= 40.8.0, wheel)
* Getting dependencies for wheel...
Traceback (most recent call last):
  File "/tmp/venv/lib/python3.6/site-packages/pep517/in_process/_in_process.py", line 363, in <module>
    main()
  File "/tmp/venv/lib/python3.6/site-packages/pep517/in_process/_in_process.py", line 345, in main
    json_out['return_val'] = hook(**hook_input['kwargs'])
  File "/tmp/venv/lib/python3.6/site-packages/pep517/in_process/_in_process.py", line 130, in get_requires_for_buil
d_wheel
    return hook(config_settings)
  File "/tmp/build-env-4zi79uth/lib/python3.6/site-packages/setuptools/build_meta.py", line 163, in get_requires_fo
r_build_wheel
    config_settings, requirements=['wheel'])
  File "/tmp/build-env-4zi79uth/lib/python3.6/site-packages/setuptools/build_meta.py", line 143, in _get_build_requ
ires
    self.run_setup()
  File "/tmp/build-env-4zi79uth/lib/python3.6/site-packages/setuptools/build_meta.py", line 268, in run_setup
    self).run_setup(setup_script=setup_script)
  File "/tmp/build-env-4zi79uth/lib/python3.6/site-packages/setuptools/build_meta.py", line 158, in run_setup
    exec(compile(code, __file__, 'exec'), locals())
  File "setup.py", line 1, in <module>
    import jinja2
ModuleNotFoundError: No module named 'jinja2'

ERROR Backend subproccess exited when trying to invoke get_requires_for_build_wheel

However, adding a pyproject.toml:

[build-system]
requires = [
    "setuptools",
    "jinja2",
]

fixes the issue

Note I'm including also setuptools as a requirement. Omitting it will also break

CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
0

I have similar problem, that I want to getting version of installer from yaml file, so I need to parse it and getting version from it.

I use following script as answer:

#!/usr/bin/env python

from setuptools import setup
import yaml


def find_version():
    with open('meta/main.yml') as meta_main:
        return yaml.load(meta_main)['version']


setup(name='sample',
      version=find_version(),
      packages=[],
      setup_requires=['pyyaml'])

I found that setup method has setup_requires parameter, that you can specify setup dependencies. As mentioned in setuptools doccumentation, projects listed in setup_requires will NOT be automatically installed on the system where the setup script is being run. If you want them to be installed, as well as being available when the setup script is run, you should add them to install_requires and setup_requires.

Let me know if you have any other problem.

Ocean
  • 2,882
  • 1
  • 18
  • 21