Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/libcst/codemod/visitors/_gather_global_names.py: 33%
36 statements
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-25 06:43 +0000
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-25 06:43 +0000
1# Copyright (c) Meta Platforms, Inc. and affiliates.
2#
3# This source code is licensed under the MIT license found in the
4# LICENSE file in the root directory of this source tree.
6from typing import Set
8import libcst
9from libcst.codemod._context import CodemodContext
10from libcst.codemod._visitor import ContextAwareVisitor
13class GatherGlobalNamesVisitor(ContextAwareVisitor):
14 """
15 Gathers all globally accessible names defined in a module and stores them as
16 attributes on the instance.
17 Intended to be instantiated and passed to a :class:`~libcst.Module`
18 :meth:`~libcst.CSTNode.visit` method in order to gather up information about
19 names defined on a module. Note that this is not a substitute for scope
20 analysis or qualified name support. Please see :ref:`libcst-scope-tutorial`
21 for a more robust way of determining the qualified name and definition for
22 an arbitrary node.
23 Names that are globally accessible through imports are currently not included
24 but can be retrieved with GatherImportsVisitor.
26 After visiting a module the following attributes will be populated:
28 global_names
29 A sequence of strings representing global variables defined in the module
30 toplevel.
31 class_names
32 A sequence of strings representing classes defined in the module toplevel.
33 function_names
34 A sequence of strings representing functions defined in the module toplevel.
36 """
38 def __init__(self, context: CodemodContext) -> None:
39 super().__init__(context)
40 self.global_names: Set[str] = set()
41 self.class_names: Set[str] = set()
42 self.function_names: Set[str] = set()
43 # Track scope nesting
44 self.scope_depth: int = 0
46 def visit_ClassDef(self, node: libcst.ClassDef) -> None:
47 if self.scope_depth == 0:
48 self.class_names.add(node.name.value)
49 self.scope_depth += 1
51 def leave_ClassDef(self, original_node: libcst.ClassDef) -> None:
52 self.scope_depth -= 1
54 def visit_FunctionDef(self, node: libcst.FunctionDef) -> None:
55 if self.scope_depth == 0:
56 self.function_names.add(node.name.value)
57 self.scope_depth += 1
59 def leave_FunctionDef(self, original_node: libcst.FunctionDef) -> None:
60 self.scope_depth -= 1
62 def visit_Assign(self, node: libcst.Assign) -> None:
63 if self.scope_depth != 0:
64 return
65 for assign_target in node.targets:
66 target = assign_target.target
67 if isinstance(target, libcst.Name):
68 self.global_names.add(target.value)
70 def visit_AnnAssign(self, node: libcst.AnnAssign) -> None:
71 if self.scope_depth != 0:
72 return
73 target = node.target
74 if isinstance(target, libcst.Name):
75 self.global_names.add(target.value)