setuptools: SystemError: Parent module 'setuptools' not loaded, cannot perform relative import with setuptools 50

After upgrading setuptools to 50.0 today, the environment fails to locate the entry points as it could not import distutils

$ python --version
Python 3.5.1
$ python -c "import distutils"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 666, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 577, in module_from_spec
  File "/home/gchan/tmp/setuptools-python-3.5/lib/python3.5/site-packages/_distutils_hack/__init__.py", line 82, in create_module
    return importlib.import_module('._distutils', 'setuptools')
  File "/home/gchan/tmp/setuptools-python-3.5/lib64/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 981, in _gcd_import
  File "<frozen importlib._bootstrap>", line 931, in _sanity_check
SystemError: Parent module 'setuptools' not loaded, cannot perform relative import

The issue could not be found in the python 3.8 environment.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 53
  • Comments: 23 (6 by maintainers)

Commits related to this issue

Most upvoted comments

Same issue. Worked around with downgrading and blacklisting 50.0:

pip install "setuptools!=50.0" --force-reinstall

and in requirements.txt:

setuptools!=50.0

For what it’s worth:

  1. I’m not terribly new to Python, but the impact of “Once again, Setuptools overrides the stdlib distutils on import.” is completely lost on me, especially when it comes to discovering entrypoints.
  2. Whatever this “number of environments” is, by far the biggest impact to me is that my organization heavily uses Python (and setuptools entrypoints) inside of Docker images… and all of our images are based on Debian. I’d expect that many people/organizations are in this same situation (given the popularity of Debian as a base for Docker images) but may not have rebuilt images recently enough for the impact to be discovered.

Can anyone clarify what SETUPTOOLS_USE_DISTUTILS=stdlib actually does? I realize it’s a workaround, and it’s definitely necessary right now for many of us, but how different is it from pre-50 behavior, if at all?

The workaround described in the changelog worked for me:

export SETUPTOOLS_USE_DISTUTILS=stdlib

The environment variable is explained in the changelog, along with the change that caused the breakage: https://setuptools.readthedocs.io/en/latest/history.html#v50-0-0 . But I think the number of “environments or invocations where this behavior is undesirable” was far larger than expected, being basically anybody on Debian, Ubuntu, or any other Debian-derived distribution.

On my side the impact is significant as every environments (by default installed by the latest setuptools) breaks. Many dependencies / libraries directly import distutils for the LooseVersion class. We cannot ask the downstream users to inject the environment variable always as well. I think eventually we should accept that setuptools monkeypatch distutils internally. But I just do not understand

  1. Why does it occur on older Python 3 versions, e.g. python 3.5 and 3.6?

  2. Why does setuptools hack the stdlib distutils even when other packages import distutils directly?

The environment variable is explained in the changelog, along with the change that caused the breakage: https://setuptools.readthedocs.io/en/latest/history.html#v50-0-0 . But I think the number of “environments or invocations where this behavior is undesirable” was far larger than expected, being basically anybody on Debian, Ubuntu, or any other Debian-derived distribution.

@jmbowman I read it, but I am concerned about the phrase “temporary escape hatch”… this is turning out to be a significant change that’ll have a broad negative impact (especially, as @jantman notes, it will impact many who don’t regularly rebuild their images and will run into this in the coming days and weeks). The thought that this will soon become impossible to override is worrisome - some reassurance that this won’t be so temporary an escape hatch would be appreciated.

I’d be happy just to pin down to < 50.0 in the requirements until this no longer breaks things, but that’s highly discouraged when it comes to a requirements-based install. I’m not sure there’s any other viable workaround except for the escape hatch above.

(FWIW I’m @MartyMacGyver above so this is part of the same thread)