class SignatureLayout(SimpleNamespace): """ Configure a signature. The layout of signatures can have different layouts which are controlled by keyword arguments: definition=True Determines if self will generated. defaults=True ellipsis=False Replaces defaults by "...". return_annotation=True parameter_names=True False removes names before ":". """ allowed_keys = SimpleNamespace(definition=True, defaults=True, ellipsis=False, return_annotation=True, parameter_names=True) allowed_values = True, False def __init__(self, **kwds): args = SimpleNamespace(**self.allowed_keys.__dict__) args.__dict__.update(kwds) self.__dict__.update(args.__dict__) err_keys = list(set(self.__dict__) - set(self.allowed_keys.__dict__)) if err_keys: self._attributeerror(err_keys) err_values = list( set(self.__dict__.values()) - set(self.allowed_values)) if err_values: self._valueerror(err_values) def __setattr__(self, key, value): if key not in self.allowed_keys.__dict__: self._attributeerror([key]) if value not in self.allowed_values: self._valueerror([value]) self.__dict__[key] = value def _attributeerror(self, err_keys): err_keys = ", ".join(err_keys) allowed_keys = ", ".join(self.allowed_keys.__dict__.keys()) raise AttributeError( dedent("""\ Not allowed: '{err_keys}'. The only allowed keywords are '{allowed_keys}'. """.format(**locals()))) def _valueerror(self, err_values): err_values = ", ".join(map(str, err_values)) allowed_values = ", ".join(map(str, self.allowed_values)) raise ValueError( dedent("""\ Not allowed: '{err_values}'. The only allowed values are '{allowed_values}'. """.format(**locals())))
def __init__(self, **kwds): args = SimpleNamespace(**self.allowed_keys.__dict__) args.__dict__.update(kwds) self.__dict__.update(args.__dict__) err_keys = list(set(self.__dict__) - set(self.allowed_keys.__dict__)) if err_keys: self._attributeerror(err_keys) err_values = list(set(self.__dict__.values()) - set(self.allowed_values)) if err_values: self._valueerror(err_values)
def _parse_line(line): line_re = r""" ((?P<multi> ([0-9]+)) : )? # the optional multi-index (?P<funcname> \w+(\.\w+)*) # the function name \( (?P<arglist> .*?) \) # the argument list ( -> (?P<returntype> .*) )? # the optional return type $ """ ret = SimpleNamespace(**re.match(line_re, line, re.VERBOSE).groupdict()) # PYSIDE-1095: Handle arbitrary default expressions argstr = ret.arglist.replace("->", ".deref.") arglist = _parse_arglist(argstr) args = [] for idx, arg in enumerate(arglist): tokens = arg.split(":") if len(tokens) < 2: if idx == 0 and tokens[0] == "self": tokens = 2 * tokens # "self: self" else: warnings.warn('Invalid argument "{}" in "{}".'.format( arg, line)) continue name, ann = tokens if name in keyword.kwlist: if LIST_KEYWORDS: print("KEYWORD", ret) name = name + "_" if "=" in ann: ann, default = ann.split("=", 1) tup = name, ann, default else: tup = name, ann args.append(tup) ret.arglist = args multi = ret.multi if multi is not None: ret.multi = int(multi) funcname = ret.funcname parts = funcname.split(".") if parts[-1] in keyword.kwlist: ret.funcname = funcname + "_" return vars(ret)