1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)""". 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)""" 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import collections 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# HIDDEN is a marker used to suppress a value, making it as if it were not set 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# in that object. This causes the search to continue through the tree. 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# This is most useful as a return value of dynamic values that want to find 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# the value they are shadowing. 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)HIDDEN = object() 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class VisitComplete(Exception): 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Indicates a vist traversal has finished early.""" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class Visitor(object): 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """The base class for anything that wants to "visit" all variables. 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) The two main uses of visitor are search and export. They differ in that export 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) is trying to find all variables, whereas search is just looking for one. 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """ 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def __init__(self): 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.stack = [] 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def VisitNode(self, node): 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Called for every node in the tree.""" 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if not node.enabled: 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return self 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) try: 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) try: 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.stack.append(node) 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.StartNode() 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Visit all the values first 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for key in self.KeysOf(node.values): 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.Visit(key, node.values[key]) 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # And now recurse into all the children 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for child in node.children: 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.VisitNode(child) 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) finally: 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.EndNode() 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.stack.pop() 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) except VisitComplete: 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if self.stack: 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # propagate back up the stack 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) raise 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Visit(self, key, value): 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Visit is called for every variable in each node.""" 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def StartNode(self): 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """StartNode is called once for each node before traversal.""" 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def EndNode(self): 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Visit is called for every node after traversal.""" 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) @property 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def root_node(self): 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Returns the variable at the root of the current traversal.""" 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self.stack[0] 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) @property 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def current_node(self): 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Returns the node currently being scanned.""" 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self.stack[-1] 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Resolve(self, key, value): 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Returns a fully substituted value. 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) This asks the root node to do the actual work. 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Args: 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) key: The key being visited. 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) value: The unresolved value associated with the key. 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Returns: 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) the fully resolved value. 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """ 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self.root_node.Resolve(self, key, value) 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Where(self): 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Returns the current traversal stack as a string.""" 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return '/'.join([entry.name for entry in self.stack]) 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SearchVisitor(Visitor): 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """A Visitor that finds a single matching key.""" 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def __init__(self, key): 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) super(SearchVisitor, self).__init__() 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.key = key 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.found = False 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.error = None 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def KeysOf(self, store): 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if self.key in store: 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) yield self.key 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Visit(self, key, value): 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) value, error = self.Resolve(key, value) 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if value is not HIDDEN: 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.found = True 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.value = value 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.error = error 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) raise VisitComplete() 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class WhereVisitor(SearchVisitor): 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """A SearchVisitor that returns the path to the matching key.""" 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Visit(self, key, value): 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.where = self.Where() 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) super(WhereVisitor, self).Visit(key, value) 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class ExportVisitor(Visitor): 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """A visitor that builds a fully resolved map of all variables.""" 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def __init__(self, store): 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) super(ExportVisitor, self).__init__() 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.store = store 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def KeysOf(self, store): 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if self.current_node.export is False: 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # not exporting from this config 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for key in store.keys(): 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if key in self.store: 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # duplicate 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (self.current_node.export is None) and key.startswith('_'): 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # non exported name 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) yield key 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Visit(self, key, value): 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) value, _ = self.Resolve(key, value) 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if value is not HIDDEN: 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.store[key] = value 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class Node(object): 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """The base class for objects in a visitable node tree.""" 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def __init__(self, name='--', enabled=True, export=True): 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._name = name 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._children = collections.deque() 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._values = {} 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._viewers = [] 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.trail = [] 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._enabled = enabled 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._export = export 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._export_cache = None 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) @property 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def name(self): 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self._name 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) @name.setter 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def name(self, value): 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._name = value 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) @property 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def enabled(self): 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self._enabled 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) @enabled.setter 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def enabled(self, value): 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if self._enabled == value: 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._enabled = value 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.NotifyChanged() 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) @property 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def export(self): 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self._export 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) @property 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def exported(self): 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if self._export_cache is None: 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._export_cache = ExportVisitor({}).VisitNode(self).store 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self._export_cache 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) @property 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def values(self): 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self._values 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) @property 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def children(self): 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self._children 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def RegisterViewer(self, viewer): 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._viewers.append(viewer) 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def UnregisterViewer(self, viewer): 200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._viewers.remove(viewer) 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def OnChanged(self, child): 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _ = child 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.NotifyChanged() 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def NotifyChanged(self): 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._export_cache = None 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for viewers in self._viewers: 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) viewers.OnChanged(self) 210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def _AddChild(self, child): 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if child and child != self and child not in self._children: 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._children.appendleft(child) 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) child.RegisterViewer(self) 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def AddChild(self, child): 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._AddChild(child) 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.NotifyChanged() 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def AddChildren(self, *children): 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for child in children: 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._AddChild(child) 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.NotifyChanged() 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Find(self, key): 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) search = SearchVisitor(key).VisitNode(self) 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if not search.found: 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return None 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return search.value 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def WhereIs(self, key): 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) search = WhereVisitor(key).VisitNode(self) 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if not search.found: 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return None 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return search.where 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Get(self, key, raise_errors=False): 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) search = SearchVisitor(key).VisitNode(self) 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if not search.found: 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) self.Missing(key) 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if search.error and raise_errors: 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) raise search.error # bad type inference pylint: disable=raising-bad-type 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return search.value 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) def Missing(self, key): 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) raise KeyError(key) 249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Resolve(self, visitor, key, value): 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _ = visitor, key 252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return value 253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Wipe(self): 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for child in self._children: 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) child.UnregisterViewer(self) 257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._children = collections.deque() 258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._values = {} 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.NotifyChanged() 260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 261