Skip to content

pyright tests: doesn't support __getattr__ for resolving submodules #5598

Closed as not planned

Description

@srittau

Example: stubs/paramiko/paramiko/kex_ecdh_nist.pyi contains imports from cryptography, but pyright can't find cryptograpy, probably because it's "hidden" in stubs/cryptography. Cc @erictraut and @jakebailey: Do you have any ideas how we could fix this?

Activity

  1. erictraut commented on Jun 9, 2021

    @erictraut
    Contributor

    Can you point to a specific example?

    On initial investigation, it looks like paramiko is accessing some modules in cryptography that are missing stubs. For example stubs/paramiko/paramiko/kex_curve25519.pyi imports from cryptography.hazmat.primitives.asymmetric.x25519 which has a stub, and the import succeeds. But stubs/paramiko/paramiko/kex_ecdh_nist.pyi imports from cryptography.hazmat.primitives.asymmetric.ec2, and there is no stub for that module, so the import fails.

  2. srittau commented on Jun 9, 2021

    @srittau
    CollaboratorAuthor

    I blame my morning tiredness for missing the 2 at the end of that filename. That said, cryptography/cryptography/hazmat/primitives/asymmetric/__init__.pyi contains a __getattr__() definition, meaning that all non-existing sub-modules should exist (as Any).

  3. erictraut commented on Jun 9, 2021

    @erictraut
    Contributor

    Pyright doesn't currently apply the module-level __getattr__ for submodule resolutions. Doing so would be quite expensive at analysis time because it would need to parse and bind every module along the import path to determine whether any of the parent modules contain this directive, so I'd prefer not to implement this unless it's really needed. This is the first time I've heard of a stub that depends on that behavior.

  4. Akuli commented on Jun 9, 2021

    @Akuli
    Collaborator

    Suppose a stub does from foo.bar import baz. First we find a folder named foo/, and this is the only step where the entire import path is needed. Then, to make this work, we would look for def __getattr__ in foo/__init__.py. Most of the time it shouldn't make things slower, because it's only needed in the less likely case that foo/bar.py doesn't exist. What am I missing?

  5. srittau commented on Jun 9, 2021

    @srittau
    CollaboratorAuthor

    The good news is that the ec2 module does not seem to exist at runtime, either, so I'm just going to fix the import. There is no immediate need to fix this and we'll see what the future brings. We should leave this issue open, though.

  6. jakebailey commented on Jun 9, 2021

    @jakebailey
    Contributor

    This likely negatively affects the new PIL stubs (#5594); in the ones I wrote that ship with Pylance (https://github.com/microsoft/python-type-stubs/tree/main/PIL), I made the stub py.typed with partial to avoid warnings about unresolved imports (for modules I didn't explicitly mark as incomplete).

    In general, we assume that stub packages that aren't partial to be complete, including that a given module doesn't exist. The import resolver doesn't really have access to the analysis info like "this file is marked as incomplete via a __getattr__" (it doesn't read the contents at all, it's purely based on the filesystem layout).

  7. changed the title [-]pyright tests: Can't import from other third-party stubs[/-] [+]pyright tests: doesn't support `__getattr__` for resolving submodules[/+] on Jun 20, 2022
  8. hauntsaninja commented on Jun 20, 2022

    @hauntsaninja
    Collaborator

    (retitled the issue to be more specific, feel free to change if I misunderstood what's going on here)

  9. srittau commented on May 13, 2025

    @srittau
    CollaboratorAuthor

    I'm not sure this is still a problem. If it is, we can always open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions