-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathqualnames.py
More file actions
57 lines (46 loc) · 1.79 KB
/
qualnames.py
File metadata and controls
57 lines (46 loc) · 1.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2026 Den Rozhnovskiy
from __future__ import annotations
import ast
__all__ = ["FunctionNode", "QualnameCollector"]
FunctionNode = ast.FunctionDef | ast.AsyncFunctionDef
class QualnameCollector(ast.NodeVisitor):
__slots__ = (
"class_count",
"class_nodes",
"funcs",
"function_count",
"method_count",
"stack",
"units",
)
def __init__(self) -> None:
self.stack: list[str] = []
self.units: list[tuple[str, FunctionNode]] = []
self.class_nodes: list[tuple[str, ast.ClassDef]] = []
self.funcs: dict[str, FunctionNode] = {}
self.class_count = 0
self.function_count = 0
self.method_count = 0
def visit_ClassDef(self, node: ast.ClassDef) -> None:
self.class_count += 1
class_qualname = ".".join([*self.stack, node.name]) if self.stack else node.name
self.class_nodes.append((class_qualname, node))
self.stack.append(node.name)
self.generic_visit(node)
self.stack.pop()
def _register_function(self, node: FunctionNode) -> None:
name = ".".join([*self.stack, node.name]) if self.stack else node.name
if self.stack:
self.method_count += 1
else:
self.function_count += 1
self.units.append((name, node))
self.funcs[name] = node
def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
self._register_function(node)
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None:
self._register_function(node)