Search code examples
pythonpre-commit-hookpre-commitpre-commit.comisort

pre-commit isort no module named 'setuptools'


I am trying to run pre-commit hooks, but they fail when they come across the isort hook which throws the error below:

  File "/home/el/.cache/pre-commit/repoffrjhcx0/py_env-python3/lib/python3.10/site-packages/_distutils_hack/__init__.py", line 92, in create_module
    return importlib.import_module('setuptools._distutils')
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ModuleNotFoundError: No module named 'setuptools'

I am using docker, and I have checked that setuptools is installed on both my machine globally, and on my docker. I do not understand why this error occurs. I think isort sets up it's own environment, but then why would it be not installed since it is defined in their config file pyproject.toml.

Below are my pre-commit and isort configs:

.pre-commit-config.yaml

repos:
- repo: https://github.com/pycqa/isort
  rev: 5.8.0
  hooks:
    - id: isort
      args: ["--multi-line=5", "--line-length=120", "--use-parentheses", "--filter-files"]
      exclude: "migrations"
      stages: [commit]

tox.ini

[isort]
line_length=120
skip_glob=*migrations*
multi_line_output=5
sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
use_parentheses=true
include_trailing_comma=true
lines_between_types=1
lines_after_imports=2
[testenv:isort]
deps =
    isort
commands =
    isort . --check-only --diff

Python version on system: 3.10.1

Python version on docker: 3.8

I appreciate any help!


Solution

  • this was a bug in setuptools which has already been fixed (see also the pinned issue on isort)

    you can work around this bug by setting the following environment variable: SETUPTOOLS_USE_DISTUTILS=stdlib

    the version of setuptools comes from the version of virtualenv you're using, so you may want to upgrade to get the correct version

    here's a longer summary of what went wrong with setuptools:

    here's the relevant things to follow up on:

    why we're suddenly seeing this:

    • the latest virtualenv release upgraded setuptools to 60.1.0 (despite what the changelog says it was upgraded to 60.1.0 here)
    • setuptools 60.* changes the default to using the setuptools-embedded distutils rather than the stdlib distutils
    • setuptools does this by way of a .pth file which redirects imports of distutils to setuptools._distutils
    • during pip's isolated builds (triggered by pyproject.toml, for example to install isort via poetry) pip attempts to clear the current sys.path of the enclosing environment and isolates to the pyproject.toml-installed build dependencies, but it's a bit too late as the .pth files from the enclosing environment are applied. so in this environment setuptools is not installed, but its import hooks are

    disclaimer: I created pre-commit