question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

python setup.py develop fails with `version = attr: pkg.__version__` in setup.cfg

See original GitHub issue

See also https://github.com/pypa/pip/issues/6350

When a package has version = attr: pkg.__version__ in its setup.cfg file, python setup.py develop can fail with a ModuleNotFoundError if not all runtime dependencies have been installed yet.

I’ve created a minimal repo to reproduce the error: https://github.com/kohr-h/minimal

Reproducing the error:

  • Create a fresh environment with python inside, but without numpy (our example dependency)
  • Run python setup.py develop in the repo root

Workaround:

  • Install numpy as well
  • Now python setup.py develop succeeds

Traceback

Traceback (most recent call last):
  File "setup.py", line 3, in <module>
    setup()
  File "/home/hkohr/miniconda/envs/tmp/lib/python3.7/site-packages/setuptools/__init__.py", line 145, in setup
    return distutils.core.setup(**attrs)
  File "/home/hkohr/miniconda/envs/tmp/lib/python3.7/distutils/core.py", line 121, in setup
    dist.parse_config_files()
  File "/home/hkohr/miniconda/envs/tmp/lib/python3.7/site-packages/setuptools/dist.py", line 705, in parse_config_files
    ignore_option_errors=ignore_option_errors)
  File "/home/hkohr/miniconda/envs/tmp/lib/python3.7/site-packages/setuptools/config.py", line 120, in parse_configuration
    meta.parse()
  File "/home/hkohr/miniconda/envs/tmp/lib/python3.7/site-packages/setuptools/config.py", line 425, in parse
    section_parser_method(section_options)
  File "/home/hkohr/miniconda/envs/tmp/lib/python3.7/site-packages/setuptools/config.py", line 398, in parse_section
    self[name] = value
  File "/home/hkohr/miniconda/envs/tmp/lib/python3.7/site-packages/setuptools/config.py", line 183, in __setitem__
    value = parser(value)
  File "/home/hkohr/miniconda/envs/tmp/lib/python3.7/site-packages/setuptools/config.py", line 513, in _parse_version
    version = self._parse_attr(value, self.package_dir)
  File "/home/hkohr/miniconda/envs/tmp/lib/python3.7/site-packages/setuptools/config.py", line 348, in _parse_attr
    module = import_module(module_name)
  File "/home/hkohr/miniconda/envs/tmp/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/hkohr/git/minimal/minimal/__init__.py", line 2, in <module>
    from . import mod
  File "/home/hkohr/git/minimal/minimal/mod.py", line 1, in <module>
    import numpy
ModuleNotFoundError: No module named 'numpy'

I wonder whether this can be fixed elegantly and does not sit too deep.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:2
  • Comments:16 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
bsolomon1124commented, Sep 29, 2020

It seems that as long as you either 1. have no third party imports or 2. point the attr: directive at a literal version = … assignment rather than a derived quantity or something imported, this should just work.

Yes, though one small correction - those two conditions need a boolean-AND, not or 😃. I’m going to venture that 90% of packages that declare a simple one-liner in a module outside of __init__.py turn around and try to import that into __init__.py so that they can bring it directly under the package namespace.

Example:

mkdir pypa-1724
cd pypa-1724
mkdir -p src/package_a
touch README.md
echo '__version__ = "1.0.0"' > src/package_a/_version.py
echo 'import setuptools; setuptools.setup()' > setup.py

cat << EOF > src/package_a/__init__.py
from flask import Flask
from ._version import __version__
EOF

cat << EOF > setup.cfg
[metadata]
name = package-a
version = attr:package_a._version.__version__
description = foo
long_description = file: README.md
long_description_content_type = text/markdown
license = Apache-2.0

[options]
packages = find:
install_requires =
    flask
    importlib_resources;python_version<"3.7"
include_package_data = True
package_dir =
    =src

[options.packages.find]
where = src
EOF

Then:

python3 -m venv venv
. ./venv/bin/activate
python3 -m pip install -e .

Breaks with:

ModuleNotFoundError: No module named 'flask'

whereas removing the flask import in __init__.py (and optionally dropping from install_requires) succeeds, verifiable with python3 -c 'import package_a; print(package_a.__version__)'.

1reaction
ThomasTNOcommented, Nov 25, 2021

For future reference, I managed to work around this error by using attr: pkg.__init__.__version__ instead of attr: pkg.__version__.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ModuleNotFoundError when using setup.cfg and version ...
cfg with version = file: VERSION.txt , and load it from your __init__.py with import importlib_metadata; __version__ = importlib_metadata.
Read more >
Single-sourcing the package version
Read the file in setup.py and get the version. ... the following in the project's setup.cfg file (replacing “package” with the import name...
Read more >
Configuring setuptools using setup.cfg files
The version file attribute has only been supported since 39.2. 0. A version loaded using the file: directive must comply with PEP 440....
Read more >
setuptools-scm - PyPI
setuptools_scm extracts Python package versions from git or hg metadata instead of ... directive (described below in setup.py usage and setup.cfg).
Read more >
Frequently Asked Questions - PyScaffold 4.3.1 documentation
Can I use PyScaffold ≥ 3 to develop a Python package that is Python 2 & 3 ... python setup.py --version and the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found