|
| 1 | +import autoapi |
| 2 | +import autoapi.documenters |
| 3 | +from autoapi._objects import PythonClass |
| 4 | + |
| 5 | + |
| 6 | +def build_signatures(object): |
| 7 | + name = object.short_name |
| 8 | + |
| 9 | + if isinstance(object, PythonClass): |
| 10 | + if object.constructor is not None: |
| 11 | + object = object.constructor |
| 12 | + object.obj["return_annotation"] = name |
| 13 | + object.obj["overloads"] = [ |
| 14 | + (arg, name) for arg, _ in object.obj["overloads"] |
| 15 | + ] |
| 16 | + |
| 17 | + else: |
| 18 | + for child in object.children: |
| 19 | + if child.short_name == "__new__": |
| 20 | + object = child |
| 21 | + break |
| 22 | + |
| 23 | + if object is None: |
| 24 | + return |
| 25 | + |
| 26 | + sigs = [(object.obj["args"], object.obj["return_annotation"])] |
| 27 | + sigs.extend(object.obj["overloads"]) |
| 28 | + |
| 29 | + for args, ret in sigs: |
| 30 | + arg_string = "" |
| 31 | + for modifier, arg_name, _, default in args: |
| 32 | + modifier = modifier or "" |
| 33 | + arg_name = arg_name or "" |
| 34 | + default = default or "" |
| 35 | + |
| 36 | + if default: |
| 37 | + default = "=" + default |
| 38 | + arg_string += f", {modifier}{arg_name}{default}" |
| 39 | + |
| 40 | + if arg_string: |
| 41 | + arg_string = arg_string[2:] |
| 42 | + |
| 43 | + if ret.count("[") > 2 or ret.count(",") > 3: |
| 44 | + ret = "..." |
| 45 | + |
| 46 | + yield f"| :sg:`{name}({arg_string}) -> {ret}`" |
| 47 | + |
| 48 | + |
| 49 | +class AutopgDocumenter(autoapi.documenters.AutoapiDocumenter): |
| 50 | + def format_signature(self, **kwargs): |
| 51 | + return "" |
| 52 | + |
| 53 | + def get_doc(self, encoding=None, ignore=1): |
| 54 | + if self.object.docstring: |
| 55 | + return super().get_doc(encoding, ignore) |
| 56 | + |
| 57 | + # If we don't already have docs, check if a python implementation exists of this |
| 58 | + # module and return its docstring if it does |
| 59 | + python_object = self.env.autoapi_all_objects.get( |
| 60 | + self.object.id.replace("pygame", "src_py"), None |
| 61 | + ) |
| 62 | + if python_object is not None: |
| 63 | + return [python_object.docstring.splitlines()] |
| 64 | + |
| 65 | + return [""] |
| 66 | + |
| 67 | + def process_doc(self, docstrings: list[str]): |
| 68 | + for docstring in docstrings: |
| 69 | + if not docstring: |
| 70 | + continue |
| 71 | + |
| 72 | + yield f"| :sl:`{docstring[0]}`" |
| 73 | + |
| 74 | + if "args" in self.object.obj or hasattr(self.object, "constructor"): |
| 75 | + yield from build_signatures(self.object) |
| 76 | + else: |
| 77 | + annotation = self.object.obj.get("annotation", None) |
| 78 | + if annotation is not None: |
| 79 | + if annotation.count("[") > 2 or annotation.count(",") > 3: |
| 80 | + annotation = "..." |
| 81 | + yield f"| :sg:`{self.object.short_name} -> {annotation}`" |
| 82 | + |
| 83 | + yield from docstring[1:] |
| 84 | + |
| 85 | + yield "" |
| 86 | + |
| 87 | + |
| 88 | +def setup(app): |
| 89 | + names = [ |
| 90 | + "function", |
| 91 | + "property", |
| 92 | + "decorator", |
| 93 | + "class", |
| 94 | + "method", |
| 95 | + "data", |
| 96 | + "attribute", |
| 97 | + "module", |
| 98 | + "exception", |
| 99 | + ] |
| 100 | + |
| 101 | + for name in names: |
| 102 | + capitalized = name.capitalize() |
| 103 | + app.add_autodocumenter( |
| 104 | + type( |
| 105 | + f"Autopg{capitalized}Documenter", |
| 106 | + ( |
| 107 | + AutopgDocumenter, |
| 108 | + getattr(autoapi.documenters, f"Autoapi{capitalized}Documenter"), |
| 109 | + ), |
| 110 | + {"objtype": f"pg{name}"}, |
| 111 | + ) |
| 112 | + ) |
0 commit comments