def _check_bases_classes(self, node): """check that the given class node implements abstract methods from base classes """ def is_abstract(method): return method.is_abstract(pass_is_abstract=False) # check if this class abstract if class_is_abstract(node): return methods = sorted( unimplemented_abstract_methods(node, is_abstract).items(), key=lambda item: item[0], ) for name, method in methods: owner = method.parent.frame() if owner is node: continue # owner is not this class, it must be a parent class # check that the ancestor's method is not abstract if name in node.locals: # it is redefined as an attribute or with a descriptor continue self.add_message('abstract-method', node=node, args=(name, owner.name))
def _has_abstract_methods(node): """Determine if the given `node` has abstract methods. The methods should be made abstract by decorating them with `abc` decorators. """ return len(utils.unimplemented_abstract_methods(node)) > 0
def cubicweb_abstractmethods_transform(classdef): if class_is_abstract(classdef): return def is_abstract(method): return method.is_abstract(pass_is_abstract=False) methods = sorted( unimplemented_abstract_methods(classdef, is_abstract).items(), key=lambda item: item[0], ) dummy_method = AstroidBuilder(MANAGER).string_build(''' def dummy_method(self): """""" ''') for name, method in methods: owner = method.parent.frame() if owner is classdef: continue if name not in classdef.locals: if name in ('cell_call', 'entity_call', 'render_body'): classdef.set_local(name, dummy_method)