@@ -40,46 +40,116 @@ def get_annotation_types(annotation):
4040 return [annotation , ]
4141
4242
43- def product_annotations (annotations ):
44- """ Get all variants of annotations."""
43+ def product_annotatios (annotations ):
44+ ''' Get all variants of annotations.'''
4545 types , vals = annotations
46+ list_of_sig = convert_to_sig_list (types )
47+ result_product = []
48+ #unique_typevars = get_internal_typevars(list_of_sig)
49+
50+ for sig in list_of_sig :
51+ result_product .extend (get_internal_typevars (sig ))
52+
53+ return result_product
54+
55+
56+ def convert_to_sig_list (types ):
57+ '''Expands all Unions'''
4658 types_product = list (product (* types .values ()))
47- typevars_unique = {}
48- count = 1
49- for name , typs in types .items ():
50- for typ in typs :
51- if not isinstance (typ , TypeVar ) or not typ .__constraints__ :
52- continue
53-
54- if typ not in typevars_unique :
55- typevars_unique [typ ] = typ .__constraints__
56- count *= len (typ .__constraints__ )
57-
58- prod = list (product (* typevars_unique .values ()))
59- temp_res = []
60-
61- for typs in types_product :
62- temp = []
63- temp_dict = {}
64- num = 0
65- for attr in types :
66- temp_dict [attr ] = typs [num ]
67- num += 1
68- temp .append (temp_dict )
69- temp .append (vals )
70- temp_res .append (temp )
59+ names = [name for name in types .keys ()]
60+ result = []
61+
62+ for sig in types_product :
63+ sig_result = {}
64+ for i in range (len (sig )):
65+ sig_result [names [i ]] = sig [i ]
66+ result .append (sig_result )
67+
68+ return result
69+
70+
71+ def get_internal_typevars (sig ):
72+ '''Get unique typevars in signature'''
73+ unique_typevars = set ()
74+ for typ in sig .values ():
75+ unique_typevars .update (get_typevars (typ ))
76+
77+ if len (unique_typevars ) == 0 :
78+ return sig
79+
80+ return expand_typevars (sig , unique_typevars )
7181
82+
83+ def get_typevars (type ):
84+ '''Get unique typevars in type (container)'''
85+ if isinstance (type , TypeVar ) and type .__constraints__ :
86+ return {type , }
87+ elif isinstance (type , _GenericAlias ):
88+ result = set ()
89+ for arg in type .__args__ :
90+ result .update (get_typevars (arg ))
91+ return result
92+
93+ return set ()
94+
95+
96+ def expand_typevars (sig , unique_typevars ):
97+ '''Exstend all Typevars in signature'''
98+ result = [sig ]
99+
100+ for typevar in unique_typevars :
101+ temp_result = []
102+ for temp_sig in result :
103+ temp_result .extend (update_sig (temp_sig , typevar ))
104+ result = temp_result
105+
106+ return result
107+
108+
109+ def update_sig (temp_sig , typevar ):
110+ '''Expand one typevar'''
72111 result = []
73- for examp in temp_res :
74- for i in range (count ):
75- result .append (deepcopy (examp ))
76-
77- name_of_typevars = list (typevars_unique .keys ())
78- for k in range (len (result )):
79- pos = k % count
80- for x in result [k ][0 ]:
81- for i in range (len (prod [pos ])):
82- if result [k ][0 ][x ] == name_of_typevars [i ]:
83- result [k ][0 ][x ] = prod [pos ][i ]
112+ for constr_type in typevar .__constraints__ :
113+ sig = {}
114+ for name , typ in temp_sig .items ():
115+ if True in exsist_typevar (typ , typevar ):
116+ sig [name ] = replace_typevar (typ , typevar , constr_type )
117+ else :
118+ sig [name ] = typ
119+
120+ result .append (sig )
84121
85122 return result
123+
124+
125+ def exsist_typevar (typ , typevar ):
126+ '''Сheck if there is a typevar in type (container)'''
127+ if typ == typevar :
128+ return {True , }
129+ elif isinstance (typ , _GenericAlias ):
130+ result = set ()
131+ for arg in typ .__args__ :
132+ result .update (exsist_typevar (arg , typevar ))
133+ return result
134+
135+ return {False , }
136+
137+
138+ def replace_typevar (typ , typevar , final_typ ):
139+ '''Replace typevar with type in container
140+ For example:
141+ # typ = Dict[T, V]
142+ # typevar = T(int, str)
143+ # final_typ = int
144+ '''
145+
146+ if typ == typevar :
147+ return (final_typ )
148+ elif isinstance (typ , _GenericAlias ):
149+ result = list ()
150+ for arg in typ .__args__ :
151+ result .append (replace_typevar (arg , typevar , final_typ ))
152+ result_type = typ .copy_with (tuple (result ))
153+ return (result_type )
154+
155+ return (typ )
0 commit comments