| 565 | |
| 566 | |
| 567 | class IndexPythonClassesVisitor(CstVisitorBase): |
| 568 | def __init__(self, classes: dict[str, Any], paths: dict[str, Any], method_verbs: dict[str, str] | None): |
| 569 | super().__init__() |
| 570 | self._module = None |
| 571 | self._package = None |
| 572 | self._filename = None |
| 573 | self._test_filename = None |
| 574 | self._classes = classes |
| 575 | self._paths = paths |
| 576 | self._ids = [] |
| 577 | self._properties = {} |
| 578 | self._methods = {} |
| 579 | self._method_verbs = method_verbs |
| 580 | |
| 581 | def module(self, module: str): |
| 582 | self._module = module |
| 583 | |
| 584 | def package(self, package: str): |
| 585 | self._package = package |
| 586 | |
| 587 | def filename(self, filename: str): |
| 588 | self._filename = filename |
| 589 | |
| 590 | def test_filename(self, test_filename: str): |
| 591 | self._test_filename = test_filename |
| 592 | |
| 593 | @property |
| 594 | def classes(self) -> dict[str, Any]: |
| 595 | return self._classes |
| 596 | |
| 597 | def leave_ClassDef(self, node: cst.ClassDef) -> bool | None: |
| 598 | class_name = self.current_class_name |
| 599 | class_name_short = node.name.value |
| 600 | class_docstring = get_class_docstring(node) |
| 601 | class_docstring = class_docstring.strip('"\r\n ') if class_docstring else None |
| 602 | class_schemas = [] |
| 603 | class_bases = [ |
| 604 | val if isinstance(val, str) else Module([]).code_for_node(val).split(".")[-1] |
| 605 | for base in node.bases |
| 606 | for val in [base.value.value] |
| 607 | ] |
| 608 | |
| 609 | # extract OpenAPI schema |
| 610 | if class_docstring: |
| 611 | lines = class_docstring.splitlines() |
| 612 | for idx, line in enumerate(lines): |
| 613 | if "The OpenAPI schema can be found at" in line: |
| 614 | while len(lines) > idx + 1 and not lines[idx + 1].strip(): |
| 615 | idx = idx + 1 |
| 616 | for schema in lines[idx + 1 :]: |
| 617 | if not schema.strip().lstrip("- "): |
| 618 | break |
| 619 | class_schemas.append(schema.strip().lstrip("- ")) |
| 620 | |
| 621 | if class_name_short in self._classes: |
| 622 | print(f"Duplicate class definition for {class_name_short}") |
| 623 | |
| 624 | # TODO: ideally, the key should be the fully qualified class name and there |
no outgoing calls
no test coverage detected
searching dependent graphs…