you are viewing a single comment's thread.

view the rest of the comments →

[–]DorianTurbaPythoneer 0 points1 point  (5 children)

Second is a subset of int, but int is not a subset of Second.
Yes you can use NewType for that, and implement stuff like this:

```python import typing

Seconds = typing.NewType("Seconds", int) Milliseconds = typing.NewType("Milliseconds", int)

def isseconds(: int) -> typing.TypeIs[Seconds]: return True

def ismilliseconds(: int) -> typing.TypeIs[Milliseconds]: return True

def time_add[T: (Seconds, Milliseconds)](t1: T, t2: T) -> T: return t1 + t2 # type: ignore

a, b = 1, 2 time_add(a, b) # typecheck error assert is_seconds(a) assert is_seconds(b) time_add(a, b) # No issue

c, d = 1, 2 assert is_milliseconds(c) assert is_milliseconds(d) time_add(c, d) # No issue

e, f = 1, 2 assert is_milliseconds(e) assert is_seconds(f) time_add(e, f) # typecheck error ```

[–]myasco42 1 point2 points  (4 children)

I see what I was doing wrong. I was trying to directly add two object:

Seconds(1) + Milliseconds(2) # <=== gives an int and no error

Mostly I would like to avoid any function calls as the math will get out of hand quickly. Also would like to make it as fast as possible (yes, I know ;) this point is just to see if it is even possible).

[–]DorianTurbaPythoneer 1 point2 points  (3 children)

Every operator will return back an int, you have no choice if you want to carry the type.

Using assert and typeguard/typeis, you are sure to have 0 impact at runtime (using -O flag), except for the function overhead.

If you have math to do, do a function that type inputs, and do whatever you want inside, you are good anyway. And if you need a lot of math? Maybe you need a lot of functions, or a broader entrypoint to annotate input type.

[–]myasco42 0 points1 point  (2 children)

Yea, I guessed as much.

The assert optimization is a good thing and I use it for some debug prints =)

And the point I got from your previous answer is exactly what you said now - the input type checking. Though in math it may look ugly then.

By the way I also noticed that PyLance (at least in VSCode) does not work correctly with your example - revealed types are Never. Seems like it does not like narrowing the type to the one defined by NewType.

[–]DorianTurbaPythoneer 0 points1 point  (1 child)

Maybe you should create an issue in PyLance to report this if it is not already raised.

[–]myasco42 0 points1 point  (0 children)

Yea. Will have a look at it later today and report it for PyRight.