Open cmeyer opened 2 years ago
I also experienced this problem and traced it down to setuptools
v64 causing the issue. This version of setuptools
seems to cause editable packages to no longer be installed with an egg-link
file and now uses another mechanism. See release notes here: https://setuptools.pypa.io/en/latest/history.html#v64-0-0
If the editable package belongs to you, you could modify your pyproject.toml
like this:
requires = [
"setuptools==63.4.3",
"wheel"
]
Previously I had setuptools
without any version locking so I presume it was using setuptools
64.0.1
.
This seems to workaround the issue (albeit withholding setuptools
versions) although perhaps a fix does sit with Mypy.
Setting export SETUPTOOLS_ENABLE_FEATURES="legacy-editable"
(eg: with direnv or in Dockerfiles) and reinstalling things also worked for me (and should work if you can't update the project's pyproject.toml
).
Is there documentation on what exactly setuptools is doing now? mypy 0.971 should just be using sys.path, which is, y'know, the standard way of making packages findable
I think the relevant PEP is PEP 660, but I'm not sure if it has all the details. With the new wheels, the site-packages
directory ends up with files like this:
__editable__.org_pkg-2.1.0.pth # imports __editable___org_pkg_2_1_0_finder and calls install()
__editable___org_pkg_2_1_0_finder.py # some Finder magic w/ refs to the source path
org_pkg-2.1.0.dist-info/ # dist info like "normal" wheels
instead of an org-pkg.egg-link
file (I don't know why this would break mypy though).
I can post back with a minimum reproducing example shortly.
Oh, so setuptools has switched to using some import hook based approach instead of static entries in pth files? Note that the super standard pth file static directory install that everyone has been using for decades is perfectly valid under PEP 660.
I don't think there's any way for IDEs and static analysis tools to support import hooks. See https://mail.python.org/archives/list/typing-sig@python.org/thread/IIVBPYDZR5T5BGPAWFVYS5ZPYDXGVHQN/#OSWHT5VSRGKPSPYD7PQWR2M4OCSL5WO3 where maintainers of PyCharm, VSCode, Pyright, Pyre, etc are all on the same page about this.
This feels like a very bold move from setuptools. I'd recommend contacting them about this.
I'd recommend contacting them about this.
Done: https://github.com/pypa/setuptools/issues/3518, though I'm prepared for them to say similar. 😉
Yeah, well, so it goes. It's one thing if it was just mypy, but this will break all the tools 🤷
If a setuptools maintainer sees this, I recommend reading and then replying to that thread on typing-sig rather than discussing here.
For posterity, I made a repro repo here which shows the issues w/ mypy and pylint for these installs.
I think I am facing the exact same problem.
+1 comments aren't particularly useful here. But if you feel a need to post one, consider posting it on the setuptools issue instead.
I believe their current recommended solution is SETUPTOOLS_ENABLE_FEATURES="legacy-editable"
env var, although they may eventually remove it.
Eventually remove it? Like this issue persisting without even having a legacy fix?
I hate to say it but the changes the setuptools maintainers have made make supporting editable installs in mypy a lot more complicated, perhaps intractable in an efficient manner. We previously relied on static path calculation for this, but they no longer guarantee that (see attention note below linked section).
Therefore I regretfully propose that we drop support for editable installs. By that I mean just disable tests, and document that if you really need editable install support, you should use a src/
layout as the setuptools implementation uses a static .pth
file in that case and it might work.
For now I suggest we remove the tests for editable installs.
The approach we've taken with pyright and pylance is to document some workarounds for those who want to use editable installs. So far, everyone has had success following these suggested workarounds. Feel free to use them in the mypy documentation and tests if you find them useful.
FWIW --config-settings editable_mode=compat
(or strict
) did not work for me. However, I found it working if I specify py.typed
as package data:
[tool.setuptools.package-data]
"*" = ["py.typed", "*.pyi"]
Edit: I just found future versions of setuptools are going to include these files by default, see https://github.com/pypa/setuptools/pull/4021
1 when installing, use editable mode
--config-settings editable_mode=strict`
``
2. your package should export py.typed
[tool.setuptools.package-data] "" = ["py.typed", ".pyi"]
both are needed.
if someone winds up here because poetry doesn't support the `build` package config settings:
https://github.com/python-poetry/poetry/issues/8909
... it still doesn't
@earonesty, thanks for pointing this out! Also please forgive me for reformatting your comment for readability:
- when installing, use editable mode
--config-settings editable_mode=strict
- your package should export
py.typed
[tool.setuptools.package-data] "" = ["py.typed", ".pyi"]
Both are needed.
If someone winds up here because poetry doesn't support the
build
package config settings: python-poetry/poetry#8909 ...it still doesn't
For anyone reaching here and trying the following:
Setting export SETUPTOOLS_ENABLE_FEATURES="legacy-editable" (eg: with direnv or in Dockerfiles) and reinstalling things also worked for me (and should work if you can't update the project's pyproject.toml).
Note that it might not work with latest pip
versions as the don't support this behaviour.
Newer versions of pip no longer run the fallback command python setup.py develop when the pyproject.toml file is present. This means that setting the environment variable SETUPTOOLS_ENABLE_FEATURES="legacy-editable" will have no effect when installing a package with pip.
Reference: https://setuptools.pypa.io/en/latest/userguide/development_mode.html#legacy-behavior
same thing
(wonder who marked this comment as duplicate:
it is sort of disrespect to shut people up by hiding their comment like that, without any argument/explanation on why)
Perhaps we should provide a warning if we see a __editable__*.pth
file in any site directory, and link to some documentation about this behavior. We aren't likely to follow pth files with runtime imports, so I think that is the best we can do.
Perhaps we should provide a warning if we see a editable*.pth file in any site directory, and link to some documentation about this behavior. We aren't likely to follow pth files with runtime imports, so I think that is the best we can do.
This makes sense to me. Honestly, it should perhaps do the same thing whenever sys.meta_hook
is set.
Another thing that could also work is to allow the mypy
plugin system to emulate the meta_hook
behaviour by allowing a plugin to define the source code of an import.
For me personally, I want static analysis to be done on the code that actually gets run, and I'd be willing to pay the price of having plugins that minimally runs the interpreter to resolve that code correctly.
Bug Report
mypy does not recognize that libraries installed as editable using pip are fully typed even though the
py.typed
file is correctly included.To Reproduce
Working script which installs a NON-editable version of library:
Failing version which installs an editable version of a library:
Expected Behavior
These should work the same. The source client and underlying library are the same in both cases except one is installed as an editable install.
Actual Behavior
The failing version gives type errors:
Your Environment
mypy.ini
(and other config files): NoneAlso note: this behavior seems to have changed around 2022-08-10 to 2022-08-11. Something in the Python ecosystem seems to have changed. Nevertheless, this seems to be a bug in
mypy
since it is all about whetherpy.typed
is found or not.