How to specify types of OrderedDict K, V for annotation like Mypy?

I am using Python 3.5 along with Mypy to have a basic static check for my script. Recently, I have reorganized some methods for returning an OrderedDict, but I encountered a "type" error that is not indexable "when I tried to use the return annotation with the specified types Key and Value.

Reduced example:

#!/usr/bin/env python3.5 from collections import OrderedDict # this works def foo() -> OrderedDict: result = OrderedDict() # type: OrderedDict[str, int] result['foo'] = 123 return result # this doesn't def foo2() -> OrderedDict[str, int]: result = OrderedDict() # type: OrderedDict[str, int] result['foo'] = 123 return result print(foo()) 

And this is the python output at startup:

 Traceback (most recent call last): File "./foo.py", line 12, in <module> def foo2() -> OrderedDict[str, int]: TypeError: 'type' object is not subscriptable 

However, Mypy has no problems with type annotation in the comment and actually warns me if I try to make result[123] = 123 .

What causes this?

+7
python mypy
source share
2 answers

Mypy has no problem (at least not in 0.501). But the problem is with Python 3.6.0. Consider the following:

 from collections import OrderedDict from typing import Dict def foo() -> Dict[str, int]: result: OrderedDict[str, int] = OrderedDict() result['two'] = 2 return result 

This code will satisfy the requirements of mypy (0.501) and Python (3.6.0). However, if you replace Dict with OrderedDict , then mypy will still be happy, but doing it will die with TypeError: 'type' object is not subscriptable .

Interestingly, the Python interpreter dies when viewing the signature of the OrderedDict in the function signature, but gladly accepts it in the annotation of a type variable.

Anyway, my workaround for this is to use Dict instead of OrderedDict in the function signature (and adding a comment that this should be fixed if / when the Python interpreter learns to accept the correct signature).

+5
source share

What you can also try using MutableMapping (as in this answer: fooobar.com/questions/313552 / ... )

 from collections import OrderedDict from typing import Dict def foo() -> MutableMapping[str, int]: result = OrderedDict() # type: MutableMapping[str, int] result['foo'] = 123 return result 
+1
source share

All Articles