Home > OS >  Python: overloading the return type for magic methods `__str__` and `__repr__`
Python: overloading the return type for magic methods `__str__` and `__repr__`

Time:03-23

I have a custom enum class that can only return a specific set of string literals when calling __str__ or __repr__. Given that these serialized string literals are sometimes used as input for other functions (and these inputs are well-typed, ie, restricted to the right set of strings), I want the return type of __str__ and __repr__ to be more precise than str.

Consider the following:

from typing import Literal

class A:
    def __repr__(self) -> Literal["world"]:
        result : Literal["world"] = "world"
        return result

test_val : Literal["world"] = repr(A())
print(test_val)

The above SHOULD work, since the type annotations are coherent, yet with mypy, I get:

playground.py:8: error: Incompatible types in assignment (expression has type "str", variable has type "Literal['world']")

for the line where I assign test_val.

I suspect this might be due to some global mechanism on how dunder method types are defined; and __repr__ will ALWAYS return a string. But given that I can choose my return type for __getitem__ just fine, I think something else might be doable.

Is there any way to force the overloading of the return type of __str__/__repr__ so long as co/contra-variance, Liskov, etc, are respected ?

CodePudding user response:

Your method is typed correctly, but you're conflating repr and __repr__. A().__repr__() returns a Literal["world"] but repr, with signature

def repr(x: object) -> str: ...

always returns a str

  • Related