Skip to content

Resolving ModuleNotFoundError for distutils in Python

Problem Statement

When importing Python packages like scikit-fuzzy or TensorFlow, you might encounter:

python
ModuleNotFoundError: No module named 'distutils'

This occurs because:

  1. distutils was deprecated in Python 3.10
  2. It was fully removed in Python 3.12+
  3. Many legacy packages still rely on this module
  4. Attempting to manually install distutils fails since it's obsolete:
    bash
    ERROR: Could not find a version that satisfies the requirement distutils

This error appears primarily in Python ≥3.12 environments when installing older packages.

Core Solution: Install setuptools

The modern replacement for distutils is setuptools. Install it with:

bash
pip install setuptools

If you're using Python 3 specifically:

bash
python3 -m pip install setuptools

Why This Works

  • Setuptools includes a backward-compatible distutils implementation
  • It resolves dependency issues caused by Python 3.12+ standard library changes

Verification

After installation, verify the import works in Python:

python
import setuptools.dist  # No error should appear
<tip> Always restart your Python environment after installation (kernel, terminal, or IDE). </tip>

Python Version Compatibility ChartDistutils availability across Python versions

Specific Environment Solutions

1. Poetry Users (Python 3.12+)

Update your pyproject.toml to require Python 3.12:

toml
[tool.poetry.dependencies]
python = "^3.12"  # Was previously "^3.11"

Then refresh dependencies:

bash
poetry lock
poetry install

2. virtualenvwrapper Users (Ubuntu 24.04+)

Create a hook to install setuptools automatically:

bash
# Create post-creation hook
cat > ~/.virtualenvs/postmkvirtualenv << 'EOF'
#!/bin/bash
"${VIRTUAL_ENV}/bin/pip" install setuptools
EOF

# Set permissions
chmod +x ~/.virtualenvs/postmkvirtualenv

Update shell configuration (.bashrc/.zshrc):

bash
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
export VIRTUALENVWRAPPER_SETUPTOOLS=1
source /usr/share/virtualenvwrapper/virtualenvwrapper.sh

3. Homebrew (macOS)

bash
brew install python-setuptools

4. Void Linux

bash
xi python3-setuptools

Legacy Package Caveats

Some packages like scikit-fuzzy or TensorFlow may require additional steps after installing setuptools. If solutions fail:

  1. Check package compatibility: Look for Python 3.12+ support issues
  2. Downgrade Python: Use Python 3.11 until the package updates
  3. Alternative imports (if applicable):
    python
    import setuptools.dist  # Before importing legacy packages
    import skfuzzy as fuzz
<warning> Packages requiring the original distutils won't work long-term. Check package repositories for Python 3.12 support updates. </warning>

Why Was distutils Removed?

  • Officially deprecated in PEP 632
  • Replaced by more modern packaging tools (setuptools, build)
  • Python 3.12 marks its complete removal
  • Security and maintenance burdens drove the decision
  1. Always specify Python version in tooling:
    toml
    # pyproject.toml
    [project]
    requires-python = ">=3.12"
  2. Prefer modern alternatives in pyproject.toml:
    toml
    [build-system]
    requires = ["setuptools>=65.5.0"]
    build-backend = "setuptools.build_meta"
  3. Migrate legacy setup scripts from distutils to setuptools

When Solutions Fail

If errors persist:

  1. Create a clean virtual environment:
    bash
    python -m venv --clear .venv
    source .venv/bin/activate
  2. Install dependencies while checking warnings
  3. Open an issue with the problematic package maintainer

Transitioning to tools like flit or hatch also avoids distutils-related issues entirely.