microsoft / vscode-mypy

Linting support for Python using the mypy linter.
https://marketplace.visualstudio.com/items?itemName=ms-python.mypy-type-checker
MIT License
120 stars 27 forks source link

MyPy should receive the python interpreter used in the project #191

Open jmfederico opened 4 years ago

jmfederico commented 4 years ago

Environment data

Expected behaviour

When running mypy, it should receive --python-executable with the path to the active python interpreter if one is set.

Actual behaviour

When mypy runs, it lints with Python interpreter available to it, and not the one selected as interpreter in VSCode, and since --ignore-missing-imports is passed to mypy by default, it can be common that types are not correctly resolved, and errors are just being muted.

Steps to reproduce:

  1. Install MyPy globally (or with pipx)
  2. Create a virtual environment and open the project with VSCode python3 -m venv .venv
  3. Enable MyPy linting "python.linting.mypyEnabled": true and "python.linting.mypyPath": "/path/to/bin/mypy"
  4. Set the Python interpreter to the one in the virtual environment "python.pythonPath": ".venv/bin/python"
  5. Install some library that has custom types (I use boto3-stubs) .venv/bin/pip install boto3-stubs
  6. Create a file with:
    from mypy_boto3 import boto3_session
    session: boto3_session.Session = 123
  7. MyPy will not report any errors

Now, to fix that problem:

  1. Add --python-executable to the list of arguments passed to MyPy:
    "python.linting.mypyArgs": [
      "--ignore-missing-imports",
      "--follow-imports=silent",
      "--show-column-numbers",
      "--python-executable=.venv/bin/python3"
    ]
  2. MyPy will now report a type error: Incompatible types in assignment (expression has type "int", variable has type "Session")

I set this as a bug and not a feature request because VSCode knows what python interpreter the user wants to use, as it is a setting that the user can change. It would make sense that the interpreter is used when it affects the behaviour of other tools.

karthiknadig commented 4 years ago

We are treating this as a feature request. We have marked this issue as "needs decision" to make sure we have a conversation about your idea. We plan to leave this feature request open for at least a month to see how many 👍 votes the opening comment gets to help us make our decision.

jmfederico commented 4 years ago

Seems like not many people like my idea :(

JamesHutchisonCarta commented 2 years ago

This is a bug. In order for mypy to be usable, I should not have to add to every single project:

                "mypyArgs": [
                    "--python-executable=/path/to/venv"
                ]

This is unexpected behavior. This creates erroneous mypy issues as it often flags return values from dependencies as Any and misbehaves. Please correct the tag and mark this as a bug.

brettcannon commented 2 years ago

In order for mypy to be usable, I should not have to add to every single project

You actually don't have to. This situation only occurs if you happen to set mypyPath to a global install of mypy. If you install mypy into your project/environment then this setting is not needed. This is also the workflow we currently support by default as mypy's type checking does shift per release, and so we try to advise people to be specific about the mypy version by installing it into their environment.

If you still disagree with our assessment that this is a feature, we have created https://github.com/microsoft/vscode-python-tools-extension-template to help people to create their own VS Code extensions for Python tools such as linters like mypy. That way you can have whatever workflow you prefer regardless of what we think.

JamesHutchisonCarta commented 2 years ago

@brettcannon Thank you very much for that link!

My rationale this is a bug is that no sane person would want different mypy results from the editor than if they ran it normally. MyPy will spit out errors if you do not provide the correct python executable. In other words, you would never run mypy on your own without this argument if your virtual environment was different from your mypy environment. This bug can create situations where your editor complains about needing a cast from Any, but your CI complains about a redundant cast.

Likewise, it is becoming more and more common to see code quality tools be split out from the actual development environment. The reasoning is that they lug with them dependencies that may conflict with your actual production dependencies, and likewise not exist on the production image.

A common example of this would be with dev containers, which ship with all the tooling you need included. A company may provide a base image with a common mypy venv installed. You could also install the correct version as part of your postCreateCommand.

Here is an example of what we are doing, where this issue was very apparent:

# set a specific mypy version. Pipx installs the tool to its own virtual env
pipx upgrade mypy --pip-args mypy==0.950

# install a specific version of poetry
pipx install poetry==1.2.0b3 --force

# create a virtual environment for the project with poetry
poetry config virtualenvs.in-project true
poetry config virtualenvs.create true
poetry install --no-interaction --no-ansi

Then in our settings, which are largely default:

// this is added
"defaultInterpreterPath": "/workspaces/my-program/.venv/bin/python"
...
// this is largely unmodified
            "linting": {
                "enabled": true,
                "flake8Enabled": true,
                "mypyEnabled": true,
                "pylintPath": "/usr/local/py-utils/bin/pylint",
                "banditPath": "/usr/local/py-utils/bin/bandit",
                "flake8Path": "/usr/local/py-utils/bin/flake8",
                "mypyPath": "/usr/local/py-utils/bin/mypy",
                "pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
                "pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
           }

As you can see, there's many linting tools that exist, and if you install all of them to the same environment there's a good chance you have dependencies you did not ask for.

The reason I am advocating for this to be handled automatically and not require additional configuration is because the bug is sneaky and you might waste a bit of time trying to figure out why VS Code is acting differently than your CI. While this may be a user error, it reflects poorly on VS Code to those who aren't aware of this nuance. You aren't aware that mypy cannot find your imports until you run it manually using the same parameters used by VS Code.

stefanbschneider commented 1 year ago

My issue is:

brettcannon commented 1 year ago
  • It seems like VSCode still uses the pre-commit and thus the mypy that is globally installed with brew, not the one within the environment.

@stefanbschneider that's either a bug or an accidental misconfiguration. Feel free to open a new bug report following the instructions at https://aka.ms/pvsc-bug.