(
self, spec_file: str, index_filename: str, class_names: list[str] | None, add: bool, dry_run: bool
)
| 2567 | return method_names |
| 2568 | |
| 2569 | def suggest_schemas( |
| 2570 | self, spec_file: str, index_filename: str, class_names: list[str] | None, add: bool, dry_run: bool |
| 2571 | ) -> bool: |
| 2572 | print(f"Using spec {spec_file}") |
| 2573 | with open(spec_file) as r: |
| 2574 | spec = json.load(r) |
| 2575 | with open(index_filename) as r: |
| 2576 | index = json.load(r) |
| 2577 | |
| 2578 | classes = index.get("classes", {}) |
| 2579 | schema_to_classes = index.get("indices", {}).get("schema_to_classes", {}) |
| 2580 | path_to_call_methods = index.get("indices", {}).get("path_to_call_methods", {}) |
| 2581 | path_to_return_classes = index.get("indices", {}).get("path_to_return_classes", {}) |
| 2582 | |
| 2583 | schemas_added = 0 |
| 2584 | schemas_suggested = 0 |
| 2585 | |
| 2586 | if class_names: |
| 2587 | if len(class_names) == 1: |
| 2588 | print(f"Suggesting API schemas for PyGithub class {class_names[0]}") |
| 2589 | else: |
| 2590 | print(f"Suggesting API schemas for {len(class_names)} PyGithub classes") |
| 2591 | else: |
| 2592 | print("Suggesting API schemas for PyGithub classes") |
| 2593 | |
| 2594 | def inner_return_type(return_type: str) -> list[str]: |
| 2595 | return_type = return_type.strip() |
| 2596 | if return_type == "None": |
| 2597 | return [] |
| 2598 | if return_type.startswith("Optional[") and return_type.endswith("]"): |
| 2599 | return inner_return_type(return_type[9:-1]) |
| 2600 | if return_type.startswith("PaginatedList[") and return_type.endswith("]"): |
| 2601 | return inner_return_type(return_type[14:-1]) |
| 2602 | if return_type.startswith("list[") and return_type.endswith("]"): |
| 2603 | return inner_return_type(return_type[5:-1]) |
| 2604 | if return_type.startswith("dict[") and "," in return_type and return_type.endswith("]"): |
| 2605 | # a dict of types indicates a wrapping object containing these types |
| 2606 | return [] |
| 2607 | |
| 2608 | # now that we have removed outer types, we can look for alternatives |
| 2609 | if "|" in return_type: |
| 2610 | return [rt for alt in return_type.split("|") for rt in inner_return_type(alt)] |
| 2611 | |
| 2612 | # return the pure class name, no outer class, module or package names |
| 2613 | if "." in return_type: |
| 2614 | return [return_type.split(".")[-1]] |
| 2615 | |
| 2616 | return [return_type] |
| 2617 | |
| 2618 | # suggest schemas based on properties of classes |
| 2619 | available_schemas = {} |
| 2620 | schema_returned_by = defaultdict(set) |
| 2621 | unimplemented_schemas = set() |
| 2622 | for cls in self.classes.values(): |
| 2623 | schemas: list[str] = cls.get("schemas", []) |
| 2624 | properties: dict[str, Any] = cls.get("properties", {}) |
| 2625 | if not schemas or not properties: |
| 2626 | continue |
no test coverage detected