Python
python3

Pythonの基本的な型の階層構造を図にしてみた

GeneratorがSequenceでないことに少し疑問に思ったこともあり
Pythonの基本的な型の階層構造をGraphvizを使って図にしてみました。

type_hierarchy.png

生成に使ったコードは以下

type_check.py
from typing import *
from typing import IO, BinaryIO, TextIO
import collections
import datetime
import enum
import numbers
import decimal
import fractions
from itertools import groupby
from more_itertools import first
from graphviz import Digraph

G = Digraph(format='png')
types = [
    TypeVar,
    # Generic,
    Type, Iterable, Iterator, Reversible, SupportsInt, SupportsFloat, SupportsComplex, SupportsBytes, SupportsAbs,
    SupportsRound, Container, Hashable, Sized, Collection, AbstractSet, MutableSet, Mapping, MutableMapping, Sequence,
    MutableSequence, ByteString, Deque, List, Set, FrozenSet, MappingView, KeysView, ItemsView, ValuesView, Awaitable,
    Coroutine, AsyncIterable, AsyncIterator, ContextManager, Dict, DefaultDict, Counter, ChainMap, Generator,
    AsyncGenerator, Text, IO, TextIO, BinaryIO,
    # Pattern,
    # Match,
    NamedTuple,
    # Any,
    # Union,
    # Optional,
    Tuple, Callable,
    # ClassVar,
    # AnyStr
    collections.OrderedDict,
    int, float, complex, range, bytes, bytearray, memoryview,
    datetime.date, datetime.time, datetime.datetime, datetime.timedelta, datetime.tzinfo, datetime.timezone,
    enum.Enum, enum.IntEnum, enum.IntFlag, enum.Flag,
    numbers.Complex, numbers.Real, numbers.Rational, numbers.Integral,
    decimal.Decimal, decimal.Context,
    fractions.Fraction
]

subtype_pairs = [(t1, t2) for t1 in types for t2 in types if t1 is not t2 if issubclass(t1, t2)]
for t1, t2_list in groupby(subtype_pairs, first):
    t2_list = list(t2_list)
    for _, t2 in t2_list:
        if not any([issubclass(x, t2) for _, x in t2_list if x is not t2]):
            G.edge(t1.__name__, t2.__name__)

G.render('type_hierarchy')

ちなみに、Anaconda/Windows環境だからなのか、動作させるためにはPythonのgraphvizパッケージだけでなく、python-graphvizパッケージも必要でした。