Skip to content

Instantly share code, notes, and snippets.

@eliasdorneles
Last active November 29, 2016 18:13
Show Gist options
  • Save eliasdorneles/146eb4726738c8ec63e8e8084749ab43 to your computer and use it in GitHub Desktop.
Save eliasdorneles/146eb4726738c8ec63e8e8084749ab43 to your computer and use it in GitHub Desktop.
# How one could go about implementing a check for abstract Python classes
# written in the old style (raise NotImplementedError),
# by looking at the methods bytecode
def is_oldstyle_abstract(cls):
def has_raise_notimplemented_code(func_code):
# this is too magic, I know.
# you can see how it works by disassembling the bytes below:
#
# >>> import dis
# >>> dis.dis(raise_varargs_bytecode)
# 0 RAISE_VARARGS 1
# 3 LOAD_CONST 0 (0)
# 6 RETURN_VALUE
raise_varargs_bytecode = b'\x82\x01\x00d\x00\x00S'
return (func_code.co_names == ('NotImplementedError',)
and func_code.co_code.endswith(raise_varargs_bytecode))
import inspect
if not inspect.isclass(cls):
return False
methods = [it for _, it in inspect.getmembers(cls)
if inspect.isfunction(it) or inspect.ismethod(it)]
return any(has_raise_notimplemented_code(m.__code__) for m in methods)
class SomeAbstractClass:
some_class_attr = 1
def __init__(self):
self.some_instance_attr = 2
def somemethod1(self):
raise NotImplementedError("Needs filling it in")
def somemethod2(self, a, b):
return a + b
class AnotherAbstractClass:
def abs_method(self):
raise NotImplementedError
class NonAbstractClass(SomeAbstractClass):
some_class_attr = 1
def __init__(self):
self.some_instance_attr = 2
def somemethod1(self):
return self.some_instance_attr + self.some_class_attr
def somemethod2(self, a, b):
return a + b
class AnotherNonAbstractClass(object):
def method(self):
return ValueError("oopes")
if __name__ == '__main__':
print(is_oldstyle_abstract(SomeAbstractClass))
print(is_oldstyle_abstract(AnotherAbstractClass))
print(is_oldstyle_abstract(NonAbstractClass) == False)
print(is_oldstyle_abstract(AnotherNonAbstractClass) == False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment