def _inspect_func(self): """Inspect the function to get useful informations from it. Sets instance attributes (desc, type_conv, name_conv) based on the informations. """ signature = inspect.signature(self.handler) doc = inspect.getdoc(self.handler) if doc is not None: self.desc = doc.splitlines()[0].strip() else: self.desc = "" if not self.ignore_args: for param in signature.parameters.values(): annotation_info = self._parse_annotation(param) if param.name == 'self': continue if self._inspect_special_param(param, annotation_info): continue typ = self._get_type(param, annotation_info) kwargs = self._param_to_argparse_kwargs(param, annotation_info) args = self._param_to_argparse_args(param, annotation_info) self._type_conv.update(self._get_typeconv(param, typ)) self._name_conv.update( self._get_nameconv(param, annotation_info)) callsig = debug.format_call( self.parser.add_argument, args, kwargs, full=False) log.commands.vdebug('Adding arg {} of type {} -> {}'.format( param.name, typ, callsig)) self.parser.add_argument(*args, **kwargs)
def run(self, win_id, args=None, count=None): """Run the command. Note we don't catch CommandError here as it might happen async. Args: win_id: The window ID the command is run in. args: Arguments to the command. count: Command repetition count. """ dbgout = ["command called:", self.name] if args: dbgout.append(str(args)) if count is not None: dbgout.append("(count={})".format(count)) log.commands.debug(' '.join(dbgout)) try: self.namespace = self.parser.parse_args(args) except argparser.ArgumentParserError as e: message.error(win_id, '{}: {}'.format(self.name, e)) return except argparser.ArgumentParserExit as e: log.commands.debug("argparser exited with status {}: {}".format( e.status, e)) return self._count = count posargs, kwargs = self._get_call_args(win_id) self._check_prerequisites(win_id) log.commands.debug('Calling {}'.format( debug.format_call(self.handler, posargs, kwargs))) self.handler(*posargs, **kwargs)
def _inspect_func(self): """Inspect the function to get useful informations from it. Sets instance attributes (desc, type_conv, name_conv) based on the informations. Return: How many user-visible arguments the command has. """ signature = inspect.signature(self.handler) doc = inspect.getdoc(self.handler) if doc is not None: self.desc = doc.splitlines()[0].strip() else: self.desc = "" if not self.ignore_args: for param in signature.parameters.values(): if param.name == 'self': continue if self._inspect_special_param(param): continue typ = self._get_type(param) is_bool = typ is bool kwargs = self._param_to_argparse_kwargs(param, is_bool) args = self._param_to_argparse_args(param, is_bool) callsig = debug_utils.format_call( self.parser.add_argument, args, kwargs, full=False) log.commands.vdebug('Adding arg {} of type {} -> {}'.format( param.name, typ, callsig)) self.parser.add_argument(*args, **kwargs) return signature.parameters.values()
def run(self, win_id, args=None, count=None): """Run the command. Note we don't catch CommandError here as it might happen async. Args: win_id: The window ID the command is run in. args: Arguments to the command. count: Command repetition count. """ dbgout = ["command called:", self.name] if args: dbgout.append(str(args)) elif args is None: args = [] if count is not None: dbgout.append("(count={})".format(count)) log.commands.debug(' '.join(dbgout)) try: self.namespace = self.parser.parse_args(args) except argparser.ArgumentParserError as e: message.error('{}: {}'.format(self.name, e), stack=traceback.format_exc()) return except argparser.ArgumentParserExit as e: log.commands.debug("argparser exited with status {}: {}".format( e.status, e)) return self._count = count self._check_prerequisites(win_id) posargs, kwargs = self._get_call_args(win_id) log.commands.debug('Calling {}'.format( debug_utils.format_call(self.handler, posargs, kwargs))) self.handler(*posargs, **kwargs)
def _inspect_func(self): """Inspect the function to get useful information from it. Sets instance attributes (desc, type_conv, name_conv) based on the information. Return: How many user-visible arguments the command has. """ signature = inspect.signature(self.handler) doc = inspect.getdoc(self.handler) if doc is not None: self.desc = doc.splitlines()[0].strip() else: self.desc = "" for param in signature.parameters.values(): # https://docs.python.org/3/library/inspect.html#inspect.Parameter.kind # "Python has no explicit syntax for defining positional-only # parameters, but many built-in and extension module functions # (especially those that accept only one or two parameters) accept # them." if param.kind == inspect.Parameter.POSITIONAL_ONLY: raise AssertionError if param.name == 'self': continue if self._inspect_special_param(param): continue if (param.kind == inspect.Parameter.KEYWORD_ONLY and param.default is inspect.Parameter.empty): raise TypeError("{}: handler has keyword only argument {!r} " "without default!".format( self.name, param.name)) typ = self._get_type(param) is_bool = typ is bool kwargs = self._param_to_argparse_kwargs(param, is_bool) args = self._param_to_argparse_args(param, is_bool) callsig = debug_utils.format_call(self.parser.add_argument, args, kwargs, full=False) log.commands.vdebug( # type: ignore 'Adding arg {} of type {} -> {}'.format( param.name, typ, callsig)) self.parser.add_argument(*args, **kwargs) if param.kind == inspect.Parameter.VAR_POSITIONAL: self._has_vararg = True return signature.parameters.values()
def _inspect_func(self): """Inspect the function to get useful informations from it. Sets instance attributes (desc, type_conv, name_conv) based on the informations. Return: How many user-visible arguments the command has. """ signature = inspect.signature(self.handler) doc = inspect.getdoc(self.handler) if doc is not None: self.desc = doc.splitlines()[0].strip() else: self.desc = "" if not self.ignore_args: for param in signature.parameters.values(): # https://docs.python.org/3/library/inspect.html#inspect.Parameter.kind # "Python has no explicit syntax for defining positional-only # parameters, but many built-in and extension module functions # (especially those that accept only one or two parameters) # accept them." assert param.kind != inspect.Parameter.POSITIONAL_ONLY if param.name == 'self': continue arg_info = self.get_arg_info(param) if arg_info.count: self._zero_count = arg_info.zero_count if self._inspect_special_param(param): continue if (param.kind == inspect.Parameter.KEYWORD_ONLY and param.default is inspect.Parameter.empty): raise TypeError("{}: handler has keyword only argument " "{!r} without default!".format(self.name, param.name)) typ = self._get_type(param) is_bool = typ is bool kwargs = self._param_to_argparse_kwargs(param, is_bool) args = self._param_to_argparse_args(param, is_bool) callsig = debug_utils.format_call( self.parser.add_argument, args, kwargs, full=False) log.commands.vdebug('Adding arg {} of type {} -> {}'.format( param.name, typ, callsig)) self.parser.add_argument(*args, **kwargs) return signature.parameters.values()
def _inspect_func(self): """Inspect the function to get useful informations from it. Sets instance attributes (desc, type_conv, name_conv) based on the informations. Return: How many user-visible arguments the command has. """ signature = inspect.signature(self.handler) doc = inspect.getdoc(self.handler) arg_count = 0 if doc is not None: self.desc = doc.splitlines()[0].strip() else: self.desc = "" if (self.count_arg is not None and self.count_arg not in signature.parameters): raise ValueError("count parameter {} does not exist!".format( self.count_arg)) if (self.win_id_arg is not None and self.win_id_arg not in signature.parameters): raise ValueError("win_id parameter {} does not exist!".format( self.win_id_arg)) if not self.ignore_args: for param in signature.parameters.values(): annotation_info = self._parse_annotation(param) if param.name == 'self': continue if self._inspect_special_param(param): continue arg_count += 1 typ = self._get_type(param, annotation_info) kwargs = self._param_to_argparse_kwargs(param, annotation_info) args = self._param_to_argparse_args(param, annotation_info) self._type_conv.update(self._get_typeconv(param, typ)) callsig = debug_utils.format_call(self.parser.add_argument, args, kwargs, full=False) log.commands.vdebug('Adding arg {} of type {} -> {}'.format( param.name, typ, callsig)) self.parser.add_argument(*args, **kwargs) return arg_count
def _inspect_func(self): """Inspect the function to get useful informations from it. Sets instance attributes (desc, type_conv, name_conv) based on the informations. Return: How many user-visible arguments the command has. """ signature = inspect.signature(self.handler) doc = inspect.getdoc(self.handler) arg_count = 0 if doc is not None: self.desc = doc.splitlines()[0].strip() else: self.desc = "" if (self.count_arg is not None and self.count_arg not in signature.parameters): raise ValueError("count parameter {} does not exist!".format( self.count_arg)) if (self.win_id_arg is not None and self.win_id_arg not in signature.parameters): raise ValueError("win_id parameter {} does not exist!".format( self.win_id_arg)) if not self.ignore_args: for param in signature.parameters.values(): annotation_info = self._parse_annotation(param) if param.name == 'self': continue if self._inspect_special_param(param): continue arg_count += 1 typ = self._get_type(param, annotation_info) kwargs = self._param_to_argparse_kwargs(param, annotation_info) args = self._param_to_argparse_args(param, annotation_info) self._type_conv.update(self._get_typeconv(param, typ)) callsig = debug_utils.format_call( self.parser.add_argument, args, kwargs, full=False) log.commands.vdebug('Adding arg {} of type {} -> {}'.format( param.name, typ, callsig)) self.parser.add_argument(*args, **kwargs) return arg_count
def _inspect_func(self): """Inspect the function to get useful informations from it. Sets instance attributes (desc, type_conv, name_conv) based on the informations. Return: How many user-visible arguments the command has. """ signature = inspect.signature(self.handler) doc = inspect.getdoc(self.handler) if doc is not None: self.desc = doc.splitlines()[0].strip() else: self.desc = "" if not self.ignore_args: for param in signature.parameters.values(): # https://docs.python.org/3/library/inspect.html#inspect.Parameter.kind # "Python has no explicit syntax for defining positional-only # parameters, but many built-in and extension module functions # (especially those that accept only one or two parameters) # accept them." assert param.kind != inspect.Parameter.POSITIONAL_ONLY if param.name == 'self': continue if self._inspect_special_param(param): continue typ = self._get_type(param) is_bool = typ is bool kwargs = self._param_to_argparse_kwargs(param, is_bool) args = self._param_to_argparse_args(param, is_bool) callsig = debug_utils.format_call(self.parser.add_argument, args, kwargs, full=False) log.commands.vdebug('Adding arg {} of type {} -> {}'.format( param.name, typ, callsig)) self.parser.add_argument(*args, **kwargs) return signature.parameters.values()
def _inspect_func(self): """Inspect the function to get useful informations from it. Return: A (has_count, desc, parser, type_conv) tuple. has_count: Whether the command supports a count. desc: The description of the command. type_conv: A mapping of args to type converter callables. name_conv: A mapping of names to convert. """ type_conv = {} name_conv = {} signature = inspect.signature(self.handler) has_count = 'count' in signature.parameters doc = inspect.getdoc(self.handler) if doc is not None: desc = doc.splitlines()[0].strip() else: desc = "" if not self.ignore_args: for param in signature.parameters.values(): if param.name in ('self', 'count'): continue annotation_info = self._parse_annotation(param) typ = self._get_type(param, annotation_info) args, kwargs = self._param_to_argparse_args( param, annotation_info) type_conv.update(self._get_typeconv(param, typ)) name_conv.update(self._get_nameconv(param, annotation_info)) callsig = debug.format_call( self.parser.add_argument, args, kwargs, full=False) log.commands.vdebug('Adding arg {} of type {} -> {}'.format( param.name, typ, callsig)) self.parser.add_argument(*args, **kwargs) return has_count, desc, type_conv, name_conv
def test_format_call(func, args, kwargs, full, expected): assert debug.format_call(func, args, kwargs, full) == expected