Optional Static Typing using mypy

I ran into this issue while attempting to get previously-written, type-hinted code running client-side. I wanted to still be able to use and type-hint my code in non-Anvil projects.

I’d be interested in learning if there’s a better way to address this than the approach I took (and please tell me if the approach I took was a terrible idea).

I converted imports like

from typing import Dict, List, Optional

to instead read:

try:
    from typing import Dict, List, Optional
except ImportError:
    from .faketyping import Dict, List, Optional  # type: ignore

and I then created a faketyping module with blank class definitions, e.g.:

class Dict:
    pass
class List:
    pass   
...

Doing that at least got rid of exceptions for code like:

def foo(bar: List[str]) -> Optional[str]:
  ...do stuff...

I did still encounter problems for type hints such as Optional[str] , when used in statements (i.e., not in function definitions). For example,

baz: Optional[int]=2

would still raise an exception. So, in those cases, I did need to switch over to comment-style type hinting as recommended on the Skulpt fourm. So the above would become:

baz=2 # type: Optional[int]

Nevertheless, since most of my type hints were in functions, I was able to avoid a lot of rewriting (I find the comment-style type hints less readable, especially for functions).

Of course, I’d very much like to hear from anyone more knowledge than myself about whether the tack I took was reasonable, or if I’m courting disaster (or somehow incurring performance penalties).

Plus, if my kludgey approach wasn’t an absolutely terrible idea, I was also considering implementing an even kludgier one, in order to make baz: Optional[int]=2 pass muster!

Namely, in faketyping, instead of writing:

class Dict:
    pass

I was instead thinking of writing:

class OptionalFakeClass:
   def __getitem__(self, x):
       pass
   def __setitem__(self, x, y):
       pass
   def __delitem__(self, x):
       pass 

Optional=OptionalFakeClass()   

Is this crazy? Is there a better way to prevent Anvil from complaining about client-side type-hints that are permissible with CPython and typing? The above does seem to work okay, per my limited testing. And since the hack’s ugliness wold be fairly well-contained, I’d find it worthwhile, since it’d mean other areas of my code would be cleaner and type-hinted. But that’s only if I I’m not somehow risking catastrophe.

Any thoughts very are very much appreciated!

-Dan

1 Like