Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Execute mypy pre-commit hook in main virtualenv to have access to dependencies #714

Merged

Conversation

jonathanperret
Copy link
Contributor

@jonathanperret jonathanperret commented Sep 26, 2024

Problem

Currently, pre-commit is configured to run mypy in an isolated virtualenv. This causes mypy to be unable to see dependencies listed in requirements.txt unless they are duplicated into additional_dependencies in the pre-commit configuration.

Because most dependencies are unavailable in that environment, mypy is configured to not follow imports (follow_imports=skip) when invoked by pre-commit.

This cause mypy to give different results on some files when run directly (as is done in the CI workflow) versus through pre-commit.

This can easily be demonstrated by running pre-commit run -a mypy, which executes the mypy hook on all files. Not only are the exclusion patterns written in mypy.ini ignored, the differing configuration causes mypy to reject src/main/python/main/ayab/engine/communication.py for example whereas it is accepted by mypy run directly.

Furthermore, that same invocation of pre-commit causes mypy to crash when invoked on a Python file that imports numpy, hitting python/mypy#17396.

To reproduce:

$ pre-commit clean
Cleaned …/.cache/pre-commit.
$ echo '#test' >> ./src/main/python/main/ayab/utils.py
$ git add ./src/main/python/main/ayab/utils.py
$ pre-commit run mypy
…
[INFO] Installing environment for https://github.com/pre-commit/mirrors-mypy.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
mypy.....................................................................Failed
- hook id: mypy
- exit code: 1

Traceback (most recent call last):
  File "/Users/jonathanperret/.cache/pre-commit/repoayxwybnl/py_env-python3.11/bin/mypy", line 8, in <module>
    sys.exit(console_entry())
             ^^^^^^^^^^^^^^^
  File "/Users/jonathanperret/.cache/pre-commit/repoayxwybnl/py_env-python3.11/lib/python3.11/site-packages/mypy/__main__.py", line 15, in console_entry
    main()
  File "mypy/main.py", line 100, in main
  File "mypy/main.py", line 182, in run_build
  File "mypy/build.py", line 192, in build
  File "mypy/build.py", line 266, in _build
  File "mypy/build.py", line 2942, in dispatch
  File "mypy/build.py", line 3340, in process_graph
  File "mypy/build.py", line 3467, in process_stale_scc
  File "mypy/build.py", line 2503, in write_cache
  File "mypy/build.py", line 1564, in write_cache
  File "mypy/nodes.py", line 387, in serialize
  File "mypy/nodes.py", line 3933, in serialize
  File "mypy/nodes.py", line 3870, in serialize
  File "mypy/nodes.py", line 3301, in serialize
  File "mypy/types.py", line 658, in serialize
  File "mypy/types.py", line 2414, in serialize
  File "mypy/types.py", line 1459, in serialize
  File "mypy/types.py", line 658, in serialize
  File "mypy/types.py", line 3051, in serialize
AssertionError: Internal error: unresolved placeholder type None

Proposed solution

The issues coming from running mypy in an isolated pre-commit environment are documented in python/mypy#13916 by the mypy maintainer.

Two solutions are suggested there: either duplicate all dependencies from requirements[.build].txt as additional_dependencies, or configure pre-commit to execute mypy in the project's default virtual environment.

In this PR I opted for the latter option, mainly because it requires less maintenance when dependencies change in the future.

The compromise is that running mypy through pre-commit will require a properly initialized virtualenv. However because we add a files: filter to the mypy hook, pre-commit will not run if no Python file has been changed; and if Python files have been changed it seems reasonable to expect a proper development environment has been set up.

The pass_filenames pre-commit option is set to false as well, as recommended, so that mypy can do whole-project analysis.

Summary by CodeRabbit

  • Chores
    • Updated the configuration for the type checker from an external repository to a local setup.
    • Removed the previous configuration file, which may affect type checking behavior.

Copy link
Contributor

coderabbitai bot commented Sep 26, 2024

Walkthrough

The changes involve modifications to the .pre-commit-config.yaml file and the removal of the .pre-commit.mypy.ini file. The .pre-commit-config.yaml file transitions the mypy hook from an external repository to a local configuration, altering how type checking is executed within the project. The deleted .pre-commit.mypy.ini file contained specific MyPy settings, and its removal indicates that the project will no longer utilize these configurations for type checking.

Changes

File(s) Change Summary
.pre-commit-config.yaml Updated mypy hook configuration from external repository to local setup with new attributes.
.pre-commit.mypy.ini Deleted file containing MyPy configuration settings, affecting type checking behavior.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@dl1com dl1com left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine to merge as it is more tooling related and has no direct impact on the 1.0.0 code.

`pre-commit` will by default create an isolated virtualenv
to run hooks such as `mypy`. This creates well-known issues
because `mypy` won't have access to packages the code depends
on. See python/mypy#13916 for
recommendations by the `mypy` maintainer.

By running `mypy` as a `system` hook as suggested, it will see the exact
same packages as running `mypy` standalone (or through an IDE) will,
which avoids discrepancies that appear only at commit time.

The compromise is that running `mypy` through `pre-commit` will require
a properly initialized virtualenv. However because we add a `files:`
filter to the `mypy` hook, `pre-commit` will not run if no Python
file has been changed; and if Python files have been changed it seems
reasonable to expect a proper development environment has been set up.

Also following the recommendation we set `pass_filenames: false` so that
`pre-commit` does not pass only the changed files to `mypy`.
Copy link

sonarcloud bot commented Sep 30, 2024

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
.pre-commit-config.yaml (1)

16-23: Minor formatting issues and missing newline at the end of file.

There are a few minor formatting issues in the YAML file:

  1. The indentation for the mypy hook (line 18) should be 10 spaces instead of 6 to align with other hooks.
  2. There should be only one space after the hyphen on line 18.
  3. There's no newline character at the end of the file (line 23).

To address these issues, please apply the following changes:

 repos:
     - repo: https://github.com/pre-commit/pre-commit-hooks
       rev: v3.1.0
       hooks:
           - id: check-yaml
     - repo: https://github.com/psf/black-pre-commit-mirror
       rev: 24.3.0
       hooks:
           - id: black
             language_version: python3.11
     - repo: https://github.com/pycqa/flake8
       rev: '7.0.0'
       hooks:
       -   id: flake8
           additional_dependencies: [flake8-bugbear,flake8-sfs]
     - repo: local
       hooks:
-      -   id: mypy
+          - id: mypy
           name: check types with mypy
           language: system
           pass_filenames: false
           entry: mypy src
-          files: ^src/.*.py$
+          files: ^src/.*.py$
+

These changes will improve the consistency of the YAML file and address the missing newline at the end of the file.

🧰 Tools
🪛 yamllint

[warning] 18-18: too many spaces after hyphen

(hyphens)


[warning] 18-18: wrong indentation: expected 10 but found 6

(indentation)


[error] 23-23: no new line character at the end of file

(new-line-at-end-of-file)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 95ed966 and 1263c05.

📒 Files selected for processing (2)
  • .pre-commit-config.yaml (1 hunks)
  • .pre-commit.mypy.ini (0 hunks)
💤 Files with no reviewable changes (1)
  • .pre-commit.mypy.ini
🧰 Additional context used
🪛 yamllint
.pre-commit-config.yaml

[warning] 18-18: too many spaces after hyphen

(hyphens)


[warning] 18-18: wrong indentation: expected 10 but found 6

(indentation)


[error] 23-23: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (1)
.pre-commit-config.yaml (1)

16-23: LGTM! The mypy hook configuration looks good and aligns with the PR objectives.

The changes effectively move the mypy hook from an external repository to a local configuration, which will allow it to run in the main virtualenv and access all project dependencies. This addresses the issues mentioned in the PR summary.

Key benefits of this configuration:

  1. pass_filenames: false enables whole-project analysis.
  2. entry: mypy src runs mypy on the entire src directory.
  3. files: ^src/.*.py$ ensures the hook only runs on Python files in the src directory.
  4. language: system allows the hook to use the system's Python installation (project's virtualenv).

These changes should resolve the discrepancies between running mypy directly and through pre-commit, as well as the internal error when processing files that import numpy.

🧰 Tools
🪛 yamllint

[warning] 18-18: too many spaces after hyphen

(hyphens)


[warning] 18-18: wrong indentation: expected 10 but found 6

(indentation)


[error] 23-23: no new line character at the end of file

(new-line-at-end-of-file)

@jonathanperret jonathanperret merged commit 4dab861 into AllYarnsAreBeautiful:main Sep 30, 2024
2 checks passed
@jonathanperret jonathanperret deleted the fix-mypy-numpy branch September 30, 2024 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants