1- from typing import Any , Hashable , Mapping , Optional , TypeVar , Union , overload
1+ from typing import Any , Hashable , Mapping , Optional , TypeVar , Union , cast , overload
22
33from hamcrest .core .base_matcher import BaseMatcher
44from hamcrest .core .description import Description
@@ -73,20 +73,26 @@ def describe_to(self, description: Description) -> None:
7373
7474# Keyword argument form
7575@overload
76- def has_entries (** keys_valuematchers : Union [Matcher [V ], V ]) -> Matcher [Mapping [str , V ]]: ...
76+ def has_entries (** keys_valuematchers : Matcher [V ]) -> Matcher [Mapping [str , V ]]: ...
77+ @overload
78+ def has_entries (** keys_valuematchers : V ) -> Matcher [Mapping [str , V ]]: ...
7779
7880
7981# Key to matcher dict form
8082@overload
81- def has_entries (keys_valuematchers : Mapping [K , Union [Matcher [V ], V ]]) -> Matcher [Mapping [K , V ]]: ...
83+ def has_entries (keys_valuematchers : Mapping [K , Matcher [V ]], / ) -> Matcher [Mapping [K , V ]]: ...
84+ @overload
85+ def has_entries (keys_valuematchers : Mapping [K , V ], / ) -> Matcher [Mapping [K , V ]]: ...
8286
8387
8488# Alternating key/matcher form
8589@overload
8690def has_entries (* keys_valuematchers : Any ) -> Matcher [Mapping [Any , Any ]]: ...
8791
8892
89- def has_entries (* keys_valuematchers , ** kv_args ):
93+ def has_entries (
94+ * keys_valuematchers : Mapping [K , Union [Matcher [V ], V ]], ** kv_args : Union [Matcher [V ], V ]
95+ ) -> Matcher [Mapping [K , V ]]:
9096 """Matches if dictionary contains entries satisfying a dictionary of keys
9197 and corresponding value matchers.
9298
@@ -132,11 +138,13 @@ def has_entries(*keys_valuematchers, **kv_args):
132138 has_entries('foo', 1, 'bar', 2)
133139
134140 """
141+ base_dict : dict [K , Matcher [V ]] = {}
142+ key : K
143+ value : Union [Matcher [V ], V ]
135144 if len (keys_valuematchers ) == 1 :
136145 try :
137- base_dict = keys_valuematchers [0 ].copy ()
138- for key in base_dict :
139- base_dict [key ] = wrap_matcher (base_dict [key ])
146+ for key , value in keys_valuematchers [0 ].items ():
147+ base_dict [key ] = wrap_matcher (value )
140148 except AttributeError :
141149 raise ValueError (
142150 "single-argument calls to has_entries must pass a dict as the argument"
@@ -146,11 +154,12 @@ def has_entries(*keys_valuematchers, **kv_args):
146154 raise ValueError ("has_entries requires key-value pairs" )
147155 base_dict = {}
148156 for index in range (int (len (keys_valuematchers ) / 2 )):
149- base_dict [ keys_valuematchers [2 * index ]] = wrap_matcher (
150- keys_valuematchers [2 * index + 1 ]
151- )
157+ key = cast ( K , keys_valuematchers [2 * index ])
158+ value = cast ( V , keys_valuematchers [2 * index + 1 ])
159+ base_dict [ key ] = wrap_matcher ( value )
152160
153- for key , value in kv_args .items ():
161+ for key_name , value in kv_args .items ():
162+ key = cast (K , key_name )
154163 base_dict [key ] = wrap_matcher (value )
155164
156165 return IsDictContainingEntries (base_dict )
0 commit comments