-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Editable installs are not recognized as having typing when using py.typed (setuptools v64 issue) #13392
Comments
I also experienced this problem and traced it down to If the editable package belongs to you, you could modify your requires = [
"setuptools==63.4.3",
"wheel"
] Previously I had This seems to workaround the issue (albeit withholding |
Setting |
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
instead of an 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 This feels like a very bold move from setuptools. I'd recommend contacting them about this. |
Done: pypa/setuptools#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 |
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 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 [tool.setuptools.package-data]
"*" = ["py.typed", "*.pyi"] Edit: I just found future versions of setuptools are going to include these files by default, see pypa/setuptools#4021 |
fixes: #868 this appears to be a known issue stemming from the use of import hooks to comply with pep 660 - see for example python/mypy#13392 and pypa/setuptools#3518. What's happening is that for editable installs `setuptools` creates files like `.../site-packages/__editable__.general_superstaq-0.5.5.pth` which are supposed to point python to the source directory. Previously these would just be text files containing a single path, e.g. ``` /<...>/client-superstaq/general-superstaq ``` but after switching to pyproject.toml it becomes an executable hook, e.g. ```python import __editable___general_superstaq_0_5_5_finder; __editable___general_superstaq_0_5_5_finder.install() ``` where `__editable___general_superstaq_0_5_5_finder.py` is another file saved in the site-packages directory. this breaks static analysis tools because they won't execute the required code afaict this pr seems to be the cleanest workaround - after these changes setuptools seems to generate the old-style `.pth` files (i.e. text files containing paths to the source directories), and `mypy` behaves as expected (at least for me)
Needed because of python/mypy#13392
1 when installing, use editable mode
[tool.setuptools.package-data]
|
@earonesty, thanks for pointing this out! Also please forgive me for reformatting your comment for readability:
|
For anyone reaching here and trying the following:
Note that it might not work with latest
Reference: https://setuptools.pypa.io/en/latest/userguide/development_mode.html#legacy-behavior |
This comment was marked as duplicate.
This comment was marked as duplicate.
Perhaps we should provide a warning if we see a |
This makes sense to me. Honestly, it should perhaps do the same thing whenever Another thing that could also work is to allow the 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. |
Djblets has historically been a setuptools-based project, relying heavily on the dynamic ability of `setup.py`. Over the years, the Python ecosystem has moved to `pyproject.toml` files, with pluggable build backends. This has reached a point of maturity, and `pip` will soon remove support for installing either production or editable installs from a legacy source tree. In theory, modernization requires just providing a `pyproject.toml` that specifies `setuptools` as a build backend. A project can still use `setup.py` for the project definition and dynamic capabilities. However, since packages are also now built in a virtualenv, it's become clear that we needed to address about our packaging. We now use `pyproject.toml` to define most of the metadata of the package. The build backend is then a specialization of `setuptools.build_meta`, living in `build-backend.py` at the root of the tree. This specializes a few things about our build process: 1. It uses all of Djblets's dependencies as build-system dependencies, needed in order to build static media for the package. 2. It builds the static media, including them in both sdist and wheel distributions. 3. It writes out a `package-requirements.txt` at build time with the dependencies from `djblets/dependencies.py`, which setuptools can then consume. This is also bundled in the sdist. With this, we no longer need `setup.py`, and constrain all custom logic to `build-backend.py`. Some things to note: 1. `python -m build .` will default to building an sdist and then a wheel from that sdist, whereas `build . -w` will build a wheel straight from the tree. Due to differences in the prep stages, and what's built from what, we need to micromanage some state (like `package-requirements.txt`) in different places. 2. Other build backends (hatch, PDM, flit, and poetry) were evaluated and discarded. These are great backends, but don't solve the core problems we've had to work around out of the box, and sort of want to manage more of the development and build process. `setuptools` is a known entity for us, and will be needed for extension packaging anyway, so we're sticking with it. 3. `Makefile` installs the package in editable-compat mode. This uses standard `.pth` files instead of newer `setuptools`-based import hooks, in order to allow `mypy` and `pyright` to find type definitions. See python/mypy#13392 and pypa/setuptools#3518. Testing Done: Tested isolated builds in the following setups: * `python -m build .` (builds sdist, then a wheel from the sdist) * `python -m build . -s` (builds sdist) * `python -m build . -w` (builds wheel) Tested isolated editable installs using `pip install -e .` and non-isolated editable installs using `pip install -e --no-build-isolation` and with `make develop`. Performed full tree diffs of generated wheels from `./setup.py bdist_wheel` (prior to this change) and both wheel-producing `python -m build` methods. Verified that all content was identical, with the exception of differences in source map paths and some modern metadata for the package. Reviewed at https://reviews.reviewboard.org/r/14137/
As mypy does not support editable installs for projects that have a pyproject.toml and use a build backend that supports PEP 660, force the legacy behavior of editable installs by passing the configuration settings "editable_mode=compat" to the build backend. It enables to remove the pip version restriction in the swh venv and avoid bad surprises when the mypy pre-commit hook is called when committing in a swh repository. See python/mypy#13392 for more details.
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.The text was updated successfully, but these errors were encountered: