Eli Korvigo Eli Korvigo - 1 year ago 68
Python Question

Python: recursive isinstance checking

How can one check a complete type signature of a nested abstract class? In this example

In [4]: from typing import Sequence

In [5]: IntSeq = Sequence[int]

In [6]: isinstance([1], IntSeq)
Out[6]: True

In [7]: isinstance([1.0], IntSeq)
Out[7]: True

I want the last
call to actually return
, while it only checks that the argument is a
. I thought about recursively checking the types, but
has no public attributes that store the nested type(s):

In [8]: dir(IntSeq)

So it doesn't seem to be straightforward to get nested types. I can't find relevant information in the docs.

I need this for a multiple dispatch implementation.


Thanks to the feedback from Alexander Huszagh and Blender we now know that abstract classes in Python 3.5 (might) have two attributes that store the nested types:
. The former is there under both Linux (Ubuntu) and Darwin (OS X), though it is empty in case of Linux. The later is only available under Linux and stores the types like
does under OS X. This implementation details add up to the confusion.

Jim Jim
Answer Source

I see you're trying to implement something using a module that is still provisional; you're bound to encounter a changing interface if you do this.

Blender noticed that the __parameters__ argument holds the parameters to the type; this was true until, I believe 3.5.1. In my git clone of the most recent version of Python (3.6.0a4+) __parameters__ again holds an empty tuple, __args__ holds the argument and __origin__ is the first entry in its __bases__ attribute:

>>> intSeq = typing.Sequence[int]
>>> intSeq.__args__
(<class 'int'>,)
>>> intSeq.__parameters__
>>> intSeq.__origin__

Since 3.6 is when typing will, from what I understand from PEP 411, leave provisional and enter a stable state, this is the version you should be working with to implement your functionality.