Skip to content
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

error: "type" has no attribute "from_private_key" #16153

Closed
rectalogic opened this issue Sep 20, 2023 · 2 comments
Closed

error: "type" has no attribute "from_private_key" #16153

rectalogic opened this issue Sep 20, 2023 · 2 comments
Labels
bug mypy got something wrong topic-join-v-union Using join vs. using unions

Comments

@rectalogic
Copy link

Bug Report
paramiko keys have base class PKey which has a classmethod from_private_key. When trying to call this on a subclass, mypy errors with:

error: "type" has no attribute "from_private_key"

To Reproduce

import io
from paramiko.dsskey import DSSKey
from paramiko.ecdsakey import ECDSAKey
from paramiko.ed25519key import Ed25519Key
from paramiko.rsakey import RSAKey

for pkey_class in (RSAKey, DSSKey, ECDSAKey, Ed25519Key):
    pkey_class.from_private_key(io.StringIO("hello"))
> python -m venv venv
> venv/bin/pip install mypy==1.5.1 paramiko==3.3.1 types-paramiko==3.3.0.0
> venv/bin/mypy pkey.py
pkey.py:8: error: "type" has no attribute "from_private_key"  [attr-defined]
Found 1 error in 1 file (checked 1 source file)

Actual Behavior

See above. Changing the code to this passes with no error:

import typing as ta
import io
from paramiko.pkey import PKey
from paramiko.dsskey import DSSKey
from paramiko.ecdsakey import ECDSAKey
from paramiko.ed25519key import Ed25519Key
from paramiko.rsakey import RSAKey

key_classes: ta.Sequence[type[PKey]] = (RSAKey, DSSKey, ECDSAKey, Ed25519Key)
for pkey_class in key_classes:
    pkey_class.from_private_key(io.StringIO("hello"))

Your Environment

  • Mypy version used: 1.5.1
  • Mypy command-line flags:
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: 3.10.13
@rectalogic rectalogic added the bug mypy got something wrong label Sep 20, 2023
@JelleZijlstra JelleZijlstra added the topic-join-v-union Using join vs. using unions label Sep 20, 2023
@JelleZijlstra
Copy link
Member

At first sight this looks like another instance of topic-join-v-union Using join vs. using unions , but what's a little odd to me is that these classes have a common base, so shouldn't the join of the types be type[PKey], not type[Any]? It seems that mypy's join infers type for types with a common base that do not have the same constructor. Here's a self-contained example

class A:
    x: int

class B(A):
    def __init__(self, y: str) -> None: ...

class C(A):
    pass

for x in (B, C):
    reveal_type(x)  # Revealed type is "builtins.type"

I can see why that is (otherwise it would be unsafe to instantiate pkey_class), but it was surprising to me.

@hauntsaninja
Copy link
Collaborator

Fixed by #17408

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-join-v-union Using join vs. using unions
Projects
None yet
Development

No branches or pull requests

3 participants