2727import argparse
2828import glob
2929import logging
30- import re
3130from collections import defaultdict
32- from typing import List , Dict , Any , Iterator
31+ from pathlib import Path
32+ from typing import List , Dict , Any
3333
3434from . import name_utils
3535from . import utils
@@ -51,6 +51,7 @@ def __init__(self):
5151 self .types : set [str ] = set ()
5252 self ._current_class_info : Dict [str , Any ] | None = None
5353 self ._is_in_method : bool = False
54+ self ._depth = 0
5455
5556 def _get_type_str (self , node : ast .AST | None ) -> str | None :
5657 """Recursively reconstructs a type annotation string from an AST node."""
@@ -112,30 +113,32 @@ def _collect_types_from_node(self, node: ast.AST | None) -> None:
112113
113114 def visit_Import (self , node : ast .Import ) -> None :
114115 """Catches 'import X' and 'import X as Y' statements."""
115- for alias in node .names :
116- if alias .asname :
117- self .imports .add (f"import { alias .name } as { alias .asname } " )
118- else :
119- self .imports .add (f"import { alias .name } " )
116+ if self ._depth == 0 : # Only top-level imports
117+ for alias in node .names :
118+ if alias .asname :
119+ self .imports .add (f"import { alias .name } as { alias .asname } " )
120+ else :
121+ self .imports .add (f"import { alias .name } " )
120122 self .generic_visit (node )
121123
122124 def visit_ImportFrom (self , node : ast .ImportFrom ) -> None :
123125 """Catches 'from X import Y' statements."""
124- module = node .module or ""
125- if not module :
126- module = "." * node .level
127- else :
128- module = "." * node .level + module
129-
130- names = []
131- for alias in node .names :
132- if alias .asname :
133- names .append (f"{ alias .name } as { alias .asname } " )
126+ if self ._depth == 0 : # Only top-level imports
127+ module = node .module or ""
128+ if not module :
129+ module = "." * node .level
134130 else :
135- names .append (alias .name )
131+ module = "." * node .level + module
132+
133+ names = []
134+ for alias in node .names :
135+ if alias .asname :
136+ names .append (f"{ alias .name } as { alias .asname } " )
137+ else :
138+ names .append (alias .name )
136139
137- if names :
138- self .imports .add (f"from { module } import { ', ' .join (names )} " )
140+ if names :
141+ self .imports .add (f"from { module } import { ', ' .join (names )} " )
139142 self .generic_visit (node )
140143
141144 def visit_ClassDef (self , node : ast .ClassDef ) -> None :
@@ -155,12 +158,15 @@ def visit_ClassDef(self, node: ast.ClassDef) -> None:
155158
156159 self .structure .append (class_info )
157160 self ._current_class_info = class_info
161+ self ._depth += 1
158162 self .generic_visit (node )
163+ self ._depth -= 1
159164 self ._current_class_info = None
160165
161166 def visit_FunctionDef (self , node : ast .FunctionDef ) -> None :
162167 """Visits a function/method definition node."""
163- if self ._current_class_info : # This is a method
168+ is_method = self ._current_class_info is not None
169+ if is_method :
164170 args_info = []
165171
166172 # Get default values
@@ -189,10 +195,13 @@ def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
189195 "return_type" : return_type ,
190196 }
191197 self ._current_class_info ["methods" ].append (method_info )
192-
193- # Visit nodes inside the method to find instance attributes.
194198 self ._is_in_method = True
195- self .generic_visit (node )
199+
200+ self ._depth += 1
201+ self .generic_visit (node )
202+ self ._depth -= 1
203+
204+ if is_method :
196205 self ._is_in_method = False
197206
198207 def _add_attribute (self , attr_name : str , attr_type : str | None = None ):
0 commit comments