If you’re working with Python packages in a Conda environment, you might encounter the ModuleNotFoundError: No module named 'distutils.msvccompiler' error when trying to install older versions of NumPy. Here’s how to understand and fix this common issue. This blog provides a comprehensive guide to understanding and resolving this issue, ensuring a smooth installation process.

Error – ModuleNotFoundError No module named ‘distutils.msvccompiler’

When trying to install NumPy 1.16 using pip install numpy==1.16, you might see an error that looks something like this:

$ pip install numpy==1.16
Collecting numpy==1.16
  Downloading numpy-1.16.0.zip (5.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 10.8 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
Building wheels for collected packages: numpy
  Building wheel for numpy (setup.py) ... error
  error: subprocess-exited-with-error
  
  × python setup.py bdist_wheel did not run successfully.
  │ exit code: 1
  ╰─> [17 lines of output]
      Running from numpy source directory.
      /tmp/pip-install-jdof0z8r/numpy_4597057bbb504aa18b7bda112f0aa37f/numpy/distutils/misc_util.py:476: SyntaxWarning: "is" with a literal. Did you mean "=="?
        return is_string(s) and ('*' in s or '?' is s)
      Traceback (most recent call last):
        File "<string>", line 2, in <module>
        File "<pip-setuptools-caller>", line 34, in <module>
        File "/tmp/pip-install-jdof0z8r/numpy_4597057bbb504aa18b7bda112f0aa37f/setup.py", line 415, in <module>
          setup_package()
        File "/tmp/pip-install-jdof0z8r/numpy_4597057bbb504aa18b7bda112f0aa37f/setup.py", line 394, in setup_package
          from numpy.distutils.core import setup
        File "/tmp/pip-install-jdof0z8r/numpy_4597057bbb504aa18b7bda112f0aa37f/numpy/distutils/core.py", line 26, in <module>
          from numpy.distutils.command import config, config_compiler, \
        File "/tmp/pip-install-jdof0z8r/numpy_4597057bbb504aa18b7bda112f0aa37f/numpy/distutils/command/config.py", line 19, in <module>
          from numpy.distutils.mingw32ccompiler import generate_manifest
        File "/tmp/pip-install-jdof0z8r/numpy_4597057bbb504aa18b7bda112f0aa37f/numpy/distutils/mingw32ccompiler.py", line 34, in <module>
          from distutils.msvccompiler import get_build_version as get_build_msvc_version
      ModuleNotFoundError: No module named 'distutils.msvccompiler'
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for numpy
  Running setup.py clean for numpy
  error: subprocess-exited-with-error
  
  × python setup.py clean did not run successfully.
  │ exit code: 1
  ╰─> [10 lines of output]
      Running from numpy source directory.
      
      `setup.py clean` is not supported, use one of the following instead:
      
        - `git clean -xdf` (cleans all files)
        - `git clean -Xdf` (cleans all versioned files, doesn't touch
                            files that aren't checked into the git repo)
      
      Add `--force` to your command to use it anyway if you must (unsupported).
      
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed cleaning build dir for numpy
Failed to build numpy
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (numpy)

This error indicates that the installation process requires the distutils.msvccompiler module, which is either missing or incompatible with your Python environment. This module is part of the distutils package used for building Python extensions, and it’s commonly required when dealing with legacy packages like NumPy 1.16.

The error typically occurs when attempting to install NumPy 1.16 using pip:

pip install numpy==1.16

Why This Error Occurs

  1. Legacy Build Requirements: NumPy 1.16 relies on older build systems that are not compatible with modern Python versions.
  2. Missing Distutils Module: The distutils module, which was included in earlier Python distributions, may not be present in your environment, especially with Python 3.12 and beyond where it is deprecated.
  3. Conda Environment Issues: Using pip within a Conda environment can sometimes lead to conflicts between Conda’s and pip’s dependency management systems.

Step-by-Step Solution

Follow these steps to resolve the issue and successfully install NumPy 1.16:

1. Verify Python Version Compatibility

NumPy 1.16 is not compatible with Python versions higher than 3.9. Ensure you’re using an appropriate Python version:

python --version

If needed, create a new Conda environment with a compatible Python version:

conda create -n numpy_env python=3.9
conda activate numpy_env

2. Update Build Tools

Ensure that the necessary build tools are up to date:

pip install --upgrade setuptools wheel

3. Install Distutils (If Missing)

If the distutils module is missing, install it manually:

python -m ensurepip --upgrade
pip install distutils

4. Use Conda to Install NumPy

Conda is often better at handling dependencies for older packages. Install NumPy 1.16 using Conda:

conda install numpy=1.16

5. Install NumPy with Pip Using Flags

If you prefer pip, use the --no-build-isolation flag to bypass certain build steps:

pip install numpy==1.16 --no-build-isolation

6. Debugging Additional Issues

If you still face errors:

  • Check for conflicting packages in your environment.
  • Use pip install --force-reinstall numpy==1.16 to overwrite any incomplete installations.
  • Inspect your Python environment for any dependency mismatches.

Alternate Methods to Resolve the Error

Install an Older Version of pip

Older versions of pip may bypass some modern compatibility issues with legacy packages:

pip install --upgrade "pip<21.0"
pip install numpy==1.16

Use easy_install

If pip fails, easy_install (from setuptools) might successfully install NumPy:

easy_install numpy==1.16

Use Docker for an Isolated Environment

Docker containers let you run applications in isolated environments. Create a container with a compatible Python version and install NumPy 1.16:

  1. Pull an older Python image:
docker pull python:3.8-slim
  1. Start a container:
docker run -it python:3.8-slim bash
  1. Install NumPy inside the container:
pip install numpy==1.16

Use Prebuilt Anaconda Environments

Anaconda provides prebuilt environments for specific versions of Python and NumPy. Instead of manually installing, download an environment that already includes NumPy 1.16.

  1. Search for compatible environments on Anaconda Cloud.
  2. Install the environment:
conda create -n legacy_env numpy=1.16 conda activate legacy_env

Use a Linux Subsystem (WSL)

If you’re on Windows, the Windows Subsystem for Linux (WSL) can provide a Unix-like environment where older packages are easier to manage:

  1. Install WSL:
wsl --install
  1. Run Ubuntu (or another distribution):
wsl
  1. Install NumPy:
sudo apt update pip install numpy==1.16

Also Read:

Best Practices

  1. Always use Conda for installing scientific Python packages in Conda environments
  2. Keep your build tools updated
  3. Consider whether you really need an older NumPy version – newer versions often have better compatibility and security

Conclusion

The ModuleNotFoundError: No module named 'distutils.msvccompiler' error can seem daunting, but with the right approach, it is entirely resolvable. By following the steps outlined in this guide, you can successfully install NumPy 1.16 or any legacy package while minimizing dependency conflicts.

If you found this guide helpful or have other solutions, feel free to share your thoughts in the comments!

Categorized in: