Search code examples
pythontypingnewtype

In python3.9 type module NewType function allows creating derived with new data type


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')

There is no error restricting to original type .i.e. int.

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?


Solution

  • 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 make Derived a function that immediately returns whatever parameter you pass it. That means the expression Derived(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.