Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use attribute from Optional[Union[str, int]] parameter depending on its type

I have a parameter of type: a: Optional[Union[str, int]].

I want to use some attributes when it is a string and other ones when it's an integer. Eg:

    if type(a) is int:
        self.a = a
    elif type(a) is str and a.endswith('some prefix'):
        self.b = a

However, MyPy complains with the following:

error: Item "int" of "Union[str, int, None]" has no attribute "endswith"

error: Item "None" of "Union[str, int, None]" has no attribute "endswith"

Is there a way to make this work with MyPy?

like image 433
FlyingPumba Avatar asked May 19 '26 01:05

FlyingPumba


1 Answers

The idiom you should be using is isinstance(a, int) instead of type(a) is int. If you do the former and write:

if isinstance(a, int):
    self.a = a
elif isinstance(a, str) and a.endswith('some_prefix'):
    self.b = a

...then your code should type-check cleanly.

The reason why doing type(a) is int isn't supported/most likely won't be supported any time soon is because what you're basically asserting there is that 'a' is exactly an int and no other type.

But we actually don't have a clean way of writing such a type in PEP 484 -- if you say some variable 'foo' is of type 'Bar', what you're really saying is that 'foo' could be of type 'Bar' or any subclass of 'Bar'.

like image 64
Michael0x2a Avatar answered May 20 '26 14:05

Michael0x2a



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!