__main__.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #!/usr/bin/env python3
  2. """Comparator is a tool for checking that classes are
  3. identical by calculating hashes of their methods' source code
  4. """
  5. import inspect
  6. from binascii import crc32
  7. from module import Example, Example2, Example3, InheritCustomInit, OverrideCustomInit
  8. def get_methods(cls):
  9. """Print source code of the given class."""
  10. print('Inspecting class', cls)
  11. methods = []
  12. # TODO: sort alphabetically
  13. for member in inspect.getmembers(cls):
  14. # Skip builtins
  15. # TODO: print if not default (__init__, __new__, ..., ???)
  16. if member[0].startswith('__'):
  17. # TODO: make list of default methods
  18. if member[0] in ['__init__', '__new__', '__eq__']:
  19. init_func = member[1]
  20. # FIXME: make it simpler
  21. if cls.__qualname__ == init_func.__qualname__.split('.')[0]:
  22. print('__init__ is overriden!')
  23. print(inspect.getsource(member[1]))
  24. continue
  25. if not callable(member[1]):
  26. print('Skipping attribute', member[0])
  27. continue
  28. print(member[0])
  29. methods.append(member)
  30. return methods
  31. def get_hashes(methods):
  32. """Calculate hash of method's source code."""
  33. hashes = []
  34. for method in methods:
  35. hashes[method[0]] = crc32(inspect.getsource(method[1]).encode())
  36. return hashes
  37. if __name__ == "__main__":
  38. # TODO: pass arg: static or dynamic (instance or class)?
  39. methods = [get_methods(x) for x in [Example]]
  40. for class_methods in methods:
  41. for method in class_methods:
  42. print(inspect.getsource(method[1]))