Eric J Ma's Website

How to debug a ModuleNotFoundError in the interrogate pre-commit hook

written by Eric J. Ma on 2023-10-29 | tags: pre-commit hooks code quality debugging python version setuptools dependency management github actions code style checks


Pre-commit hooks are an indispensable tool in the modern development workflow. They help enforce code quality and consistency right at the stage of committing the code, well before it becomes a part of the codebase or enters the CI/CD pipeline. Recently, while working with interrogate, a popular pre-commit hook for checking Python docstrings, I encountered a puzzling ModuleNotFoundError. Here's how I debugged the issue and some potential solutions to the problem.

The Error

I ran the pre-commit command like usual within LlamaBot's CI/CD pipelines, and all seemed well until I hit this snag:

interrogate..............................................................Failed
- hook id: interrogate
- exit code: 1

Traceback (most recent call last):
  File "/home/runner/.cache/pre-commit/repox_7d0awa/py_env-python3/bin/interrogate", line 5, in <module>
    from interrogate.cli import main
  File "/home/runner/.cache/pre-commit/repox_7d0awa/py_env-python3/lib/python3.12/site-packages/interrogate/cli.py", line 11, in <module>
    from interrogate import badge_gen
  File "/home/runner/.cache/pre-commit/repox_7d0awa/py_env-python3/lib/python3.12/site-packages/interrogate/badge_gen.py", line 11, in <module>
    import pkg_resources
ModuleNotFoundError: No module named 'pkg_resources'

Diagnosis

Upon investigating, I narrowed down the problem to a few key points:

  1. Python Version: Pre-commit was defaulting to the latest Python version, which at the time was Python 3.12.
  2. Missing Package: Python 3.12 no longer ships with setuptools, which provides the missing pkg_resources, by default within a virtual environment (venv).
  3. Dependency Gap: The interrogate package itself doesn't explicitly depend on setuptools.

The Solution

Given the diagnosis, one way to fix this would be to ensure that interrogate explicitly lists setuptools as a dependency. Doing this would ensure that pkg_resources is available, eliminating the ModuleNotFoundError. To that end, I submitted a bug report and immediately put in a pull request to fix the bug.

Workaround the issue

While waiting for an official fix, the workaround for the pre-commit hook is to ensure that you are running Python<3.12 when installing pre-commit. In my case, I set the Python version to 3.11 within the relevant GitHub Actions YAML file:

# Run code style checks on each pull request.
name: Code style checks

on: [pull_request]

jobs:
  linting:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
        with:
          python-version: 3.11
      - uses: pre-commit/action@v2.0.0

This ensured that setuptools was installed within the virtual environment for each hook, and should solve any similar issues in the short-term.

Conclusion

This experience underscores the importance of keeping track of dependencies and being mindful of how language and library updates can break existing setups. The good news is that this issue is quite fixable, either through an update to interrogate or through manual intervention.

Issues like these are bound to happen in a continually evolving ecosystem like Python, and troubleshooting them is part and parcel of a developer's life. If you've faced similar issues or have suggestions, feel free to share them in the comments below!


Cite this blog post:
@article{
    ericmjl-2023-how-hook,
    author = {Eric J. Ma},
    title = {How to debug a ModuleNotFoundError in the interrogate pre-commit hook},
    year = {2023},
    month = {10},
    day = {29},
    howpublished = {\url{https://ericmjl.github.io}},
    journal = {Eric J. Ma's Blog},
    url = {https://ericmjl.github.io/blog/2023/10/29/how-to-debug-a-modulenotfounderror-in-the-interrogate-pre-commit-hook},
}
  

I send out a newsletter with tips and tools for data scientists. Come check it out at Substack.

If you would like to sponsor the coffee that goes into making my posts, please consider GitHub Sponsors!

Finally, I do free 30-minute GenAI strategy calls for teams that are looking to leverage GenAI for maximum impact. Consider booking a call on Calendly if you're interested!