-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Support egg installs with PEP 561 searching #5007
Comments
Running Development installs on the other hand aren't intended to be supported, at least for now, as they don't put the files in the path, so you will need to handle this manually, just like before. I will look at the possibility of adding this. |
Thank you for your quick reply! I did a bit of digging into the That's good to know and definitely understandable that the development use case (with |
The stubs contained an unconditional reference to SupportsBytes, which only exists in Python 3. To make these valid on Python 2, conditionally import that Protocol in Python 3 and otherwise use a dummy class in Python 2. Also have `ndarray` extend `Contains`, while we're here. This also extends the test suites to run all tests against both Python 2 and Python 3, with the ability to specify that certain tests should only be run against Python 3 (eg to test Python 3 exclusive operators). This should help prevent errors like this moving forward. One downside of this is that flake8 doesn't understand the `# type:` comments, so it thinks that imports from `typing` are unused. A workaround for this is to add `# noqa: F401` at the end of the relevant imports, though this is a bit tedious. Finally, change how test requirements are installed and how the `numpy-stubs` package is exposed to mypy, and update the README/Travis file to reflect this. See python/mypy#5007 for more details about the rational behind this change.
Hm, it does sound strange that MYPYPATH has any effect here at all (unless
it's via the normal pre-PEP-561 code?).
I do think it would be nice for both `python setup.py install` and `pip
install -e .` to work interchangeably, since they do so in other situations
as well.
|
I just took a look and this doesn't seem too hard to support, essentially we just need to look where the
Yes, I agree. @FuegoFro could you give exact commands that you issued? It will be helpful in understanding what the issue is.
The complication is this doesn't always agree well with mypy's view "its a module if its a file in the path, or in a package on the path". This is almost the case except for egg distributions, which are either a directory containing the package, or a zipped version of it. Though I don't like it, I think we should support egg installs, however weird they are. This would involve special casing files/directories ending in This will be a bit more painful than supporting editable installs. |
Hm, but I still wish `pip install -e .` would also work.
Perhaps we can ask the Python executable which you're asking for the
location of its site-packages to do the digging for us?
|
Yeah, this should be pretty easy to handle.
Unfortunately, this would introduce a lot of overhead because we'd need to shell out for each package. Ideally we can special case egg installations and everything else should "just work". |
... we'd need to shell out for each package ...
Oops, never mind then. That's prohibitively expensive.
|
Regarding
I'm pretty sure this is due to the Given this it seems like it wouldn't be too bad to support |
Hm, thinking about it more, looking for foo-stubs along $MYPYPATH (or
really the whole search path that mypy constructs) makes some sense.
|
Okay, I will try getting this to work after I add develop install support. |
* Ensure stubs are valid for Python 2 and fix running of tests The stubs contained an unconditional reference to SupportsBytes, which only exists in Python 3. To make these valid on Python 2, conditionally import that Protocol in Python 3 and otherwise use a dummy class in Python 2. Also have `ndarray` extend `Contains`, while we're here. This also extends the test suites to run all tests against both Python 2 and Python 3, with the ability to specify that certain tests should only be run against Python 3 (eg to test Python 3 exclusive operators). This should help prevent errors like this moving forward. One downside of this is that flake8 doesn't understand the `# type:` comments, so it thinks that imports from `typing` are unused. A workaround for this is to add `# noqa: F401` at the end of the relevant imports, though this is a bit tedious. Finally, change how test requirements are installed and how the `numpy-stubs` package is exposed to mypy, and update the README/Travis file to reflect this. See python/mypy#5007 for more details about the rational behind this change. * Split `pip install .` out of the `test-requirements.txt` file, update Travis and README files accordingly.
Good news! The implementation was a lot easier than I expected. I implemented and tested support for:
this leaves:
The format descriptions here are quite helpful: https://github.com/pypa/setuptools/blob/master/docs/formats.txt |
Talking to Jason Coombs, eggs are essentially deprecated. Therefore, I will only work on adding support for egg-link. I will add to the documentation that packages should be installed with pip when I add support for that. |
I don't think the egg-links are relevant for this use case; as far as I can tell, they are only used for setuptools to be able find package metadata, not for actually setting your search path. If you install with In def getsitepackages():
# type: () -> List[str]
if hasattr(site, 'getusersitepackages') and hasattr(site, 'getsitepackages'):
user_dir = site.getusersitepackages()
return site.getsitepackages() + [user_dir]
else:
return [get_python_lib()] There does not appear to be any good way to re-use the logic in
Is there any reason not to just use this to get the exact same search path as you'd get if just executing the code? |
@lambda yes, your points are well made. I used the name "egg-link" instead of editable install, but I mean editable install, which is the type of installation you are talking about. I think the best plan is to inspect Edit: Also keep in mind, this information needs to be statically found (as much as possible) for a python executable handed to mypy. |
This adds support for setuptool's egg format, which includes support for editable installs (`pip install -e .`/`python setup.py develop`)! Setuptools creates its own directory to put the package we want to find. These directories are listed in `easy-install.pth` in a site-package directory. Fixes #5007.
When working on a repo containing types to be distributed in accordance with PEP 561 (such as https://github.com/numpy/numpy-stubs) it is surprisingly difficult to get mypy to actually see and respect those types. In particular, things that do not work (though I would expect them to):
-stubs
directory to theMYPYPATH
python setup.py install
pip install -e .
I eventually was able to make it work by running
pip install .
, but (particularly for things like runningpy.test
while developing one of these stubs repos) this seems non-optimal.Interestingly, adding the directory containing the
-stubs
directory toMYPYPATH
did allow me to resolve types in the root of the package we care about (in this casenumpy
), but not in nested packages (in this casenumpy.core
). It looks like this might have something to do with this code wheredir_chain
is an empty string when looking for a top-level package and thereforefind_lib_path_dirs
doesn't filter out the items inlib_path
. When we're trying to get a nested package it's non-empty and can't be found in thelib_path
dirs, which then get filtered out. We also don't populatethird_party_stubs_dirs
in any of the above cases because the items onMYPYPATH
aren't looked at for that (only site packages) and the other two methods don't create a bare directory named-stubs
in the site packages (one creates a.egg
and the other creates a.egg-link
).I did these experiments on commit
7fe60a547c476c8b341a47b87d72fc4460532102
of mypy with Python 3.6.4 on macOS.Let me know if there's anything else I can provide which would be helpful! I'm not sure if this is more of a bug or a feature request because I couldn't tell from my reading of PEP 561 whether this use case was covered by that.
The text was updated successfully, but these errors were encountered: