pylint-bot / astroid-unofficial

UNOFFICIAL playground for astroid github migration
GNU Lesser General Public License v2.1
0 stars 0 forks source link

Crash when encountering PEP 448 unpacking in a dictionary #206

Closed pylint-bot closed 8 years ago

pylint-bot commented 9 years ago

Originally reported by: Claudiu Popa (BitBucket: PCManticore, GitHub: PCManticore)


Given this code {'x': 1, **{'y': 2}}, astroid fails with the following traceback

#!python

 (most recent call last):
 File "e:\projects\repos\pylint\pylint\lint.py", line 899, in get_ast
   return MANAGER.ast_from_file(filepath, modname, source=True)
 File "e:\projects\repos\astroid-1\astroid\manager.py", line 90, in ast_from_file
   return AstroidBuilder(self).file_build(filepath, modname)
 File "e:\projects\repos\astroid-1\astroid\builder.py", line 140, in file_build
   module = self._data_build(data, modname, path)
 File "e:\projects\repos\astroid-1\astroid\builder.py", line 189, in _data_build
   module = builder.visit_module(node, modname, node_file, package)
 File "e:\projects\repos\astroid-1\astroid\rebuilder.py", line 122, in visit_module
   newnode.postinit([self.visit(child, newnode) for child in node.body])
 File "e:\projects\repos\astroid-1\astroid\rebuilder.py", line 122, in <listcomp>
   newnode.postinit([self.visit(child, newnode) for child in node.body])
 File "e:\projects\repos\astroid-1\astroid\rebuilder.py", line 134, in visit
   return visit_method(node, parent, assign_ctx)
 File "e:\projects\repos\astroid-1\astroid\rebuilder.py", line 220, in visit_assign
   self.visit(node.value, newnode, None))
 File "e:\projects\repos\astroid-1\astroid\rebuilder.py", line 134, in visit
   return visit_method(node, parent, assign_ctx)
 File "e:\projects\repos\astroid-1\astroid\rebuilder.py", line 392, in visit_dict
   for key, value in zip(node.keys, node.values)])
 File "e:\projects\repos\astroid-1\astroid\rebuilder.py", line 392, in <listcomp>
   for key, value in zip(node.keys, node.values)])
 File "e:\projects\repos\astroid-1\astroid\rebuilder.py", line 132, in visit
   visit_method = getattr(self, visit_name)
AttributeError: 'TreeRebuilder3' object has no attribute 'visit_nonetype'

This happens because the dictionary is represented as a pair of keys and values in the form (['x', None], [1, {'y', 2}]) and astroid considers that each component is an AST node.


pylint-bot commented 9 years ago

Original comment by BitBucket: cezarelnazli, GitHub: cezarelnazli:


Are there any other cases where None might appear? Would a possible solution look something like if Pair[0][i] is None: Pair[0].remove(i); Pair[0].insert(i, Pair[1][i].keys())? Would something like this work for nested dicts as well ({'x': 1, **{'y': 2, **{'z': 3}}})?

pylint-bot commented 9 years ago

Original comment by Claudiu Popa (BitBucket: PCManticore, GitHub: PCManticore):


Add a new node, DictUnpack, for representing the unpacking of a dict using PEP 448

This is a different approach than what the builtin ast module does, since it just uses None to represent this kind of operation, which seems conceptually wrong, due to the fact the AST contains non-AST nodes. Closes issue #206.

pylint-bot commented 9 years ago

Original comment by Claudiu Popa (BitBucket: PCManticore, GitHub: PCManticore):


Cezar, I don't know, hopefully this was the only place where this occurred. I fixed it by adding a new node, since it seems that the builtin ast module does some things conceptually wrong (putting None as an AST node).

pylint-bot commented 8 years ago

Original comment by Claudiu Popa (BitBucket: PCManticore, GitHub: PCManticore):


Add a new node, DictUnpack, for representing the unpacking of a dict using PEP 448

This is a different approach than what the builtin ast module does, since it just uses None to represent this kind of operation, which seems conceptually wrong, due to the fact the AST contains non-AST nodes. Closes issue #206.