Дженерики Python и наследованиеPython

Программы на Python
Ответить
Anonymous
 Дженерики Python и наследование

Сообщение Anonymous »

Я создал этот абстрактный базовый класс:

Код: Выделить всё

import json
from dataclasses import dataclass, InitVar, field

from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes, PublicKeyTypes

from ..signer.signer import Signer

_PubKeyT = TypeVar("_PubKeyT", bound=PublicKeyTypes)
_PrivKeyT = TypeVar("_PrivKeyT", bound=PrivateKeyTypes)

@dataclass(kw_only=True, repr=False)
class Message(Generic[_PubKeyT, _PrivKeyT], ABC):
signer: InitVar[Signer[_PubKeyT, _PrivKeyT]]
signature: bytes | None = field(default=None, repr=False)

@classmethod
def deserialize(cls, data: bytes, signer: Signer[_PubKeyT, _PrivKeyT]) -> Self:
obj = json.loads(data)

payload = base64.b64decode(obj["payload"])
signature = base64.b64decode(obj["signature"])

return cls._from_payload(payload, signature, signer)
Реализация этого класса следующая

Код: Выделить всё

import json
from dataclasses import dataclass
from typing import Generic, Self, TypeVar
import base64

from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes, PublicKeyTypes

_PubKeyT = TypeVar("_PubKeyT", bound=PublicKeyTypes)
_PrivKeyT = TypeVar("_PrivKeyT", bound=PrivateKeyTypes)

@dataclass(repr=False)
class Content(Message[_PubKeyT, _PrivKeyT], Generic[_PubKeyT, _PrivKeyT]):
content: bytes

@property
def payload(self) -> bytes:
obj = {
"content": base64.b64encode(self.content).decode()
}
return json.dumps(obj, separators=(",", ":"), sort_keys=True).encode()

@classmethod
def _from_payload(cls, payload: bytes, signature: bytes, signer: Signer[_PubKeyT, _PrivKeyT]) -> Self:
obj = json.loads(payload)

return cls(
content=base64.b64decode(obj["content"]),
signature=signature,
signer=signer,
)
который я использую, например

Код: Выделить всё

signed_message = Content.deserialize(signed_message_bytes, self.signer)
Это приводит к этому предупреждению pylance:

Код: Выделить всё

Type of "deserialize" is partially unknown
Type of "deserialize" is "(data: bytes, signer: Signer[Unknown, Unknown]) -> Content[Unknown, Unknown]"PylancereportUnknownMemberType
(method) def deserialize(
data: bytes,
signer: Signer[Unknown, Unknown]
) -> Content[Unknown, Unknown]
Однако явная установка типов устраняет предупреждение (все тесты пройдены и т. д.)

Код: Выделить всё

signed_message = Content[_SigPubT, _SigPrivT].deserialize(signed_message_bytes, self.signer)
Поэтому pylance не может определить типы подписывающих лиц. Это что-то не так в моем коде или ограничение pylance? Есть идеи, как заставить pylance, если это вообще возможно, выводить типы?


Подробнее здесь: https://stackoverflow.com/questions/798 ... nheritance
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»