You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Let's say we have two separate packages, a and b. b depends on stuff in a, so a is installed when b is installed. E.g., there's a module in b that does the following:
If I run mypy on b/module.py I will get the following error: error: Cannot find module named 'a', even though a is installed in my virtualenv.
As I understand it, this is the intended behavior, and the solution is to either append --ignore-missing-imports or add stubs to typeshed.
The problem in our case is that
a is a private package we have developed for our own internal use, so typeshed is not an option
mypy --ignore-missing-imports b/module.py will not be able to verify that module.bar correctly calls module.foo
attempting to add my virtualenv's packages to MYPYPATH seems to be highly discouraged, and is also not a great option because b might also depend on and install 3rd party stuff that isn't properly type hinted
So basically, my question is this: How can we tell mypy to include the imported package a when typechecking b?
I suppose we could add .pyi stubs for a inside the b repository and point MYPYPATH there, but that is suboptimal as it would require us to maintain the API for a in two separate repositories, and entirely unnecessary since everything in a is already properly type hinted.
You can write or generate your own stubs for a and update MYPYPATH to include the directory containing those stubs (the parent of the directory a containing a/module.pyi etc., presumably).
Or, assuming the source for a type-checks without errors, you can point mypy at package a directly, again by setting MYPYPATH -- the trick is that you shouldn't use the installed version of a, because that presumably contains lots of other 3rd party packages/modules for which you would prefer the typeshed stubs.
Sorry for taking so long to respond, but I haven't had the opportunity to try this out until now.
Now I've tried both approaches.
As I mentioned in my original post, writing or generating stubs incurs an unnecessary maintenance burden I would prefer to avoid, since a type-checks without issues.
Pointing MYPYPATH to a cloned repo of a is a better approach, but requiring that a is cloned somewhere locally is also a bit annoying, especially since it is already installed and available in the virtualenv.
Ideally, I would have liked to be able to explicitly whitelist specific packages inside the virtualenv's site-packages folder. E.g., MYPYPATH_WHITELIST=some_package:some_other_package, and make mypy aware that usage of some_package and some_other_package should be type-checked if found to be installed in the venv.
Or is that something you don't want to support with mypy?
@JelleZijlstra Does that solve the issue I have, though? I don't see the point of using .pyi files (i.e., stubs), if the .py files themselves are already type hinted. It's like we're regressing back to requiring C header files.
Or can .py files be used as stubs as well?
To exemplify, I've solved the issue I describe in the previous posts by having my tox.ini copy some_package and some_other_package from site-packages into a temp-folder, then pointing MYPYPATH there. I.e.,
The problem with using .py files is that they might only type check cleanly with specific mypy options, or only with specific mypy versions. Stub files are more likely to work consistently in multiple contexts, though even there it's possible to have issues if Optional[...] is not used consistently. One option that we've discussed is making a tool that can automatically generate annotated .pyi files from .py files. Then a 3rd party package would ship annotated .py files and automatically generated .pyi files, and mypy would somehow automatically find and use the .pyi files. Another option would be to implicitly ignore all type errors in 3rd party modules, but that would be less robust as mypy version incompatibilities can result in invalid inferred types for public methods, for example.
One option that we've discussed is making a tool that can automatically generate annotated .pyi files from .py files. Then a 3rd party package would ship annotated .py files and automatically generated .pyi files, and mypy would somehow automatically find and use the .pyi files.
Note that there is #3169 for preserving existing annotations by stubgen. I hope @dmoisset will continue working on it.
Just preserving annotations is not quite enough, since some types are inferred. Stubgen would have to type check the code and then print out the inferred types.
Well, to be honest, I am personally not that enamored with stubs, since I think they are redundant in the same way I think header files are redundant. I see why they exist, and why they might be required in some cases, but I don't understand why they should be required. And as my hacky workaround above shows, they aren't actually necessary at all.
A mypy user who wants to utilize 2nd/3rd party .py files from some arbitrary installed package when type checking their code, should be able to do so, don't you think? Obviously, it's then also up to the user to worry about whether the correct mypy options/versions are in effect.
Anyway, I'm asking for clarification here because I want to know if you are at all open to the idea of adding the option to whitelist stuff in site-packages. If yes, I could start working on a pull request, but I realize that what I'm asking for might not be general enough for inclusion in mypy, and I don't want to waste time implementing something you don't want at all.
We are open to the idea, but it's not clear what the option should look like. Preferable a user shouldn't need to know which packages have inline annotations in them -- mypy should be able to figure this out automatically somehow. Perhaps each package should declare the presence of inline annotations. There is more discussion about this topic in #1190. Maybe we should close this issue and continue discussion in #1190?
Here's a summary of how this could move forward:
Propose a concrete approach for how to do this (no implementation yet) in Search procedure for inline annotations #1190. Read the existing discussion first -- there are a bunch of things to consider.
Once we reach agreement, you (or somebody else) can implement it in mypy.
Once there is an implementation, somebody can write it up as a PEP in case the approach can be generalized to other tools beyond mypy.
Activity
gvanrossum commentedon May 10, 2017
You can write or generate your own stubs for
aand updateMYPYPATHto include the directory containing those stubs (the parent of the directoryacontaininga/module.pyietc., presumably).Or, assuming the source for
atype-checks without errors, you can point mypy at packageadirectly, again by settingMYPYPATH-- the trick is that you shouldn't use the installed version ofa, because that presumably contains lots of other 3rd party packages/modules for which you would prefer the typeshed stubs.eddie-dunn commentedon Jun 28, 2017
Sorry for taking so long to respond, but I haven't had the opportunity to try this out until now.
Now I've tried both approaches.
As I mentioned in my original post, writing or generating stubs incurs an unnecessary maintenance burden I would prefer to avoid, since
atype-checks without issues.Pointing MYPYPATH to a cloned repo of
ais a better approach, but requiring thatais cloned somewhere locally is also a bit annoying, especially since it is already installed and available in the virtualenv.Ideally, I would have liked to be able to explicitly whitelist specific packages inside the virtualenv's
site-packagesfolder. E.g.,MYPYPATH_WHITELIST=some_package:some_other_package, and make mypy aware that usage ofsome_packageandsome_other_packageshould be type-checked if found to be installed in the venv.Or is that something you don't want to support with mypy?
JelleZijlstra commentedon Jun 28, 2017
I'm working on a proposal to standardize a way to have a site-packages-like directory for stubs; see python/typing#84.
eddie-dunn commentedon Jun 29, 2017
@JelleZijlstra Does that solve the issue I have, though? I don't see the point of using
.pyifiles (i.e., stubs), if the.pyfiles themselves are already type hinted. It's like we're regressing back to requiring C header files.Or can
.pyfiles be used as stubs as well?To exemplify, I've solved the issue I describe in the previous posts by having my tox.ini copy
some_packageandsome_other_packagefrom site-packages into a temp-folder, then pointingMYPYPATHthere. I.e.,It works, but it's an ugly hack.
JukkaL commentedon Jun 29, 2017
The problem with using
.pyfiles is that they might only type check cleanly with specific mypy options, or only with specific mypy versions. Stub files are more likely to work consistently in multiple contexts, though even there it's possible to have issues ifOptional[...]is not used consistently. One option that we've discussed is making a tool that can automatically generate annotated.pyifiles from.pyfiles. Then a 3rd party package would ship annotated.pyfiles and automatically generated.pyifiles, and mypy would somehow automatically find and use the.pyifiles. Another option would be to implicitly ignore all type errors in 3rd party modules, but that would be less robust as mypy version incompatibilities can result in invalid inferred types for public methods, for example.ilevkivskyi commentedon Jun 29, 2017
Note that there is #3169 for preserving existing annotations by
stubgen. I hope @dmoisset will continue working on it.JukkaL commentedon Jun 29, 2017
Just preserving annotations is not quite enough, since some types are inferred. Stubgen would have to type check the code and then print out the inferred types.
eddie-dunn commentedon Jun 29, 2017
Well, to be honest, I am personally not that enamored with stubs, since I think they are redundant in the same way I think header files are redundant. I see why they exist, and why they might be required in some cases, but I don't understand why they should be required. And as my hacky workaround above shows, they aren't actually necessary at all.
A mypy user who wants to utilize 2nd/3rd party
.pyfiles from some arbitrary installed package when type checking their code, should be able to do so, don't you think? Obviously, it's then also up to the user to worry about whether the correct mypy options/versions are in effect.Anyway, I'm asking for clarification here because I want to know if you are at all open to the idea of adding the option to whitelist stuff in site-packages. If yes, I could start working on a pull request, but I realize that what I'm asking for might not be general enough for inclusion in mypy, and I don't want to waste time implementing something you don't want at all.
JukkaL commentedon Jun 29, 2017
We are open to the idea, but it's not clear what the option should look like. Preferable a user shouldn't need to know which packages have inline annotations in them -- mypy should be able to figure this out automatically somehow. Perhaps each package should declare the presence of inline annotations. There is more discussion about this topic in #1190. Maybe we should close this issue and continue discussion in #1190?
Here's a summary of how this could move forward:
ambv commentedon Jul 13, 2017
Since this is not mypy-specific, I'd suggest continuing in python/typing#84.
emmatyping commentedon Sep 6, 2017
Closing in favor of python/typing#84.