|
1 | | -not_implemented = [(name, method) |
2 | | - for name, (val, methods) in expected_methods.items() |
3 | | - for method in methods |
4 | | - if not hasattr(val, method)] |
5 | | - |
6 | | -for r in not_implemented: |
7 | | - print(r[0], ".", r[1], sep="") |
8 | | -if not not_implemented: |
| 1 | + |
| 2 | +def attr_is_not_inherited(type_, attr): |
| 3 | + """ |
| 4 | + returns True if type_'s attr is not inherited from any of its base classes |
| 5 | + """ |
| 6 | + bases = type_.__mro__[1:] |
| 7 | + |
| 8 | + return getattr(type_, attr) not in (getattr(base, attr, None) for base in bases) |
| 9 | + |
| 10 | + |
| 11 | +not_implementeds = [] |
| 12 | +for name, (typ, methods) in expected_methods.items(): |
| 13 | + for method in methods: |
| 14 | + has_method = hasattr(typ, method) |
| 15 | + is_inherited = has_method and not attr_is_not_inherited(typ, method) |
| 16 | + if has_method and not is_inherited: |
| 17 | + continue |
| 18 | + not_implementeds.append((name, method, is_inherited)) |
| 19 | + |
| 20 | +for r in not_implementeds: |
| 21 | + print(r[0], ".", r[1], " (inherited)" if r[2] else "", sep="") |
| 22 | +if not not_implementeds: |
9 | 23 | print("Not much \\o/") |
10 | 24 |
|
11 | 25 | if platform.python_implementation() == "CPython": |
12 | | - assert len(not_implemented) == 0, "CPython should have all the methods" |
| 26 | + assert len(not_implementeds) == 0, "CPython should have all the methods" |
0 commit comments