Find symbol node by path to file and line number. Find the first function declared *before or on* the line number. Return module id and the node found. Raise SuggestionFailure if can't find one.
(self, file: str, line: int)
| 619 | return names[funcname].node |
| 620 | |
| 621 | def find_node_by_file_and_line(self, file: str, line: int) -> tuple[str, SymbolNode]: |
| 622 | """Find symbol node by path to file and line number. |
| 623 | |
| 624 | Find the first function declared *before or on* the line number. |
| 625 | |
| 626 | Return module id and the node found. Raise SuggestionFailure if can't find one. |
| 627 | """ |
| 628 | if not any(file.endswith(ext) for ext in PYTHON_EXTENSIONS): |
| 629 | raise SuggestionFailure("Source file is not a Python file") |
| 630 | try: |
| 631 | modname, _ = self.finder.crawl_up(os.path.normpath(file)) |
| 632 | except InvalidSourceList as e: |
| 633 | raise SuggestionFailure("Invalid source file name: " + file) from e |
| 634 | if modname not in self.graph: |
| 635 | raise SuggestionFailure("Unknown module: " + modname) |
| 636 | # We must be sure about any edits in this file as this might affect the line numbers. |
| 637 | tree = self.ensure_loaded(self.fgmanager.graph[modname], force=True) |
| 638 | node: SymbolNode | None = None |
| 639 | closest_line: int | None = None |
| 640 | # TODO: Handle nested functions. |
| 641 | for _, sym, _ in tree.local_definitions(): |
| 642 | if isinstance(sym.node, (FuncDef, Decorator)): |
| 643 | sym_line = sym.node.line |
| 644 | # TODO: add support for OverloadedFuncDef. |
| 645 | else: |
| 646 | continue |
| 647 | |
| 648 | # We want the closest function above the specified line |
| 649 | if sym_line <= line and (closest_line is None or sym_line > closest_line): |
| 650 | closest_line = sym_line |
| 651 | node = sym.node |
| 652 | if not node: |
| 653 | raise SuggestionFailure(f"Cannot find a function at line {line}") |
| 654 | return modname, node |
| 655 | |
| 656 | def extract_from_decorator(self, node: Decorator) -> FuncDef | None: |
| 657 | for dec in node.decorators: |
no test coverage detected