|
25 | 25 | # along with PyGithub. If not, see <http://www.gnu.org/licenses/>. # |
26 | 26 | # # |
27 | 27 | ################################################################################ |
| 28 | +from __future__ import annotations |
28 | 29 |
|
29 | 30 | import datetime |
30 | 31 | import glob |
31 | 32 | import os |
| 33 | +import re |
32 | 34 | import sys |
| 35 | +from typing import Iterable |
33 | 36 |
|
34 | 37 | # If extensions (or modules to document with autodoc) are in another directory, |
35 | 38 | # add these directories to sys.path here. If the directory is relative to the |
|
268 | 271 | autodoc_member_order = "bysource" |
269 | 272 | autoclass_content = "both" |
270 | 273 |
|
271 | | -githubClasses = [ |
272 | | - fileName[10:-3] |
273 | | - for fileName in sorted(glob.glob("../github/*.py")) |
274 | | - if fileName |
275 | | - not in [ |
276 | | - "../github/GithubException.py", |
277 | | - "../github/GithubObject.py", |
278 | | - "../github/InputFileContent.py", |
279 | | - "../github/InputGitAuthor.py", |
280 | | - "../github/InputGitTreeElement.py", |
281 | | - "../github/Legacy.py", |
282 | | - "../github/MainClass.py", |
283 | | - "../github/PaginatedList.py", |
284 | | - "../github/Requester.py", |
285 | | - "../github/Consts.py", |
286 | | - "../github/__init__.py", |
287 | | - ] |
288 | | -] |
| 274 | +githubObjectTypes = { |
| 275 | + variation |
| 276 | + for object_type in ["GithubObject", "CompletableGithubObject", "NonCompletableGithubObject"] |
| 277 | + for variation in [object_type, "GithubObject." + object_type, "github.GithubObject." + object_type] |
| 278 | +} |
| 279 | +githubObjectClasses: dict[str, str] = {} |
| 280 | + |
| 281 | + |
| 282 | +def collect_classes(types: set[str]) -> Iterable[tuple[str, str]]: |
| 283 | + def get_base_classes(class_definition: str) -> Iterable[str]: |
| 284 | + if "(" in class_definition and ")" in class_definition: |
| 285 | + for base in class_definition[class_definition.index("(") + 1 : class_definition.index(")")].split(","): |
| 286 | + yield base.strip() |
| 287 | + else: |
| 288 | + return [] |
| 289 | + |
| 290 | + for filename in sorted(glob.glob("../github/*.py")): |
| 291 | + module = f"github.{filename[10:-3]}" |
| 292 | + with open(filename) as r: |
| 293 | + for line in r.readlines(): |
| 294 | + if line.startswith("class ") and any([base in types for base in get_base_classes(line)]): |
| 295 | + class_name = re.match(r"class (\w+)[:(]", line).group(1) |
| 296 | + if class_name not in types: |
| 297 | + yield class_name, f"{module}" |
| 298 | + |
| 299 | + |
| 300 | +# get all classes derived from GithubObject classes directly |
| 301 | +classes = list(collect_classes(githubObjectTypes)) |
| 302 | +while classes: |
| 303 | + githubObjectClasses.update(classes) |
| 304 | + # get all classes derived from detected classes |
| 305 | + githubObjectTypes.update( |
| 306 | + { |
| 307 | + variation |
| 308 | + for object_type in [cls for cls, _ in classes] |
| 309 | + for variation in [object_type, "GithubObject." + object_type, "github.GithubObject." + object_type] |
| 310 | + } |
| 311 | + ) |
| 312 | + classes = list(collect_classes(set(githubObjectTypes))) |
289 | 313 |
|
290 | 314 | with open("github_objects.rst", "w") as f: |
291 | 315 | f.write("Github objects\n") |
|
294 | 318 | f.write(".. autoclass:: github.GithubObject.GithubObject()\n") |
295 | 319 | f.write("\n") |
296 | 320 | f.write(".. toctree::\n") |
297 | | - for githubClass in githubClasses: |
298 | | - f.write(" github_objects/" + githubClass + "\n") |
| 321 | + for githubObjectClass in sorted(githubObjectClasses.keys()): |
| 322 | + f.write(" github_objects/" + githubObjectClass + "\n") |
299 | 323 |
|
300 | | -for githubClass in githubClasses: |
301 | | - with open("github_objects/" + githubClass + ".rst", "w") as f: |
302 | | - f.write(githubClass + "\n") |
303 | | - f.write("=" * len(githubClass) + "\n") |
| 324 | +for githubObjectClass, module in githubObjectClasses.items(): |
| 325 | + with open("github_objects/" + githubObjectClass + ".rst", "w") as f: |
| 326 | + f.write(githubObjectClass + "\n") |
| 327 | + f.write("=" * len(githubObjectClass) + "\n") |
304 | 328 | f.write("\n") |
305 | | - f.write(".. autoclass:: github." + githubClass + "." + githubClass + "()\n") |
| 329 | + f.write(".. autoclass:: " + module + "." + githubObjectClass + "()\n") |
306 | 330 |
|
307 | 331 | methods = dict() |
308 | | -for githubClass in githubClasses + ["MainClass"]: |
309 | | - with open("../github/" + githubClass + ".py") as f: |
310 | | - if githubClass == "MainClass": |
311 | | - githubClass = "github.MainClass.Github" |
312 | | - else: |
313 | | - githubClass = "github." + githubClass + "." + githubClass |
| 332 | +githubObjectClasses.update([("MainClass", "github.MainClass")]) |
| 333 | +githubObjectClasses.update([("GithubIntegration", "github.GithubIntegration")]) |
| 334 | +for githubObjectClass, module in githubObjectClasses.items(): |
| 335 | + with open("../" + module.replace(".", "/") + ".py") as f: |
314 | 336 | method = None |
315 | 337 | isProperty = False |
316 | 338 | for line in f: |
|
345 | 367 | methods[url] = dict() |
346 | 368 | if verb not in methods[url]: |
347 | 369 | methods[url][verb] = set() |
348 | | - methods[url][verb].add(":meth:`" + githubClass + "." + method + "`") |
| 370 | + methods[url][verb].add(":meth:`" + module + "." + githubObjectClass + "." + method + "`") |
349 | 371 | method = None |
350 | 372 |
|
351 | 373 | methods["/markdown/raw"] = dict() |
|
0 commit comments