Skip to content

Instantly share code, notes, and snippets.

@pkit
Created October 29, 2024 17:51
Show Gist options
  • Save pkit/d64b4256214967eba6908cef344b3476 to your computer and use it in GitHub Desktop.
Save pkit/d64b4256214967eba6908cef344b3476 to your computer and use it in GitHub Desktop.
Analyze and print method resolution for each method in a class
from some_package import SomeClass
def analyze_method_resolution(cls: Type, include_magic_methods: bool = False) -> None:
"""
Analyzes and prints the method resolution for all methods in a class
without executing them.
Args:
cls: The class to analyze
include_magic_methods: Whether to include magic methods (defaults to False)
"""
def get_all_methods(class_obj: Type) -> Set[str]:
methods = set()
for name, value in inspect.getmembers(class_obj, inspect.isfunction):
if not include_magic_methods and name.startswith('__'):
continue
methods.add(name)
return methods
all_methods = set()
for base in cls.__mro__:
all_methods.update(get_all_methods(base))
print(f"\nClass Hierarchy Analysis for: {cls.__name__}")
print("=" * 50)
print(f"Method Resolution Order (MRO):")
for i, base in enumerate(cls.__mro__):
print(f" {i}. {base.__name__}")
print("\nMethod Resolution Analysis:")
print("=" * 50)
for method_name in sorted(all_methods):
defining_classes = []
for base in cls.__mro__:
if method_name in base.__dict__:
defining_classes.append(base.__name__)
if defining_classes:
for base in cls.__mro__:
if method_name in base.__dict__:
print(f"\nMethod: {base.__name__}.{method_name}")
break
else:
print(f"\nMethod: <dynamic>.{method_name}")
resolution_path = []
for base in cls.__mro__:
if method_name in base.__dict__:
resolution_path.append(base.__name__)
if resolution_path:
print(f"└── Resolution path: {' -> '.join(resolution_path)}")
if __name__ == "__main__":
analyze_method_resolution(SomeClass)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment