Search code examples
pythontypingmypy

python typing: Is it possible to specify the type of a variable later than at its creation?


I know that it is possible to specify variable type when they are passed as function arguments (the : Header below) or when they are created (with # type: instruction).

But is it possible to specify, in the middle of the code (typically inside an if block), what is the expected type of a variable?

For example in the following function, I would like to specify that my variables are of a specific subclass of Header to avoid PyCharm warning "Unresolved attribute reference 'unit' for class 'Header'":

def change_header(old_header: Header, new_header: Header)
    if old_header.is_measure:
        # I would like to specify here that both old_header and 
        # new_header are of the subclass MeasureHeader and therefore have              
        # a 'unit' property
        if new_header.unit != old_header.unit:
            raise Exception("flag 'all' can't change the unit"

Thanks.


Solution

  • PyCharm will recognise isinstance checks:

    def change_header(old_header: Header, new_header: Header)
        if isinstance(old_header, MeasureHeader) and \
                isinstance(new_header, MeasureHeader):
            ...
    

    You could also intersperse such an isinstance with an assert. Other possibilities are listed in the PyCharm help.

    Lastly you could honour your own type hints more closely and actually stick to only the types you declare in your function signature, which in this case might mean to widen the type hint:

    from typing import Union
    
    def change_header(old_header: Union[Header, MeasureHeader], ...):