Working with typing module of python, I am using NewType to create distinct types did following.
UserId = NewType('UserId',int)
As per documentation https://docs.python.org/3/library/typing.html if I use new data type UserId for any operation the output will be of original Type i.e. int. However doing this:
total = UserId(0.3) + UserId(100)
type(total) # the output is float. Why is this changing to float should it be int?
Even it allows to pass any other data type to UserId.
some_id = UserId('adfd')
Further some_id datatype is set as str.
I was trying to rely on this for type checking and error out if data type doesn't match to original. Confused hence wanted to get opinion, is something wrong here?
Per the documentation on NewType
:
Note that these checks are enforced only by the static type checker. At runtime, the statement
Derived = NewType('Derived', Base)
will makeDerived
a function that immediately returns whatever parameter you pass it. That means the expressionDerived(some_value)
does not create a new class or introduce any overhead beyond that of a regular function call.
So at runtime any NewType
function is essentially just lambda x: x
; it will not perform any isinstance
checks. The purpose of using NewType
is purely for type annotation. If you put your code in an IDE, or run it through type checkers such as mypy, a warning will be shown if you use it on an invalid type.
If you need runtime type-checks, you could do so with a simply function like this:
def UserId(x):
if isinstance(x, int):
return x
raise TypeError(f"{x} is not an int")
Also, check out pydantic if you need type-checking and validation for more complex structures.