1
|
|
|
from collections import OrderedDict |
2
|
|
|
from typing import Optional, Any |
3
|
|
|
|
4
|
|
|
|
5
|
|
View Code Duplication |
class ClsDict(OrderedDict): |
|
|
|
|
6
|
|
|
""" |
7
|
|
|
ClsDict is a dict that accepts (only) types as keys and will return its |
8
|
|
|
values depending on instance checks rather than equality checks. |
9
|
|
|
""" |
10
|
|
|
def __new__(cls, *args, **kwargs): |
11
|
|
|
""" |
12
|
|
|
Construct a new instance of ``ClsDict``. |
13
|
|
|
:param args: a dict. |
14
|
|
|
:param kwargs: any kwargs that ``dict`` accepts. |
15
|
|
|
:return: a ``ClsDict``. |
16
|
|
|
""" |
17
|
|
|
from typish.functions._is_type_annotation import is_type_annotation |
18
|
|
|
|
19
|
|
|
if len(args) > 1: |
20
|
|
|
raise TypeError('TypeDict accepts only one positional argument, ' |
21
|
|
|
'which must be a dict.') |
22
|
|
|
if args and not isinstance(args[0], dict): |
23
|
|
|
raise TypeError('TypeDict accepts only a dict as positional ' |
24
|
|
|
'argument.') |
25
|
|
|
if not all([is_type_annotation(key) for key in args[0]]): |
26
|
|
|
raise TypeError('The given dict must only hold types as keys.') |
27
|
|
|
return super().__new__(cls, args[0], **kwargs) |
28
|
|
|
|
29
|
|
|
def __getitem__(self, item: Any) -> Any: |
30
|
|
|
""" |
31
|
|
|
Return the value of the first encounter of a key for which |
32
|
|
|
``is_instance(item, key)`` holds ``True``. |
33
|
|
|
:param item: any item. |
34
|
|
|
:return: the value of which the type corresponds with item. |
35
|
|
|
""" |
36
|
|
|
from typish.functions._get_type import get_type |
37
|
|
|
from typish.functions._subclass_of import subclass_of |
38
|
|
|
|
39
|
|
|
item_type = get_type(item, use_union=True) |
40
|
|
|
for key, value in self.items(): |
41
|
|
|
if subclass_of(item_type, key): |
42
|
|
|
return value |
43
|
|
|
raise KeyError('No match for {}'.format(item)) |
44
|
|
|
|
45
|
|
|
def get(self, item: Any, default: Any = None) -> Optional[Any]: |
46
|
|
|
try: |
47
|
|
|
return self.__getitem__(item) |
48
|
|
|
except KeyError: |
49
|
|
|
return default |
50
|
|
|
|