-
-
Notifications
You must be signed in to change notification settings - Fork 1.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
protobuf type stubs obscure other imports from google.* #5800
Comments
We need to mark this package as "partial" by adding a |
@srittau does this need to be fixed first before adding any more packages in the google namespace? I'd be happy to give it a crack. It seems easy to knock off. Would it be possible to point me to the stub uploader code? I've grepped through the source code and can't see where the magic happens :) |
It's in https://github.com/typeshed-internal/stub_uploader. Probably https://github.com/typeshed-internal/stub_uploader/blob/main/scripts/build_wheel.py is what needs to change. |
I spend some time on this today. Apart from the weird problem I ran with pyright, I've found that the way we currently package those namespace packages leads to problems when uninstalling them. E.g. if I install Now I wonder whether any google namespace stub packages will have to be packaged together to avoid such a scenario. Or they will have to share a common directory under |
It seems, google-cloud-ndb depends on protobuf, so we could just make the types package depend on each other like this. This way, protobuf has the "common" files, and google-cloud-ndb doesn't. |
Maybe there should be a separate namespace package on which other packages would depend |
Reading PEP 561 again, I'm not sure,
Steps 4 and 5 are inline packages and typeshed, respectively. This means that |
That's my personal understanding (from our implementation in pyright/Pylance); the spec doesn't really allow for more than one partial package at a time (especially given that they must have By the same rules, a partial stub also can't override a py.typed library. Both things combined make our use of partial stubs in Pylance (working around hard-to-analyze libraries without fully typing them) a little fragile depending on the rest of the ecosystem. |
This is also a good idea. |
If I remember correctly, technically PEP 561 talks about the order to resolve modules aka |
Can you publish two partial distributions if |
I'm afraid I'm not sure I understand your scenario. Are you saying two namespace packages would interfere because they both need the py.typed at their root, and that would be an error on installation? |
Yes, that's what I'm describing. This would affect both typeshed and regular packages published to PyPI, as they all get placed in site-packages. |
I've actually had a look why def _entity_from_protobuf(protobuf):
"""Deserialize an entity from a protobuffer.
Args:
protobuf (google.cloud.datastore_v1.types.Entity): An entity protobuf
to be deserialized.
Returns:
.Model: The deserialized entity.
"""
ds_entity = helpers.entity_from_protobuf(protobuf)
return _entity_from_ds_entity(ds_entity) So arguably the types do not depend on each other, but I think the possibility for them to be installed in the same The idea of having a common namespace package is neat, but I doubt it would scale very well if there are more packages to be typed. |
Looking at the According to PEP-561 - it appears that when a stub package is present, type checkers should use it w/o falling back to the implementation library. See this comment in pyright's issue However, in this case, typeshed's stub uploader is creating a package What strategy should we use here? Ideally Is suspect we need to have the stub package for protobuf declare the namespace package here for things to work - so the "complete" protobuf stubs don't make it think that google.cloud is complete. I will try to experiment with it. https://github.com/typeshed-internal/stub_uploader/blob/main/scripts/build_wheel.py#L53 |
I played with this for a couple of hours. How do we expect a stub package for a namespace package to look? Ideally, we are able to claim full types on a stub package like The best guidance I can find is here https://www.python.org/dev/peps/pep-0561/#stub-only-packages - but it doesn't reference how namespace packages should work. Currently typeshed generates a package that looks like this
This seems wrong since I don't think the PEP-561 is clear on how this should work. I see two possible interpretations (neither of which work with either mypy or pyright today in my testing). The typeshed stub uploader does neither of these (see above). Interpretation 1
Interpretation 2
How should we proceed? [EDIT] - fixed a typo in my interpretations |
This would strike me as a bug (or, an oversight); this is probably the first time anyone's ever tried to make namespace stub packages. Namespace packages are notoriously tricky, and adding stub package logic on top is probably extra tricky and not yet handled. I think interpretation 1 is the one I would be expecting; IIRC we look for stub packages in the import roots, not deeper per-module; that'd be even more complicated, as any subdir of an import root could somehow modify the types of other import roots just by having a |
@erictraut may have some thoughts (he's probably only following the issues on pyright/pylance). |
Yeah this strikes me a bit as undefined behaviour? I actually commented on the original pyright issue from which this ticket was created, but it's very easy to get lost in confusing setups and I wasn't really helping getting to the bottom of this. I wanted to try reproduce this from scratch on the pyright side, but just haven't found the time to do so. |
Ok! So I was able to poke with this further. I was working on supporting Interpretation 1 in mypy. While working on python/mypy#11141 - I found that it does work in mypy if the Agree w/ @jakebailey on eliminating Interpretation 2 out of inelegance/unnecessary complexity My Proposed SolutionAccept Interpretation 1 above. Action items
Alternate Solution IdeasMandate
Ban namespace packages from using stub-only package distributions
|
Thanks @nipunn1313, that's great progress. I like your proposal. |
Hi, sorry I haven't been keeping up with this thread. Interpretation 1 is definitely correct. Since the package is called As for namespace packages in mypy, there is python/mypy#9636 to make it default but there are some issues with making it work with the daemon and cache, so it may not happen immediately. I definitely would be happy to review a suggested wording change to PEP 561 on this, I agree it really isn't clear. |
Just to clarify: Would we have one package |
@srittau - I'm have a terminology confusion about what a "package" is - I think the term is sometimes referring to a pip package, and sometimes to an installed directory (in I'll try to be clear about my terminology - and explain my sense of the ideal. Each of these google packages have a separate pypi distribution (eg protobuf and ndb and firestore. Each one can decide independently whether to use inline types via Each stub-only distribution will install into a common namespace-package in In this example, |
This only adds tests that show the current behavior when we provide a stub-only package for a subpackage of a namespace package Proposals for behavior changes exist in python/typeshed#5800 Real world example is the `protobuf` package which installs to `google.protobuf` and the `types-protobuf` package which installs to `google-stubs/protobuf` (where `google` is a namespace package)
Are there any workarounds for that now? I would just remove protobuf-types, but it's a transient dependency. |
I reproed like this with pyright (not with mypy)
This is a workaround microsoft/pyright#2113 (comment) And we hope to have an imminent fix available here #8937 (comment) |
Is this still an issue now that |
It appears to be fixed, thanks! |
Fantastic! |
See this issue: microsoft/pyright#2113
The text was updated successfully, but these errors were encountered: