Skip to content

Instantly share code, notes, and snippets.

@onionka
Created July 24, 2017 15:59
Show Gist options
  • Save onionka/bdd555c4616546b3571c5e94b36eead8 to your computer and use it in GitHub Desktop.
Save onionka/bdd555c4616546b3571c5e94b36eead8 to your computer and use it in GitHub Desktop.
Implementation of instance function overloading achieved with annotations and inspect
import inspect
class Overloadable(object):
def __init__(self, fn):
self.base = fn
self.overloads = (fn, inspect.signature(fn).parameters),
self.instance = None
def overload(self, fn):
self.overloads += (fn, inspect.signature(fn).parameters),
return self
def __call__(self, *args, **kwargs):
_args = tuple((None, a) for a in args)
for fn, o in self.overloads:
try:
overloaded_params = tuple(o.items())
params = _args + tuple(kwargs.items())
assert len(params) == len(overloaded_params) - 1
for (sn, st), (rn, rt) in zip(overloaded_params[1:], params):
assert isinstance(rt, st.annotation)
return fn(self.parent_object, *args, **kwargs)
except AssertionError as ex:
pass
raise NotImplemented("this kind of overload is not implemented")
def __get__(self, instance, owner):
self.parent_object = instance
return self
def overloadable(fn):
return Overloadable(fn)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment