def function(self, func_name, func, modifier=None): ret = self.result_type() signature = get_signature(func, 'hintingstub') if signature is not None: with self.fmt.function(func_name, signature, modifier) as key: ret[key] = signature return ret
def seterror_argument(args, func_name): update_mapping() func = eval(func_name, namespace) sigs = get_signature(func, "typeerror") if type(sigs) != list: sigs = [sigs] if type(args) != tuple: args = (args, ) # temp! found = matched_type(args, sigs) if found: msg = dedent(""" '{func_name}' called with wrong argument values: {func_name}{args} Found signature: {func_name}{found} """.format(**locals())).strip() return ValueError, msg type_str = ", ".join(type(arg).__name__ for arg in args) msg = dedent(""" '{func_name}' called with wrong argument types: {func_name}({type_str}) Supported signatures: """.format(**locals())).strip() for sig in sigs: msg += "\n {func_name}{sig}".format(**locals()) # We don't raise the error here, to avoid the loader in the traceback. return TypeError, msg
def function(self, func_name, func): ret = self.result_type() signature = get_signature(func, 'existence') sig = stringify(signature) if signature is not None else None if sig is not None and func_name not in ("next", "__next__", "__div__"): with self.fmt.function(func_name, sig) as key: ret[key] = sig return ret
def seterror_argument(args, func_name, info): func = None try: func = eval(func_name, namespace) except Exception as e: msg = "Internal error evaluating {func_name}: {e}".format(**locals()) return TypeError, msg if info and type(info) is str: err = TypeError if info == "<": msg = "{func_name}(): not enough arguments".format(**locals()) elif info == ">": msg = "{func_name}(): too many arguments".format(**locals()) elif info.isalnum(): msg = "{func_name}(): got multiple values for keyword argument '{info}'".format(**locals()) else: msg = "{func_name}(): {info}".format(**locals()) err = AttributeError return err, msg if info and type(info) is dict: keyword = tuple(info)[0] msg = "{func_name}(): unsupported keyword '{keyword}'".format(**locals()) return AttributeError, msg sigs = get_signature(func, "typeerror") if not sigs: msg = "{func_name}({args}) is wrong (missing signature)".format(**locals()) return TypeError, msg if type(sigs) != list: sigs = [sigs] if type(args) != tuple: args = (args,) # temp! found = matched_type(args, sigs) if found: msg = dedent(""" '{func_name}' called with wrong argument values: {func_name}{args} Found signature: {func_name}{found} """.format(**locals())).strip() return ValueError, msg type_str = ", ".join(type(arg).__name__ for arg in args) msg = dedent(""" '{func_name}' called with wrong argument types: {func_name}({type_str}) Supported signatures: """.format(**locals())).strip() for sig in sigs: msg += "\n {func_name}{sig}".format(**locals()) # We don't raise the error here, to avoid the loader in the traceback. return TypeError, msg
def make_helptext(func): existing_doc = func.__doc__ sigs = get_signature(func) if not sigs: return existing_doc if type(sigs) != list: sigs = [sigs] try: func_name = func.__name__ except AttributeError: func_name = func.__func__.__name__ sigtext = "\n".join(func_name + str(sig) for sig in sigs) msg = sigtext + "\n\n" + existing_doc if check_string_type(existing_doc) else sigtext return msg
def klass(self, class_name, klass): modname = klass.__module__ if not (modname.startswith("PySide2") or modname.startswith("shiboken2")): # don't look into any foreign classes! ret = self.result_type() return ret bases_list = [] for base in klass.__bases__: name = base.__name__ if name in ("object", "type"): pass else: modname = base.__module__ name = modname + "." + base.__name__ bases_list.append(name) class_str = "{}({})".format(class_name, ", ".join(bases_list)) with self.fmt.klass(class_name, class_str): ret = self.result_type() # class_members = inspect.getmembers(klass) # gives us also the inherited things. class_members = sorted(list(klass.__dict__.items())) subclasses = [] functions = [] for thing_name, thing in class_members: if inspect.isclass(thing): subclass_name = ".".join((class_name, thing_name)) subclasses.append((subclass_name, thing)) elif inspect.isroutine(thing): func_name = thing_name.split(".")[0] # remove ".overload" functions.append((func_name, thing)) self.fmt.level += 1 for subclass_name, subclass in subclasses: ret.update(self.klass(subclass_name, subclass)) if isinstance(subclass, EnumType): self.enum(subclass) ret = self.function("__init__", klass) for func_name, func in functions: func_kind = get_signature(func, "__func_kind__") modifier = func_kind if func_kind in ( "staticmethod", "classmethod") else None ret.update(self.function(func_name, func, modifier)) self.fmt.level -= 1 return ret
def klass(self, class_name, klass): ret = self.result_type() if "<" in class_name: # This is happening in QtQuick for some reason: ## class QSharedPointer<QQuickItemGrabResult >: # We simply skip over this class. return ret bases_list = [] for base in klass.__bases__: name = base.__name__ if name not in ("object", "type"): name = base.__module__ + "." + name bases_list.append(name) class_str = "{}({})".format(class_name, ", ".join(bases_list)) # class_members = inspect.getmembers(klass) # gives us also the inherited things. class_members = sorted(list(klass.__dict__.items())) subclasses = [] functions = [] enums = [] for thing_name, thing in class_members: if inspect.isclass(thing): subclass_name = ".".join((class_name, thing_name)) subclasses.append((subclass_name, thing)) elif inspect.isroutine(thing): func_name = thing_name.split(".")[0] # remove ".overload" signature = getattr(thing, "__signature__", None) if signature is not None: functions.append((func_name, thing)) elif type(type(thing)) is EnumType: enums.append((thing_name, thing)) init_signature = getattr(klass, "__signature__", None) enums.sort(key=lambda tup: tup[1]) # sort by enum value self.fmt.have_body = bool(subclasses or functions or enums or init_signature) with self.fmt.klass(class_name, class_str): self.fmt.level += 1 self.fmt.class_name = class_name if hasattr(self.fmt, "enum"): # this is an optional feature for enum_name, value in enums: with self.fmt.enum(class_name, enum_name, int(value)): pass for subclass_name, subclass in subclasses: if klass == subclass: # this is a side effect of the typing module for Python 2.7 # via the "._gorg" property, which we can safely ignore. print( "Warning: {class_name} points to itself via {subclass_name}, skipped!" .format(**locals())) continue ret.update(self.klass(subclass_name, subclass)) self.fmt.class_name = class_name ret.update(self.function("__init__", klass)) for func_name, func in functions: func_kind = get_signature(func, "__func_kind__") modifier = func_kind if func_kind in ("staticmethod", "classmethod") else None ret.update(self.function(func_name, func, modifier)) self.fmt.level -= 1 return ret