123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- #!/usr/bin/env python3
- """Comparator is a tool for checking that classes are
- identical by calculating hashes of their methods' source code
- """
- import inspect
- from binascii import crc32
- from module import Example, Example2, Example3, InheritCustomInit, OverrideCustomInit
- def get_methods(cls):
- """Print source code of the given class."""
- print('Inspecting class', cls)
- methods = []
- # TODO: sort alphabetically
- for member in inspect.getmembers(cls):
- # Skip builtins
- # TODO: print if not default (__init__, __new__, ..., ???)
- if member[0].startswith('__'):
- # TODO: make list of default methods
- if member[0] in ['__init__', '__new__', '__eq__']:
- init_func = member[1]
- # FIXME: make it simpler
- if cls.__qualname__ == init_func.__qualname__.split('.')[0]:
- print('__init__ is overriden!')
- print(inspect.getsource(member[1]))
- continue
- if not callable(member[1]):
- print('Skipping attribute', member[0])
- continue
- print(member[0])
- methods.append(member)
- return methods
- def get_hashes(methods):
- """Calculate hash of method's source code."""
- hashes = []
- for method in methods:
- hashes[method[0]] = crc32(inspect.getsource(method[1]).encode())
- return hashes
- if __name__ == "__main__":
- # TODO: pass arg: static or dynamic (instance or class)?
- methods = [get_methods(x) for x in [Example]]
- for class_methods in methods:
- for method in class_methods:
- print(inspect.getsource(method[1]))
|