def _get_consumer_conf(consumer): attr = 'ftrace_conf' consumer_cls = get_method_class(consumer) conf = getattr(consumer_cls, attr, FtraceConf()) # This is not strictly speaking forbidden but in the current situation, # there is no legitimate use case where it could happen, and it is very # likely that it comes from a design issue in the class if not conf['events'] and issubclass(consumer_cls, TestBundle): raise ValueError( f"Empty events list in {consumer_cls.__qualname__}.{attr}") return conf
def __new__(metacls, name, bases, dct, **kwargs): new_cls = super().__new__(metacls, name, bases, dct, **kwargs) # Collect all the events that can be used by all methods available on # that class. ftrace_events = set() for name, obj in inspect.getmembers(new_cls, callable): try: used_events = obj.used_events except AttributeError: continue else: ftrace_events.update(used_events.get_all_events()) # Get the ftrace_conf attribute of the class, and make sure it is # unique to that class (i.e. not shared with any other parent or # sibling classes) try: ftrace_conf = new_cls.ftrace_conf except AttributeError: ftrace_conf = FtraceConf(src=new_cls.__qualname__) else: # If the ftrace_conf attribute has been defined in a base class, # make sure that class gets its own copy since we are going to # modify it if 'ftrace_conf' not in dct: ftrace_conf = copy.copy(ftrace_conf) new_cls.ftrace_conf = ftrace_conf # Merge-in a new source to FtraceConf that contains the events we # collected ftrace_conf.add_merged_src( src='{}(required)'.format(new_cls.__qualname__), conf={ 'events': sorted(ftrace_events), }, ) return new_cls