The following code:
class Foo(int):
def __new__(cls, x, *args, **kwargs):
x = x if isinstance(x, int) else 42
return super(Foo, cls).__new__(cls, x, *args, **kwargs)
Results in a warning (in PyCharm): "Expected type 'str | bytes | bytearray', got 'int' instead
" on x
in the last line.
Why is this?
If I evaluate super(Size, cls).__new__ == int.__new__
, the result is True
. Wouldn't that expect an int
as well?
Is there a better way to create a subclass of int
, if I want to add behaviour when a value is first assigned or some value is cast to this type?
A concrete example of such a class would be a class Size(int)
that could be instantiated as Size(1024)
or Size('1 KiB')
, with the same result.
The overload of int
with multiple args takes a string as the first param. It is roughly equivalent to
int(x:int = 0) -> int:
int(x:str, base: int = 10) -> int:
You are providing __new__(cls, x, *args, **kwargs)
, so it is expecting that there should be a string as the first param.
So for this to not complain, drop the extra args:
class Foo(int):
def __new__(cls, x):
x = x if isinstance(x, int) else 42
return super(Foo, cls).__new__(cls, x)
print(Foo(2))
print(Foo("2"))
2
42