3030 class _MyGenericAlias : # unused, but must be a class to support isinstance() check.
3131 pass
3232
33+ from .misc import safeissubclass
34+
3335__all__ = ["isoftype" ]
3436
3537def isoftype (value , T ):
@@ -207,19 +209,19 @@ def get_args(tp):
207209 typing .SupportsAbs ,
208210 typing .SupportsRound ):
209211 if U is T :
210- return issubclass (type (value ), U )
212+ return safeissubclass (type (value ), U )
211213
212214 # We don't have a match yet, so T might still be one of those meta-utilities
213215 # that hate `issubclass` with a passion.
214216 try :
215- if issubclass (T , typing .Text ): # https://docs.python.org/3/library/typing.html#typing.Text
217+ if safeissubclass (T , typing .Text ): # https://docs.python.org/3/library/typing.html#typing.Text
216218 return isinstance (value , str ) # alias for str
217219
218220 # Subclass test for Python 3.6 only. Python 3.7+ have typing._GenericAlias for the generics.
219- if issubclass (T , typing .Tuple ) or get_origin (T ) is tuple :
221+ if safeissubclass (T , typing .Tuple ) or get_origin (T ) is tuple :
220222 if not isinstance (value , tuple ):
221223 return False
222- # bare `typing.Tuple`, no restrictions on length or element type.
224+ # blare `typing.Tuple`, no restrictions on length or element type.
223225 if T .__args__ is None :
224226 return True
225227 # homogeneous element type, arbitrary length
@@ -249,12 +251,12 @@ def ismapping(statictype, runtimetype):
249251 for statictype , runtimetype in ((typing .Dict , dict ),
250252 (typing .MutableMapping , collections .abc .MutableMapping ),
251253 (typing .Mapping , collections .abc .Mapping )):
252- if issubclass (T , statictype ) or get_origin (T ) is runtimetype :
254+ if safeissubclass (T , statictype ) or get_origin (T ) is runtimetype :
253255 return ismapping (statictype , runtimetype )
254256
255257 # ItemsView is a special-case mapping in that we must not call
256258 # `.items()` on `value`.
257- if issubclass (T , typing .ItemsView ) or get_origin (T ) is collections .abc .ItemsView :
259+ if safeissubclass (T , typing .ItemsView ) or get_origin (T ) is collections .abc .ItemsView :
258260 if not isinstance (value , collections .abc .ItemsView ):
259261 return False
260262 if T .__args__ is None :
@@ -274,7 +276,7 @@ def ismapping(statictype, runtimetype):
274276 def iscollection (statictype , runtimetype ):
275277 if not isinstance (value , runtimetype ):
276278 return False
277- if issubclass (statictype , typing .ByteString ) or get_origin (statictype ) is collections .abc .ByteString :
279+ if safeissubclass (statictype , typing .ByteString ) or get_origin (statictype ) is collections .abc .ByteString :
278280 # WTF? A ByteString is a Sequence[int], but only statically.
279281 # At run time, the `__args__` are actually empty - it looks
280282 # like a bare Sequence, which is invalid. HACK the special case.
@@ -305,10 +307,10 @@ def iscollection(statictype, runtimetype):
305307 (typing .MutableSequence , collections .abc .MutableSequence ),
306308 (typing .MappingView , collections .abc .MappingView ),
307309 (typing .Sequence , collections .abc .Sequence )):
308- if issubclass (T , statictype ) or get_origin (T ) is runtimetype :
310+ if safeissubclass (T , statictype ) or get_origin (T ) is runtimetype :
309311 return iscollection (statictype , runtimetype )
310312
311- if issubclass (T , typing .Callable ) or get_origin (T ) is collections .abc .Callable :
313+ if safeissubclass (T , typing .Callable ) or get_origin (T ) is collections .abc .Callable :
312314 if not callable (value ):
313315 return False
314316 return True
0 commit comments