def caller(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]: """ This method will dispatch to the appropriate instance function based on the type of the input we receive. """ out_type = None if self.output_type is not None: out_type = target.get_type(self.output_type) baked = dict() for (_, method) in inspect.getmembers(self, inspect.ismethod): if not hasattr(method, "input_typename_handled"): continue baked[type_canonicalize_name( method.input_typename_handled)] = method if self.isfirst: assert not objs yield from self.no_input() return for i in objs: obj_type_name = type_canonical_name(i.type_) # try subclass-specified input types first, so that they can # override any other behavior if obj_type_name in baked: yield from baked[obj_type_name](i) continue # try passthrough of output type # note, this may also be handled by subclass-specified input types if obj_type_name == type_canonical_name(out_type): yield i continue # try walkers if out_type is not None: try: # pylint: disable=protected-access for obj in Walk()._call([i]): yield drgn.cast(out_type, obj) continue except CommandError: pass # error raise CommandError( self.name, 'no handler for input of type {}'.format(i.type_))
def check_input_type(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]: """ This function acts as a generator, checking that each passed object matches the input type for the command """ assert self.input_type is not None type_name = type_canonicalize_name(self.input_type) for obj in objs: if type_canonical_name(obj.type_) != type_name: raise CommandError( self.name, f'expected input of type {self.input_type}, but received ' f'type {obj.type_}') yield obj
def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]: """ This function will call walk() on each input object, verifying the types as we go. """ assert self.input_type is not None expected_type = type_canonicalize_name(self.input_type) for obj in objs: if type_canonical_name(obj.type_) != expected_type: raise CommandError( self.name, 'expected input of type {}, but received {}'.format( expected_type, type_canonical_name(obj.type_))) yield from self.walk(obj)
def _call( # type: ignore[return] self, objs: Iterable[drgn.Object]) -> Optional[Iterable[drgn.Object]]: """ This function will call pretty_print() on each input object, verifying the types as we go. """ assert self.input_type is not None type_name = type_canonicalize_name(self.input_type) for obj in objs: if type_canonical_name(obj.type_) != type_name: raise CommandError( self.name, f'exepected input of type {self.input_type}, but received ' f'type {obj.type_}') self.pretty_print([obj])
def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]: baked = { type_canonicalize_name(type_): class_ for type_, class_ in Walker.allWalkers.items() } has_input = False for i in objs: has_input = True this_type_name = type_canonical_name(i.type_) if this_type_name not in baked: raise CommandError(self.name, Walk._help_message(i.type_)) yield from baked[this_type_name]().walk(i) # If we got no input and we're the last thing in the pipeline, we're # probably the first thing in the pipeline. Print out the available # walkers. if not has_input and self.islast: print(Walk._help_message())