[Python] Overloaded method invocation causes type check error

Discussão em 'Python' iniciado por Stack, Janeiro 31, 2025.

  1. Stack

    Stack Membro Participativo

    I posted a question earlier asking how to overload Python methods using generics.

    The solution provided is shown below.

    from __future__ import annotations
    from typing import Literal, overload

    class WoodData: ...
    class ConcreteData: ...

    class Foo[T: Literal["wood", "concrete"]]:
    def __init__(self, data_type: T) -> None:
    self.data_type = data_type

    @overload
    def get_data(self: Foo[Literal["wood"]]) -> WoodData: ...

    @overload
    def get_data(self: Foo[Literal["concrete"]]) -> ConcreteData: ...

    def get_data(self):
    if self.data_type == "wood":
    return WoodData()
    return ConcreteData()

    foo = Foo("concrete")
    x = foo.get_data()


    This example works as expected, but the problem arises when we try to call get_data from a sibling class method.

    For example, I add the bar method below.

    from __future__ import annotations
    from typing import Literal, overload

    class WoodData: ...
    class ConcreteData: ...

    class Foo[T: Literal["wood", "concrete"]]:
    def __init__(self, data_type: T) -> None:
    self.data_type = data_type

    @overload
    def get_data(self: Foo[Literal["wood"]]) -> WoodData: ...

    @overload
    def get_data(self: Foo[Literal["concrete"]]) -> ConcreteData: ...

    def get_data(self):
    if self.data_type == "wood":
    return WoodData()
    return ConcreteData()

    def bar(self):
    self.get_data()


    This gives the typing error:

    Cannot access attribute "get_data" for class "Foo[T@Foo]*"
    Could not bind method "get_data" because "Self@Foo[T@Foo]" is not assignable to parameter "self"
    "Foo[T@Foo]*" is not assignable to "Foo[Literal['wood']]"
    Type parameter "T@Foo" is covariant, but "T@Foo" is not a subtype of "Literal['wood']"
    Type "Literal['wood', 'concrete']" is not assignable to type "Literal['wood']"
    "Literal['concrete']" is not assignable to type "Literal['wood']"
    Could not bind method "get_data" because "Self@Foo[T@Foo]" is not assignable to parameter "self"
    "Foo[T@Foo]*" is not assignable to "Foo[Literal['concrete']]"
    Type parameter "T@Foo" is covariant, but "T@Foo" is not a subtype of "Literal['concrete']"


    How can I access the get_data function from another method without getting a typing error?

    Continue reading...

Compartilhe esta Página