-
-
Notifications
You must be signed in to change notification settings - Fork 44
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
Stubs from pypi are not found by mypy #39
Comments
I ran into this issue myself and monkey-patched a hacky solution. Here's what I discovered:
Mypy also offers a MYPYPATH, but it does not use the "...-stubs" layout, so we can't just stick all of the Bazel PyPI directories into the MYPYPATH (I tried that initially). So, here's my hacky solution: step 1: monkey patch mypy modulefinderI grabbed all the pypi__ paths from sys.path, then I added them as new "site packages".
step 2: add type packages as dependenciesThe types-... packages need to be available to the mypy binary when it does the type checking, so I just added them as dependencies:
These also need to be added to your
I applied both of these patches in my workspace file like so:
Of course, I think it would be ideal to have native support for this sort of thing (or let me know if I'm doing something wrong), but this solution works for me in the short-term. |
I'm also affected by this issue. |
At a high level, the issue is that Bazel creates a non-idiomatic layout of python files. It then provides a "stub" in py_binary which tries to correct for this layout by doing things like patching up the So at a high level I think there are two solutions:
|
This involves setting the PYTHONPATH (sys.path), if I understand you correctly. I think there is a third solution, which is make the packages available via MYPYPATH as the original author has attempted.
This approach suffers from another problem, which is that the python packages installed on the system leak into the Bazel python setup and are available to the mypy command. This can be verified by simply pip-installing |
I think this is a great initiative but since this still seems experimental I think it would be useful to also support users that use the more standard |
rules_py would be in addition to rules_python, not replacing it. In that model, it's just these type-checking actions which would run inside a standard virtualenv created by those rules, but all other actions/tests would be unaffected. |
Ok, makes sense, and sounds good to me! |
Dropping some notes here about my option 2 above:
I think the conclusion here is that rules_py isn't ready for this use case, and we'd need still need some monkey-patch hacks to get it to work. |
Looking at the runfiles, we have the following structure for
Looking inside If yes, there is a problem that the dep[PyInfo].transitive_sources which is at line 75 of |
This was fixed in mypy 0.971 🎉 https://mypy-lang.blogspot.com/2022/07/mypy-0971-released.html |
When I use mypy version
See example invocation: https://app.buildbuddy.io/invocation/82dd2ab8-d1de-4cf5-a1ca-7cd350927bf7. I'm currently using |
Signed-off-by: Thomas Lam <[email protected]>
@robin-wayve Do you mind elaborate on what exactly got fixed by
What's the latest suggestion to make this work (I didn't try the monkey-patch approach yet as I don't want to push this to everyone my the project ^^) |
Reading through the comments, it's not clear to me why this regressed. If I use an older release, I do not experience any of the errors described by others, with any mypy version. git_repository(
name = "mypy_integration",
commit = "c1193a230e3151b89d2e9ed05b986da34075c280",
remote = "https://github.com/thundergolfer/bazel-mypy-integration",
shallow_since = "1639112081 +1100",
) If I try a newer release, such as git_repository(
name = "mypy_integration",
commit = "285d2a0d31c42eb273a0287195d36c6908d6e838",
remote = "https://github.com/bazel-contrib/bazel-mypy-integration",
shallow_since = "1665756151 -0700",
) I begin experiencing the "Cannot find implementation or library stub for module" errors. |
@ph03 The issue I linked is what got fixed: mypy changed to search I can't speak for all of this integrating with versions of |
Any updates on this? I'm using mypy version 0.971 and bazel-mypy-integration 0.4.0 but mypy is still complaining that it cannot find my external libraries. |
I'm experiencing this as well. @alexeagle given that a year has passed, do you think rules_py is capable of helping with this now? |
We're discussing it again now, but it would still help to have a funding source for this repo. https://opencollective.com/bazel-rules-authors-sig currently owes more than it has. |
I've been working on a separate project based on this one since we haven't seen a lot of activity in this repo lately, and added support for PEP-561 stub packages over here: alexmirrington/rules_mypy#9 |
Hey @alexmirrington I finally have some client funding for working on mypy again. I'm interested to study what you've done and collaborate on this :) |
@alexeagle Great to hear! The biggest learning I've found from playing around with PEP-561 stub packages is that it's easiest to generate a virtual environment and use the I've had success with this using I'm currently working on creating some venv rules to replace the starlark I wrote to symlink stubs, would be keen to see if you have any other ideas |
rules_py creates a venv for every binary/test, I think it could probably create one for libraries as well. See aspect-build/rules_py#235 and https://github.com/aspect-build/rules_py/blob/main/docs/rules.md#py_venv |
Just to add here, one way to make stubs available to mypy is to make it available to mypy binary as deps: # in /toolings/typing/BUILD
load("@rules_python//python/entry_points:py_console_script_binary.bzl", "py_console_script_binary")
load("@pip…", "requirement") # your pip setup
py_console_script_binary(
name = "mypy",
pkg = "@pip…//mypy", # your pip setup
deps = [
requirement("grpc-stubs"),
requirement("pytest"),
],
) Then provide this as the mypy via the .bazelrc
This wasn't obvious to me so it might help someone else. Perhaps it could be an example or documented use case. |
I've tried several different ways of referencing packages like
types-python-dateutil
from PyPI and I can't get any of them to actually provide the type stubs to mypy usingbazel-mypy-integration
.Here's a repo where I've demonstrated the approaches I've tried.
requirement()
a dependency of thepy_binary
target passed tomypy_test
.mypy_stubs
target manually pointing at the.pyi
files inside the pypi target.mypy_stubs
target pointing at the pypi target as returned byrequirement()
. This one causes bazel errors because thepy_library
rule internal to thepip_install
workspace rule does not include.pyi
files in itssrcs
(only indata
), as I understand it.When running
bazel test --test_output=all //:uses_deps_mypy
, I see the following output:Interestingly, if I run mypy manually using the stubs as downloaded by bazel from pypi, I get the same error:
But if I rename the directory to
dateutil
, it works (obviously this is not sane as one shouldn't muck around in the bazel cache, but it helps demonstrate that mypy and the bazel plumbing do not seem to agree on directory structure):What is the intended way to use stub libraries from PyPI with
bazel-mypy-integration
?The text was updated successfully, but these errors were encountered: