Goal: extract methods/functions defined in module. This excludes:
- Imports
- Lambda methods
- Magic methods
- Builtin methods
- Class methods
- Classes
- Non-original definitions (i.e. function assignments,
alt_name = orig_fn)
My approach + test below. Any room for improvement, or false positives/negatives? (In particular I wonder if we can get away without typechecks, e.g. isinstance(method, types.LambdaType))
Code: live demo
import utils
def get_module_methods(module):
def is_module_function(obj):
return ('<function' in str(obj) and
module.__name__ in getattr(obj, '__module__', ''))
def not_lambda(obj):
return not ('<lambda>' in getattr(obj, '__qualname__', ''))
def not_magic(obj):
s = getattr(obj, '__name__', '').split('__')
return (len(s) < 2) or not (s[0] == s[-1] == '')
def not_duplicate(name, obj):
return name == getattr(obj, '__name__', '')
def cond(name, obj):
return (is_module_function(obj) and not_lambda(obj) and
not_magic(obj) and not_duplicate(name, obj))
objects = {name: getattr(module, name) for name in dir(module)}
m_methods = {}
for name, obj in objects.items():
if cond(name, obj):
m_methods[name] = obj
return m_methods
mm = get_module_methods(utils)
_ = [print(k, '--', v) for k, v in mm.items()]
Test:
# utils.py
import random
import numpy as np
from inspect import getsource
def fn1(a, b=5):
print("wrong animal", a, b)
class Dog():
meow = fn1
def __init__(self):
pass
def bark(self):
print("WOOF")
d = Dog()
barker = d.bark
mewoer = d.meow
A = 5
arr = np.random.randn(100, 100)
def __getattr__(name):
return getattr(random, name, None)
magic = __getattr__
duplicate = fn1
_builtin = str
lambd = lambda: 1
# main.py
import utils
# def get_module_methods(): ...
mm = get_module_methods(utils)
_ = [print(k, '--', v) for k, v in mm.items()]
fn1 -- <function fn1 at 0x7f00a7eb2820>
Edit: additional test case for a lambda surrogate:
import functools
def not_lambda():
return 1
functools.wraps(lambda i: i)(not_lambda).__name__
Code in question and answer catch not_lambda as a lambda - false positive.