def _handle_function(doc): name = doc[NAME] doc = Docs(doc[DOC], 1) return_annotation = ' -> %s' % doc.rtype if doc.rtype else '' docstring = doc.get_doc_string() if docstring: docstring = '\n' + docstring end = '' else: end = '\n ...' res = 'def %s(%s) %s:%s%s' % (name, doc.get_argument_string(), return_annotation, docstring, end) return res
def _handle_function(fun: FunctionInfo): function = Docs(fun.doc, 1) return_annotation = " -> %s" % _get_function_rtype(fun.name, function.rtype) docstring = function.get_doc_string() if docstring: docstring = "\n" + docstring + "\n" end = "" else: end = " ..." arg_strings = list(function.get_argument_strings()) if len(arg_strings) == 1: yield "def %s(%s)%s:%s%s" % (fun.name, arg_strings[0], return_annotation, docstring, end) else: for arg_string in arg_strings: yield "@overload\ndef %s(%s)%s: ..." % (fun.name, arg_string, return_annotation) yield "def %s(*args)%s:%s%s" % (fun.name, return_annotation, docstring, end)
def _handle_class(info: ClassInfo): assert not info.doc, "Got docs need to handle it" parents = [x for x in info.parents if x != "object"] result = [] if parents: result.append("class %s(%s):" % (info.name, ", ".join(info.parents))) else: result.append("class %s:" % info.name) properties = [] instance_methods = [] for attr_name, attr in sorted(info.attributes.items()): if attr["type"] == "<class 'property'>": rtype = attr.get("rtype", "") if not rtype: rtype = _get_property_return_type_by_name(attr_name) else: rtype = _update_property_return_type(attr_name, rtype) properties.append((attr_name, rtype)) elif attr["type"] in ("<class 'Boost.Python.function'>", "<class 'function'>"): instance_methods.append(attr["routine"]) else: warning("Skipping '%s' (%s): %s" % ((info.name), attr["type"], attr)) for property_name, rtype in properties: if not rtype: return_annotation = "" else: return_annotation = " -> %s" % rtype if property_name == "class": result.append(" # cant define it via python in that way") result.append(" # @property") result.append(" # def %s(self)%s: ..." % (property_name, return_annotation)) else: result.append(" @property") result.append(" def %s(self)%s: ..." % (property_name, return_annotation)) result.append("") for routine_name, routine_docs in instance_methods: docs = Docs(routine_docs, 2, is_class=True) # TODO: Subclass map-like classes from dict (or custom class) rather than this hack rtype = _update_method_return_type(info.name, routine_name, docs.rtype) doc_string = docs.get_doc_string() if doc_string: doc_string = "\n" + doc_string end = "" else: end = " ..." return_annotation = " -> %s" % rtype if rtype else "" arg_strings = list(docs.get_argument_strings()) if len(arg_strings) == 1: result.append( " def %s(%s)%s:%s%s" % (routine_name, next(docs.get_argument_strings()), return_annotation, doc_string, end) ) else: for arg_string in arg_strings: result.append(" @overload\n def %s(%s)%s:%s" % (routine_name, arg_string, return_annotation, end)) result.append(" def %s(*args)%s:%s%s" % (routine_name, return_annotation, doc_string, end)) result.append("") if not (properties or instance_methods): result.append(" ...") if not result[-1]: result.pop() yield "\n".join(result)
def _handle_class(info): name = info[NAME] docs = info[DOC] attrs = info[ATTRS] assert not docs, "Got docs need to handle it" parents = info[PARENTS] if not parents: parents = ['object'] # instance is boost wrapper result = [] if 'object' in parents: parents.remove('object') if parents: result.append('class %s(%s):' % (name, ', '.join(parents))) else: result.append('class %s:' % name) properties = [] instance_methods = [] for attr_name, attr in sorted(attrs.items()): if attr['type'] == "<class 'property'>": properties.append((attr_name, attr.get('rtype', ''))) elif attr['type'] in ("<class 'Boost.Python.function'>", "<class 'function'>"): instance_methods.append(attr['routine']) else: warning("Skipping '%s' (%s): %s" % (name, attr['type'], attr)) for property_name, rtype in properties: if not rtype: return_annotation = '' elif rtype.startswith("<type"): return_annotation = '-> %s' % rtype[7:-2] else: return_annotation = '-> %s' % rtype.split('.')[-1].strip("'>") if property_name == 'class': result.append(' # cant define it via python in that way') result.append(' # @property') result.append(' # def %s(self)%s: ' % (property_name, return_annotation)) result.append(' # ...') else: result.append(' @property') result.append(' def %s(self)%s:' % (property_name, return_annotation)) result.append(' ...') result.append('') for routine_name, routine_docs in instance_methods: docs = Docs(routine_docs, 2, is_class=True) # TODO: Subclass map-like classes from dict (or custom class) rather than this hack if docs.rtype in ('VisibilityIntMap', 'IntIntMap'): docs.rtype = 'Dict[int, int]' doc_string = docs.get_doc_string() if doc_string: doc_string = '\n' + doc_string end = '' else: end = '\n ...' result.append(' def %s(%s) -> %s:%s%s' % (routine_name, docs.get_argument_string(), docs.rtype, doc_string, end)) result.append('') if not (properties or instance_methods): result.append(' ...') if not result[-1]: result.pop() return '\n'.join(result)