Last active
January 5, 2018 17:04
-
-
Save miki725/08546c625876f055d98bc6ef9d194d48 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from __future__ import absolute_import, print_function, unicode_literals | |
import inspect | |
from importlib import import_module | |
import click | |
click.disable_unicode_literals_warning = True | |
def parse_dot(path): | |
module, klass_and_method = path.split(':') | |
klass, method = klass_and_method.split('.') | |
return module, klass, method | |
def parse_pycharm(path): | |
module_and_klass, method = path.split('#') | |
module, klass = module_and_klass.rsplit('.', 1) | |
return module, klass, method | |
parse_mapping = { | |
'dot': parse_dot, | |
'pycharm': parse_pycharm, | |
} | |
def print_method(klass, method): | |
source = inspect.getsource(method) | |
lines = source.splitlines() | |
indent = len(lines[0]) - len(lines[0].lstrip(' \t')) | |
lines = [i[indent:] for i in lines] | |
header = '{}.{}.{}'.format(klass.__module__, klass.__name__, method.__name__) | |
print('-' * len(header)) | |
print(header) | |
print('-' * len(header)) | |
print('\n'.join(lines)) | |
@click.command() | |
@click.argument( | |
'path', | |
metavar='METHOD_PATH', | |
) | |
@click.option( | |
'--pre', | |
metavar='CODE', | |
help=""" | |
Arbitrary python statements to exec before importing module. | |
""" | |
) | |
@click.option( | |
'--django', | |
is_flag=True, | |
default=False, | |
help=""" | |
Initialize django before importing modules. | |
""" | |
) | |
@click.option( | |
'--path-style', | |
default='dot', | |
type=click.Choice(['dot', 'pycharm']), | |
help=""" | |
Style in which path is provided. | |
* dot - standard dot-notation (e.g. "module.path:Class.method") | |
* pycharm - PyCharm notation (e.g. "module.path.Class#method") | |
""" | |
) | |
def mro_method(path, pre, django, path_style): | |
""" | |
Get all method definitions within class method mro | |
Useful to inspect classes with complex mro order. | |
Method path can be provided in normal Python dot notation: | |
"module.path:Class.method". | |
Alternatively PyCharm style "module.path.Class#method" is also supported. | |
""" | |
module, klass, method = parse_mapping[path_style](path) | |
if django: | |
import django | |
django.setup() | |
if pre: | |
exec(pre) | |
module = import_module(module) | |
klass = getattr(module, klass) | |
print('========') | |
print('Full MRO') | |
print('========') | |
for c in klass.mro(): | |
print('{}.{}'.format(c.__module__, c.__name__)) | |
print() | |
for c in klass.mro(): | |
m = c.__dict__.get(method) | |
if not m: | |
continue | |
print_method(c, m) | |
print() | |
if __name__ == '__main__': | |
mro_method() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment