Return an unordered sequence of all classes related to cls. Traverses diamond hierarchies. Fibs slightly: subclasses of builtin types are not returned. Thus class_hierarchy(class A(object)) returns (A, object), not A plus every class systemwide that derives from object.
(cls)
| 924 | |
| 925 | |
| 926 | def class_hierarchy(cls): |
| 927 | """Return an unordered sequence of all classes related to cls. |
| 928 | |
| 929 | Traverses diamond hierarchies. |
| 930 | |
| 931 | Fibs slightly: subclasses of builtin types are not returned. Thus |
| 932 | class_hierarchy(class A(object)) returns (A, object), not A plus every |
| 933 | class systemwide that derives from object. |
| 934 | |
| 935 | """ |
| 936 | |
| 937 | hier = {cls} |
| 938 | process = list(cls.__mro__) |
| 939 | while process: |
| 940 | c = process.pop() |
| 941 | bases = (_ for _ in c.__bases__ if _ not in hier) |
| 942 | |
| 943 | for b in bases: |
| 944 | process.append(b) |
| 945 | hier.add(b) |
| 946 | |
| 947 | if c.__module__ == "builtins" or not hasattr(c, "__subclasses__"): |
| 948 | continue |
| 949 | |
| 950 | for s in [ |
| 951 | _ |
| 952 | for _ in ( |
| 953 | c.__subclasses__() |
| 954 | if not issubclass(c, type) |
| 955 | else c.__subclasses__(c) |
| 956 | ) |
| 957 | if _ not in hier |
| 958 | ]: |
| 959 | process.append(s) |
| 960 | hier.add(s) |
| 961 | return list(hier) |
| 962 | |
| 963 | |
| 964 | def iterate_attributes(cls): |