Avoid nasty side effects in creation of Node

This issue led to bugs in Jedi, because Jedi used the nodes in a wrong way.
This commit is contained in:
Dave Halter
2019-01-01 23:35:20 +01:00
parent 29325d3052
commit c7c464e5e9
5 changed files with 16 additions and 9 deletions

View File

@@ -186,7 +186,7 @@ class Grammar(object):
return normalizer.issues return normalizer.issues
def __repr__(self): def __repr__(self):
nonterminals = self._pgen_grammar._nonterminal_to_dfas.keys() nonterminals = self._pgen_grammar.nonterminal_to_dfas.keys()
txt = ' '.join(list(nonterminals)[:3]) + ' ...' txt = ' '.join(list(nonterminals)[:3]) + ' ...'
return '<%s:%s>' % (self.__class__.__name__, txt) return '<%s:%s>' % (self.__class__.__name__, txt)

View File

@@ -152,9 +152,12 @@ class BaseParser(object):
def convert_node(self, nonterminal, children): def convert_node(self, nonterminal, children):
try: try:
return self.node_map[nonterminal](children) node = self.node_map[nonterminal](children)
except KeyError: except KeyError:
return self.default_node(nonterminal, children) node = self.default_node(nonterminal, children)
for c in children:
c.parent = node
return node
def convert_leaf(self, type_, value, prefix, start_pos): def convert_leaf(self, type_, value, prefix, start_pos):
try: try:

View File

@@ -60,7 +60,7 @@ def _assert_valid_graph(node):
assert node.start_pos == actual, (node.start_pos, actual) assert node.start_pos == actual, (node.start_pos, actual)
else: else:
for child in children: for child in children:
assert child.parent == node assert child.parent == node, (node, child)
_assert_valid_graph(child) _assert_valid_graph(child)

View File

@@ -90,7 +90,7 @@ class Parser(BaseParser):
strictly bottom-up. strictly bottom-up.
""" """
try: try:
return self.node_map[nonterminal](children) node = self.node_map[nonterminal](children)
except KeyError: except KeyError:
if nonterminal == 'suite': if nonterminal == 'suite':
# We don't want the INDENT/DEDENT in our parser tree. Those # We don't want the INDENT/DEDENT in our parser tree. Those
@@ -104,7 +104,10 @@ class Parser(BaseParser):
elif nonterminal == 'listmaker': elif nonterminal == 'listmaker':
# Same as list_if above. # Same as list_if above.
nonterminal = 'testlist_comp' nonterminal = 'testlist_comp'
return self.default_node(nonterminal, children) node = self.default_node(nonterminal, children)
for c in children:
c.parent = node
return node
def convert_leaf(self, type, value, prefix, start_pos): def convert_leaf(self, type, value, prefix, start_pos):
# print('leaf', repr(value), token.tok_name[type]) # print('leaf', repr(value), token.tok_name[type])
@@ -189,7 +192,10 @@ class Parser(BaseParser):
all_nodes = [node for stack_node in self.stack[start_index:] for node in stack_node.nodes] all_nodes = [node for stack_node in self.stack[start_index:] for node in stack_node.nodes]
if all_nodes: if all_nodes:
self.stack[start_index - 1].nodes.append(tree.PythonErrorNode(all_nodes)) node = tree.PythonErrorNode(all_nodes)
for n in all_nodes:
n.parent = node
self.stack[start_index - 1].nodes.append(node)
self.stack[start_index:] = [] self.stack[start_index:] = []
return bool(all_nodes) return bool(all_nodes)

View File

@@ -244,8 +244,6 @@ class BaseNode(NodeOrLeaf):
type = None type = None
def __init__(self, children): def __init__(self, children):
for c in children:
c.parent = self
self.children = children self.children = children
""" """
A list of :class:`NodeOrLeaf` child nodes. A list of :class:`NodeOrLeaf` child nodes.