[Python] How can I define a protocol for a class that contains a protocol field and use a...

Discussão em 'Python' iniciado por Stack, Maio 7, 2025.

  1. Stack

    Stack Membro Participativo

    I want to do this:

    import typing
    import dataclasses

    class ConfigProtocol(typing.Protocol):
    a: str

    @dataclasses.dataclass
    class Config:
    a: str

    class HasConfigProtocol(typing.Protocol):
    config: ConfigProtocol


    @dataclasses.dataclass
    class HasConfig:
    config: Config

    def accepts_hasconfig(h: HasConfigProtocol):
    pass

    accepts_hasconfig(HasConfig(config=Config(a="")))


    But in pylance it reports:

    Argument of type "Position" cannot be assigned to parameter "template_position" of type "PositionProtocol" in function "__init__"
    "Position" is incompatible with protocol "PositionProtocol"
    "config" is invariant because it is mutable
    "config" is an incompatible type
    "Configuration" is incompatible with protocol "ConfigurationProtocol"


    To get this to work do I need to freeze my dataclasses and provide read only access in my protocols like so?

    class ConfigProtocol(typing.Protocol):
    @property
    def a(self) -> str:
    ...

    @dataclasses.dataclass(frozen=True)
    class Config:
    a: str

    class HasConfigProtocol(typing.Protocol):
    @property
    def config(self) -> ConfigProtocol:
    ...


    @dataclasses.dataclass(frozen=True)
    class HasConfig:
    config: Config

    def accepts_hasconfig(h: HasConfigProtocol):
    pass

    accepts_hasconfig(HasConfig(config=Config(a="")))


    Long term this is the code in one module, module_a which is stand alone. There is another module_b which also exists, has similar code and is stand alone. I want to use instances of HasConfig from module_a in module_b. Because the modules do not know about eachother, I am including the same protocol definition in each of them.

    To reuse protocols across modules and have instances work for both of them, the protocol definitions must be the same, and the Protocol definitions only must use @property definitions.

    Continue reading...

Compartilhe esta Página