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

mypy+poetry - using the wrong mypy. #917

Closed
nipunn1313 opened this issue Apr 18, 2023 · 9 comments
Closed

mypy+poetry - using the wrong mypy. #917

nipunn1313 opened this issue Apr 18, 2023 · 9 comments
Assignees

Comments

@nipunn1313
Copy link

From command line

mypy . # fails due to missing installed dependencies
.venv/bin/mypy . # passes
.venv/bin/python -m mypy . # passes

I found that coc-pyright is using mypy rather than .venv/bin/mypy, meaning it's not grabbing the venv dependencies when typechecking.

Issue is similar, but different from #324
I've set up my workspace root correctly (:CocList folders looks good).

As you can see here, it's appropriately using .venv/bin/python.
However, it's using the mypy I have installed globally rather than .venv/bin/mypy (or alternately .venv/bin/python -m mypy.

What's the output of :CocCommand pyright.version
[coc.nvim] coc-pyright 1.1.303 with Pyright 1.1.303

What's the output of :CocCommand workspace.showOutput Pyright
more relevant is coc-pyright-linting here

  Using python from /Users/nipunn/src/convex/smoke/.venv/bin/python

  ########## active linter: mypy
  ########## Run linter mypy:
  {"execPath":"/Users/nipunn/.pyenv/shims/mypy","args":["--no-pretty","--ignore-missing-imports","--follow-imports=silent","--show-column-numbers","/Users/nipunn/src/convex/smoke/conftest.py"],"  product":7}

  ########## Linting Output - mypy ##########
  conftest.py:30:1: error: Library stubs not installed for "requests"  [import]
  conftest.py:31:1: error: Library stubs not installed for "requests.adapters"  [import]
  conftest.py:31:1: note: Hint: "python3 -m pip install types-requests"
  conftest.py:31:1: note: (or run "mypy --install-types" to install all missing stub packages)
  conftest.py:31:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
  conftest.py:32:1: error: Library stubs not installed for "decorator"  [import]
  conftest.py:32:1: note: Hint: "python3 -m pip install types-decorator"
  Found 3 errors in 1 file (checked 1 source file)

Appreciate all the work you do on coc-pyright. It's a good plugin!

@lithammer
Copy link
Contributor

It's just using mypy from $PATH. So you have to activate the virtualenv first.

@nipunn1313
Copy link
Author

Pardon my ignorance, but why activate?

coc-pyright works very hard to use the correct workspace root.

Then coc-pyright is correctly automatically using the python from the env without explicitly activating it, based on the workspace root inference.

  Using python from /Users/nipunn/src/convex/smoke/.venv/bin/python

Seems reasonable to use the mypy inside the venv (or otherwise use a mypy that has knowledge about the venv).

Alternately, mypy has this --python-executable flag to help it find the packages - https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-python-executable

But I think the better solution is to run mypy through the selected python executable (via something like python -m mypy)

@yaegassy
Copy link
Contributor

@nipunn1313 If you want to use the mypy of your project without activate a virtual environment, please set python.linting.mypyPath in coc-settings.json or .vim/coc-settings.json.

Currently, in coc-pyright, each tool for linting and formatting is implemented as command execution rather than module execution.

The process of determining whether a tool can be executed as a module in an existing Python environment may vary for each tool and may become complex. Furthermore, ruff cannot be executed as a python module in the first place.

@fannheyward
Copy link
Owner

coc-pyright runs third Python tools, parses results and applies.

The key point: how to run third tools. coc-pyright supports sub process execution and module execution.

The previous:

  1. get tool's path from settings, by default is mypy, use it as execPath
  2. path.basename(execPath) === execPath, use it as module name
  3. tool info: execPath = mypy, moduleName = mypy
  4. run the tool with python, in this case, prefer module execution, python -m mypy
  5. if user has change the path in settings, for example, ~/bin/mypy, now we have execPath = ~/bin/mypy
  6. path.basename(execPath) is not equal to execPath, module name is undefined
  7. run in sub process mode, ~/bin/mypy xxx

This should be what you want, but this solution has another problem: we need to install the tool in every projects, we can't use global tool for projects.

In 3d987bc, I've changed to:

  1. get tool's path from setting, execPath = mypy
  2. use which to get full exec path, execPath = /full/path/to/mypy
  3. now basename never equal to execPath, module name is undefined
  4. run in sub process mode, /full/path/to/mypy xxx

The new logic broken the module mode, but with some better use cases:

  1. the tool is installed globally, we find and use it like /path/to/global/mypy
  2. the tool is installed in project's venv, something like /path/to/project/.venv/bin/mypy

For your case, you have both global and project-level tool installed, but they're different, you can activate venv first to use it.

We can find for a better way to run third tools.

@fannheyward
Copy link
Owner

coc-pyright works very hard to use the correct workspace root.

Thank you for your feedback, coc-pyright did a lot to use the correct Python/tools, to work as correctly as possible.

@lithammer
Copy link
Contributor

lithammer commented Apr 19, 2023

Couldn't the logic be something like this? If pythonPath has been resolved to something in a virtualenv (e.g. .venv/bin/python). Store const venvBinPath = path.dirname(pythonPath). And then when running mypy you first try path.join(venvBinPath, 'mypy'). And if that fails, look in $PATH?

You could maybe even do that logic during startup and save the absolute path to the binary so you don't have to run a subprocess twice in the global case.

@nipunn1313
Copy link
Author

This should be what you want, but this solution has another problem: we need to install the tool in every projects, we can't use global tool for projects.

Great point - thanks for clarifying.
I do think https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-python-executable is then probably the better solution. For my particular issue, more important than using the correct mypy, is ensuring that mypy is configured with the appropriate python executable (and thus resolves imports correctly).

Using the mypy in the venv does this automatically, but broadly speaking, if working on a project whose workspace root finds a venv (eg via poetry), setting --python-executable to the python in that venv would be valuable.

Is there a way to configure this? Something like this, where coc-pyright fills in the workspace root.

"python.linting.mypyArgs": ["--python-executable", $workspace_root]

@fannheyward
Copy link
Owner

@nipunn1313 try v1.1.304.

@nipunn1313
Copy link
Author

Tried it out! Works great! Thanks @fannheyward .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants