In-line type hints for briefer use in `if`, `while` and `for` (perhaps some others)

Type hints currently are supported in python during function definitions and variable assignment. I propose a method for type assignment during other operations, such as if, while and for.

from pathlib import Path
path = Path('tmp')
if path.exists()! bool:
   print('true')

This could be used for all kinds of situations, including the below where is list is used in a for, and we want to ensure the has a certain type it’s iterating over:

list_here = [1,2,3]
for i! int in list_here:
    print(i)

…or perhaps for a while case, that must always refer to a list:

# here let's assume get_list comes from an external library
def get_list(i):
   return list(range(i))

i = 5
while get_list(i)! list[int]:
     i = i -1

Perhaps for a more advanced if case

# here let's assume get_list comes from an external library
def get_list():
   r = random.uniform(1)
   if r <=0.5:
       return list(['test2', 'test3'])
   else:
       return []

if get_list()! list[str]:
  print('here')

I should also add the delimiter of ! I’ve chosen here is just the best one I could determine right now - the same concept could work with a different delimiter.

Strong -1 from me. The pathlib case should already be handled by typeshed, and the second can already be handled by a type declaration:

list_here = [1,'2',3]
i: int
for i in list_here:
    print(i)

For this, mypy gives the error

ttyp.py:3: error: Incompatible types in assignment (expression has type "object", variable has type "int")  [assignment]
Found 1 error in 1 file (checked 1 source file)

For your other examples, you’re assuming untyped functions with your “let’s assume X comes from an external library”. This isn’t a reasonable assumption - you can add type hints for external functions using stub files. This is an explicitly documented and intended use case for stubs.

Overall, type checkers seem to already have this well covered. And in addition, the proposed syntax is intrusive and ugly (IMO) so I’d very strongly object to seeing it in any projects I control.

9 Likes

Doesn’t assert_type() already statically provide what the proposed “!” syntax should bring?

(cannot test as I’m currently on mobile device without mypy)

3 Likes

Wow this is cool! Haven’t seen this function before - you’re right it does provide the same utility. I suppose the only point remaining is brevity - the ! syntax I describe is quite a bit shorter than using this typing function, and also would come as a built-in - so no need for the import at the top. That said, with a short choice of import name it can be quite brief:

from typing import assert_type as at
# here let's assume get_list comes from an external library
def get_list():
   r = random.uniform(1)
   if r <=0.5:
       return list(['test2', 'test3'])
   else:
       return []

if at(get_list(), list[str]):
  print('here')

In some way I suppose python progressed from the Union syntax, to using | - similarly perhaps there is some way assert_type could have a syntax upgrade