@@ -182,12 +182,16 @@ def get_origin(tp):
182182 # Optional normalizes to Union[argtype, NoneType].
183183 # Python 3.6 has the repr, 3.7+ use typing._GenericAlias.
184184 if repr (T .__class__ ) == "typing.Union" or get_origin (T ) is typing .Union :
185- if T .__args__ is None : # bare `typing.Union`; empty, has no types in it, so no value can match.
185+ if T .__args__ is None : # Python 3.6 bare `typing.Union`; empty, has no types in it, so no value can match.
186186 return False
187187 if not any (isoftype (value , U ) for U in T .__args__ ):
188188 return False
189189 return True
190190
191+ # Python 3.7+ bare typing.Union; empty, has no types in it, so no value can match.
192+ if T is typing .Union : # isinstance(T, typing._SpecialForm) and T._name == "Union":
193+ return False
194+
191195 # TODO: in Python 3.7+, what is the mysterious callable that doesn't have `__qualname__`?
192196 if callable (T ) and hasattr (T , "__qualname__" ) and T .__qualname__ == "NewType.<locals>.new_type" :
193197 # This is the best we can do, because the static types created by `typing.NewType`
@@ -253,12 +257,14 @@ def get_origin(tp):
253257 def ismapping (statictype , runtimetype ):
254258 if not isinstance (value , runtimetype ):
255259 return False
256- if T .__args__ is None :
257- raise TypeError ("Missing mandatory key, value type arguments of `{}`" .format (statictype ))
258- assert len (T .__args__ ) == 2
260+ if T .__args__ is None : # Python 3.6: consistent behavior with 3.7+, which use unconstrained TypeVar KT, VT.
261+ args = (typing .TypeVar ("KT" ), typing .TypeVar ("VT" ))
262+ else :
263+ args = T .__args__
264+ assert len (args ) == 2
259265 if not value : # An empty dict has no key and value types.
260266 return False
261- K , V = T . __args__
267+ K , V = args
262268 return all (isoftype (k , K ) and isoftype (v , V ) for k , v in value .items ())
263269 for statictype , runtimetype in ((typing .Dict , dict ),
264270 (typing .MutableMapping , collections .abc .MutableMapping ),
@@ -271,12 +277,14 @@ def ismapping(statictype, runtimetype):
271277 if safeissubclass (T , typing .ItemsView ) or get_origin (T ) is collections .abc .ItemsView :
272278 if not isinstance (value , collections .abc .ItemsView ):
273279 return False
274- if T .__args__ is None :
275- raise TypeError ("Missing mandatory key, value type arguments of `{}`" .format (statictype ))
276- assert len (T .__args__ ) == 2
280+ if T .__args__ is None : # Python 3.6: consistent behavior with 3.7+, which use unconstrained TypeVar KT, VT.
281+ args = (typing .TypeVar ("KT" ), typing .TypeVar ("VT" ))
282+ else :
283+ args = T .__args__
284+ assert len (args ) == 2
277285 if not value : # An empty dict has no key and value types.
278286 return False
279- K , V = T . __args__
287+ K , V = args
280288 return all (isoftype (k , K ) and isoftype (v , V ) for k , v in value )
281289
282290 # Check iterable types that allow non-destructive iteration.
0 commit comments