Skip to content

Instantly share code, notes, and snippets.

@eirenik0
Last active November 1, 2017 18:53
Show Gist options
  • Save eirenik0/cc3935825b7c541d1e698bde35368737 to your computer and use it in GitHub Desktop.
Save eirenik0/cc3935825b7c541d1e698bde35368737 to your computer and use it in GitHub Desktop.
Show method hierarchy source codes for selected class method
"""
Allows to looking through method hierarchy source codes for selected class method
Usage:
sources = get_method_hierarchy_sources(CompanyProfileSettingsForm, 'save')
# shows all instances code
show_method_hierarchy(sources)
# shows shorter and prettier version
show_method_hierarchy(combine_by_similar_methods_sources(sources))
"""
from inspect import getsource
def get_method_hierarchy_sources(cls, method_name):
sources = []
for klass in cls.__mro__:
method = getattr(klass, method_name, None)
if method:
sources.append((klass.__name__, getsource(method)))
return sources
def combine_by_similar_methods_sources(sources):
tmp = {}
for cls_name, method_source in sources:
if method_source not in tmp:
tmp[method_source] = [cls_name]
else:
tmp[method_source].extend([cls_name])
return [(cls_names, method_source) for method_source, cls_names in tmp.items()]
def show_method_hierarchy(sources):
for cls_name, method_source in sources:
# if was combined
if isinstance(cls_name, list):
cls_name = ['{} => '.format(name) for name in cls_name]
cls_name = ''.join(cls_name).rstrip(' =>')
print "{name}:\n {method}\n".format(name=cls_name, method=method_source)
@eirenik0
Copy link
Author

eirenik0 commented Nov 1, 2017

In [94]: sources = get_method_hierarchy_sources(CompanyProfileSettingsForm, 'save')

In [95]: show_method_hierarchy(combine_by_similar_methods_sources(sources))
CompanyProfileForm <= CustodyAccountsMixin:
     def save(self, commit=True):
        profile = super(CustodyAccountsMixin, self).save(commit)
        if self.campaign and self.campaign.required_custody_account:
            CustodyAccountDetails(account_number=self.cleaned_data['account_number'],
                                  account_bank=self.cleaned_data['account_bank']).save()
        return profile


AddressForm <= ModelForm <= BaseModelForm:
     def save(self, commit=True):
        """
        Saves this ``form``'s cleaned_data into model instance
        ``self.instance``.

        If commit=True, then the changes to ``instance`` will be saved to the
        database. Returns ``instance``.
        """
        if self.instance.pk is None:
            fail_message = 'created'
        else:
            fail_message = 'changed'
        return save_instance(self, self.instance, self._meta.fields,
                             fail_message, commit, self._meta.exclude,
                             construct=False)




Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment