pythoncastingpython-typing

Cast variable to right type automatically in Python


Is there a way in Python to implement type-casting that automatically chooses the right type?

Say you have a class:

class Foo:
    foo: list[int]

    def __init__(self):
        self.foo = cast(list[int], api.get())

You know that api.get() always returns list[int] but it's a weird library with haphazard type hints, so it claims that it's (say) FunkyContainerType when it's not. Also you can't be bothered to create a correct stub file for the library today because deadlines.

self.foo = cast(list[int], api.get()) creates a lot visual noise in the code, which is also redundant if the type of self.foo is already defined. Moreover, if the variable has a custom type, you have to import the type at runtime for the program not to crash, so you can't put it in a stub file and you'll run into issues with circular imports more often.

I'd much rather use self.foo = cast(api.get()) that finds out what type self.foo is and casts the result of the API call to that type.

So the key desiderata are (1) don't state the type redundantly, (2) change nothing about the runtime behavior, i.e. no type imports at runtime, and (3) minimal visual clutter.

Notes: (1) This question is about exactly what it says it is. It is not about copying or converting values at runtime. It is about type hints. (2) The use of cast is to supply extra information to the type-checker that you know but that the type-checker cannot infer.


Solution

  • # type: ignore or better (for Pyright) # pyright: ignore [reportAssignmentType] do the trick.

    The assignment doesn't change or extend the type of the attribute. (H/t juanpa.arrivillaga.)

    What also works is:

    self.foo = cast(Any, api.get())

    It does not change the type of self.foo to list[int] | Any as I would've expected but has my desired result (of not changing the type). But I like it less now because it's less obvious to me and adds more clutter in my opinion.