|
74 | 74 | StatementMissing,
|
75 | 75 | TooManyLevelsError,
|
76 | 76 | )
|
77 |
| -from astroid.filter_statements import _filter_stmts |
78 | 77 | from astroid.interpreter.dunder_lookup import lookup
|
79 | 78 | from astroid.interpreter.objectmodel import ClassModel, FunctionModel, ModuleModel
|
80 | 79 | from astroid.manager import AstroidManager
|
81 | 80 | from astroid.nodes import Arguments, Const, node_classes
|
| 81 | +from astroid.nodes.scoped_nodes.mixin import ComprehensionScope, LocalsDictNodeNG |
82 | 82 | from astroid.nodes.scoped_nodes.utils import builtin_lookup
|
83 | 83 | from astroid.nodes.utils import Position
|
84 | 84 |
|
@@ -215,157 +215,6 @@ def function_to_method(n, klass):
|
215 | 215 | return n
|
216 | 216 |
|
217 | 217 |
|
218 |
| -# TODO move this Mixin to mixins.py; problem: 'FunctionDef' in _scope_lookup |
219 |
| -class LocalsDictNodeNG(node_classes.LookupMixIn, node_classes.NodeNG): |
220 |
| - """this class provides locals handling common to Module, FunctionDef |
221 |
| - and ClassDef nodes, including a dict like interface for direct access |
222 |
| - to locals information |
223 |
| - """ |
224 |
| - |
225 |
| - # attributes below are set by the builder module or by raw factories |
226 |
| - |
227 |
| - locals: Dict[str, List[node_classes.NodeNG]] = {} |
228 |
| - """A map of the name of a local variable to the node defining the local.""" |
229 |
| - |
230 |
| - def qname(self): |
231 |
| - """Get the 'qualified' name of the node. |
232 |
| -
|
233 |
| - For example: module.name, module.class.name ... |
234 |
| -
|
235 |
| - :returns: The qualified name. |
236 |
| - :rtype: str |
237 |
| - """ |
238 |
| - # pylint: disable=no-member; github.com/pycqa/astroid/issues/278 |
239 |
| - if self.parent is None: |
240 |
| - return self.name |
241 |
| - return f"{self.parent.frame(future=True).qname()}.{self.name}" |
242 |
| - |
243 |
| - def scope(self: T) -> T: |
244 |
| - """The first parent node defining a new scope. |
245 |
| -
|
246 |
| - :returns: The first parent scope node. |
247 |
| - :rtype: Module or FunctionDef or ClassDef or Lambda or GenExpr |
248 |
| - """ |
249 |
| - return self |
250 |
| - |
251 |
| - def _scope_lookup(self, node, name, offset=0): |
252 |
| - """XXX method for interfacing the scope lookup""" |
253 |
| - try: |
254 |
| - stmts = _filter_stmts(node, self.locals[name], self, offset) |
255 |
| - except KeyError: |
256 |
| - stmts = () |
257 |
| - if stmts: |
258 |
| - return self, stmts |
259 |
| - |
260 |
| - # Handle nested scopes: since class names do not extend to nested |
261 |
| - # scopes (e.g., methods), we find the next enclosing non-class scope |
262 |
| - pscope = self.parent and self.parent.scope() |
263 |
| - while pscope is not None: |
264 |
| - if not isinstance(pscope, ClassDef): |
265 |
| - return pscope.scope_lookup(node, name) |
266 |
| - pscope = pscope.parent and pscope.parent.scope() |
267 |
| - |
268 |
| - # self is at the top level of a module, or is enclosed only by ClassDefs |
269 |
| - return builtin_lookup(name) |
270 |
| - |
271 |
| - def set_local(self, name, stmt): |
272 |
| - """Define that the given name is declared in the given statement node. |
273 |
| -
|
274 |
| - .. seealso:: :meth:`scope` |
275 |
| -
|
276 |
| - :param name: The name that is being defined. |
277 |
| - :type name: str |
278 |
| -
|
279 |
| - :param stmt: The statement that defines the given name. |
280 |
| - :type stmt: NodeNG |
281 |
| - """ |
282 |
| - # assert not stmt in self.locals.get(name, ()), (self, stmt) |
283 |
| - self.locals.setdefault(name, []).append(stmt) |
284 |
| - |
285 |
| - __setitem__ = set_local |
286 |
| - |
287 |
| - def _append_node(self, child): |
288 |
| - """append a child, linking it in the tree""" |
289 |
| - # pylint: disable=no-member; depending by the class |
290 |
| - # which uses the current class as a mixin or base class. |
291 |
| - # It's rewritten in 2.0, so it makes no sense for now |
292 |
| - # to spend development time on it. |
293 |
| - self.body.append(child) |
294 |
| - child.parent = self |
295 |
| - |
296 |
| - def add_local_node(self, child_node, name=None): |
297 |
| - """Append a child that should alter the locals of this scope node. |
298 |
| -
|
299 |
| - :param child_node: The child node that will alter locals. |
300 |
| - :type child_node: NodeNG |
301 |
| -
|
302 |
| - :param name: The name of the local that will be altered by |
303 |
| - the given child node. |
304 |
| - :type name: str or None |
305 |
| - """ |
306 |
| - if name != "__class__": |
307 |
| - # add __class__ node as a child will cause infinite recursion later! |
308 |
| - self._append_node(child_node) |
309 |
| - self.set_local(name or child_node.name, child_node) |
310 |
| - |
311 |
| - def __getitem__(self, item): |
312 |
| - """The first node the defines the given local. |
313 |
| -
|
314 |
| - :param item: The name of the locally defined object. |
315 |
| - :type item: str |
316 |
| -
|
317 |
| - :raises KeyError: If the name is not defined. |
318 |
| - """ |
319 |
| - return self.locals[item][0] |
320 |
| - |
321 |
| - def __iter__(self): |
322 |
| - """Iterate over the names of locals defined in this scoped node. |
323 |
| -
|
324 |
| - :returns: The names of the defined locals. |
325 |
| - :rtype: iterable(str) |
326 |
| - """ |
327 |
| - return iter(self.keys()) |
328 |
| - |
329 |
| - def keys(self): |
330 |
| - """The names of locals defined in this scoped node. |
331 |
| -
|
332 |
| - :returns: The names of the defined locals. |
333 |
| - :rtype: list(str) |
334 |
| - """ |
335 |
| - return list(self.locals.keys()) |
336 |
| - |
337 |
| - def values(self): |
338 |
| - """The nodes that define the locals in this scoped node. |
339 |
| -
|
340 |
| - :returns: The nodes that define locals. |
341 |
| - :rtype: list(NodeNG) |
342 |
| - """ |
343 |
| - # pylint: disable=consider-using-dict-items |
344 |
| - # It look like this class override items/keys/values, |
345 |
| - # probably not worth the headache |
346 |
| - return [self[key] for key in self.keys()] |
347 |
| - |
348 |
| - def items(self): |
349 |
| - """Get the names of the locals and the node that defines the local. |
350 |
| -
|
351 |
| - :returns: The names of locals and their associated node. |
352 |
| - :rtype: list(tuple(str, NodeNG)) |
353 |
| - """ |
354 |
| - return list(zip(self.keys(), self.values())) |
355 |
| - |
356 |
| - def __contains__(self, name): |
357 |
| - """Check if a local is defined in this scope. |
358 |
| -
|
359 |
| - :param name: The name of the local to check for. |
360 |
| - :type name: str |
361 |
| -
|
362 |
| - :returns: True if this node has a local of the given name, |
363 |
| - False otherwise. |
364 |
| - :rtype: bool |
365 |
| - """ |
366 |
| - return name in self.locals |
367 |
| - |
368 |
| - |
369 | 218 | class Module(LocalsDictNodeNG):
|
370 | 219 | """Class representing an :class:`ast.Module` node.
|
371 | 220 |
|
@@ -849,12 +698,6 @@ def frame(self: T, *, future: Literal[None, True] = None) -> T:
|
849 | 698 | return self
|
850 | 699 |
|
851 | 700 |
|
852 |
| -class ComprehensionScope(LocalsDictNodeNG): |
853 |
| - """Scoping for different types of comprehensions.""" |
854 |
| - |
855 |
| - scope_lookup = LocalsDictNodeNG._scope_lookup |
856 |
| - |
857 |
| - |
858 | 701 | class GeneratorExp(ComprehensionScope):
|
859 | 702 | """Class representing an :class:`ast.GeneratorExp` node.
|
860 | 703 |
|
|
0 commit comments