1*cda5da8dSAndroid Build Coastguard Worker"""Interface to the compiler's internal symbol tables""" 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard Workerimport _symtable 4*cda5da8dSAndroid Build Coastguard Workerfrom _symtable import (USE, DEF_GLOBAL, DEF_NONLOCAL, DEF_LOCAL, DEF_PARAM, 5*cda5da8dSAndroid Build Coastguard Worker DEF_IMPORT, DEF_BOUND, DEF_ANNOT, SCOPE_OFF, SCOPE_MASK, FREE, 6*cda5da8dSAndroid Build Coastguard Worker LOCAL, GLOBAL_IMPLICIT, GLOBAL_EXPLICIT, CELL) 7*cda5da8dSAndroid Build Coastguard Worker 8*cda5da8dSAndroid Build Coastguard Workerimport weakref 9*cda5da8dSAndroid Build Coastguard Worker 10*cda5da8dSAndroid Build Coastguard Worker__all__ = ["symtable", "SymbolTable", "Class", "Function", "Symbol"] 11*cda5da8dSAndroid Build Coastguard Worker 12*cda5da8dSAndroid Build Coastguard Workerdef symtable(code, filename, compile_type): 13*cda5da8dSAndroid Build Coastguard Worker """ Return the toplevel *SymbolTable* for the source code. 14*cda5da8dSAndroid Build Coastguard Worker 15*cda5da8dSAndroid Build Coastguard Worker *filename* is the name of the file with the code 16*cda5da8dSAndroid Build Coastguard Worker and *compile_type* is the *compile()* mode argument. 17*cda5da8dSAndroid Build Coastguard Worker """ 18*cda5da8dSAndroid Build Coastguard Worker top = _symtable.symtable(code, filename, compile_type) 19*cda5da8dSAndroid Build Coastguard Worker return _newSymbolTable(top, filename) 20*cda5da8dSAndroid Build Coastguard Worker 21*cda5da8dSAndroid Build Coastguard Workerclass SymbolTableFactory: 22*cda5da8dSAndroid Build Coastguard Worker def __init__(self): 23*cda5da8dSAndroid Build Coastguard Worker self.__memo = weakref.WeakValueDictionary() 24*cda5da8dSAndroid Build Coastguard Worker 25*cda5da8dSAndroid Build Coastguard Worker def new(self, table, filename): 26*cda5da8dSAndroid Build Coastguard Worker if table.type == _symtable.TYPE_FUNCTION: 27*cda5da8dSAndroid Build Coastguard Worker return Function(table, filename) 28*cda5da8dSAndroid Build Coastguard Worker if table.type == _symtable.TYPE_CLASS: 29*cda5da8dSAndroid Build Coastguard Worker return Class(table, filename) 30*cda5da8dSAndroid Build Coastguard Worker return SymbolTable(table, filename) 31*cda5da8dSAndroid Build Coastguard Worker 32*cda5da8dSAndroid Build Coastguard Worker def __call__(self, table, filename): 33*cda5da8dSAndroid Build Coastguard Worker key = table, filename 34*cda5da8dSAndroid Build Coastguard Worker obj = self.__memo.get(key, None) 35*cda5da8dSAndroid Build Coastguard Worker if obj is None: 36*cda5da8dSAndroid Build Coastguard Worker obj = self.__memo[key] = self.new(table, filename) 37*cda5da8dSAndroid Build Coastguard Worker return obj 38*cda5da8dSAndroid Build Coastguard Worker 39*cda5da8dSAndroid Build Coastguard Worker_newSymbolTable = SymbolTableFactory() 40*cda5da8dSAndroid Build Coastguard Worker 41*cda5da8dSAndroid Build Coastguard Worker 42*cda5da8dSAndroid Build Coastguard Workerclass SymbolTable: 43*cda5da8dSAndroid Build Coastguard Worker 44*cda5da8dSAndroid Build Coastguard Worker def __init__(self, raw_table, filename): 45*cda5da8dSAndroid Build Coastguard Worker self._table = raw_table 46*cda5da8dSAndroid Build Coastguard Worker self._filename = filename 47*cda5da8dSAndroid Build Coastguard Worker self._symbols = {} 48*cda5da8dSAndroid Build Coastguard Worker 49*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 50*cda5da8dSAndroid Build Coastguard Worker if self.__class__ == SymbolTable: 51*cda5da8dSAndroid Build Coastguard Worker kind = "" 52*cda5da8dSAndroid Build Coastguard Worker else: 53*cda5da8dSAndroid Build Coastguard Worker kind = "%s " % self.__class__.__name__ 54*cda5da8dSAndroid Build Coastguard Worker 55*cda5da8dSAndroid Build Coastguard Worker if self._table.name == "top": 56*cda5da8dSAndroid Build Coastguard Worker return "<{0}SymbolTable for module {1}>".format(kind, self._filename) 57*cda5da8dSAndroid Build Coastguard Worker else: 58*cda5da8dSAndroid Build Coastguard Worker return "<{0}SymbolTable for {1} in {2}>".format(kind, 59*cda5da8dSAndroid Build Coastguard Worker self._table.name, 60*cda5da8dSAndroid Build Coastguard Worker self._filename) 61*cda5da8dSAndroid Build Coastguard Worker 62*cda5da8dSAndroid Build Coastguard Worker def get_type(self): 63*cda5da8dSAndroid Build Coastguard Worker """Return the type of the symbol table. 64*cda5da8dSAndroid Build Coastguard Worker 65*cda5da8dSAndroid Build Coastguard Worker The values returned are 'class', 'module' and 66*cda5da8dSAndroid Build Coastguard Worker 'function'. 67*cda5da8dSAndroid Build Coastguard Worker """ 68*cda5da8dSAndroid Build Coastguard Worker if self._table.type == _symtable.TYPE_MODULE: 69*cda5da8dSAndroid Build Coastguard Worker return "module" 70*cda5da8dSAndroid Build Coastguard Worker if self._table.type == _symtable.TYPE_FUNCTION: 71*cda5da8dSAndroid Build Coastguard Worker return "function" 72*cda5da8dSAndroid Build Coastguard Worker if self._table.type == _symtable.TYPE_CLASS: 73*cda5da8dSAndroid Build Coastguard Worker return "class" 74*cda5da8dSAndroid Build Coastguard Worker assert self._table.type in (1, 2, 3), \ 75*cda5da8dSAndroid Build Coastguard Worker "unexpected type: {0}".format(self._table.type) 76*cda5da8dSAndroid Build Coastguard Worker 77*cda5da8dSAndroid Build Coastguard Worker def get_id(self): 78*cda5da8dSAndroid Build Coastguard Worker """Return an identifier for the table. 79*cda5da8dSAndroid Build Coastguard Worker """ 80*cda5da8dSAndroid Build Coastguard Worker return self._table.id 81*cda5da8dSAndroid Build Coastguard Worker 82*cda5da8dSAndroid Build Coastguard Worker def get_name(self): 83*cda5da8dSAndroid Build Coastguard Worker """Return the table's name. 84*cda5da8dSAndroid Build Coastguard Worker 85*cda5da8dSAndroid Build Coastguard Worker This corresponds to the name of the class, function 86*cda5da8dSAndroid Build Coastguard Worker or 'top' if the table is for a class, function or 87*cda5da8dSAndroid Build Coastguard Worker global respectively. 88*cda5da8dSAndroid Build Coastguard Worker """ 89*cda5da8dSAndroid Build Coastguard Worker return self._table.name 90*cda5da8dSAndroid Build Coastguard Worker 91*cda5da8dSAndroid Build Coastguard Worker def get_lineno(self): 92*cda5da8dSAndroid Build Coastguard Worker """Return the number of the first line in the 93*cda5da8dSAndroid Build Coastguard Worker block for the table. 94*cda5da8dSAndroid Build Coastguard Worker """ 95*cda5da8dSAndroid Build Coastguard Worker return self._table.lineno 96*cda5da8dSAndroid Build Coastguard Worker 97*cda5da8dSAndroid Build Coastguard Worker def is_optimized(self): 98*cda5da8dSAndroid Build Coastguard Worker """Return *True* if the locals in the table 99*cda5da8dSAndroid Build Coastguard Worker are optimizable. 100*cda5da8dSAndroid Build Coastguard Worker """ 101*cda5da8dSAndroid Build Coastguard Worker return bool(self._table.type == _symtable.TYPE_FUNCTION) 102*cda5da8dSAndroid Build Coastguard Worker 103*cda5da8dSAndroid Build Coastguard Worker def is_nested(self): 104*cda5da8dSAndroid Build Coastguard Worker """Return *True* if the block is a nested class 105*cda5da8dSAndroid Build Coastguard Worker or function.""" 106*cda5da8dSAndroid Build Coastguard Worker return bool(self._table.nested) 107*cda5da8dSAndroid Build Coastguard Worker 108*cda5da8dSAndroid Build Coastguard Worker def has_children(self): 109*cda5da8dSAndroid Build Coastguard Worker """Return *True* if the block has nested namespaces. 110*cda5da8dSAndroid Build Coastguard Worker """ 111*cda5da8dSAndroid Build Coastguard Worker return bool(self._table.children) 112*cda5da8dSAndroid Build Coastguard Worker 113*cda5da8dSAndroid Build Coastguard Worker def get_identifiers(self): 114*cda5da8dSAndroid Build Coastguard Worker """Return a view object containing the names of symbols in the table. 115*cda5da8dSAndroid Build Coastguard Worker """ 116*cda5da8dSAndroid Build Coastguard Worker return self._table.symbols.keys() 117*cda5da8dSAndroid Build Coastguard Worker 118*cda5da8dSAndroid Build Coastguard Worker def lookup(self, name): 119*cda5da8dSAndroid Build Coastguard Worker """Lookup a *name* in the table. 120*cda5da8dSAndroid Build Coastguard Worker 121*cda5da8dSAndroid Build Coastguard Worker Returns a *Symbol* instance. 122*cda5da8dSAndroid Build Coastguard Worker """ 123*cda5da8dSAndroid Build Coastguard Worker sym = self._symbols.get(name) 124*cda5da8dSAndroid Build Coastguard Worker if sym is None: 125*cda5da8dSAndroid Build Coastguard Worker flags = self._table.symbols[name] 126*cda5da8dSAndroid Build Coastguard Worker namespaces = self.__check_children(name) 127*cda5da8dSAndroid Build Coastguard Worker module_scope = (self._table.name == "top") 128*cda5da8dSAndroid Build Coastguard Worker sym = self._symbols[name] = Symbol(name, flags, namespaces, 129*cda5da8dSAndroid Build Coastguard Worker module_scope=module_scope) 130*cda5da8dSAndroid Build Coastguard Worker return sym 131*cda5da8dSAndroid Build Coastguard Worker 132*cda5da8dSAndroid Build Coastguard Worker def get_symbols(self): 133*cda5da8dSAndroid Build Coastguard Worker """Return a list of *Symbol* instances for 134*cda5da8dSAndroid Build Coastguard Worker names in the table. 135*cda5da8dSAndroid Build Coastguard Worker """ 136*cda5da8dSAndroid Build Coastguard Worker return [self.lookup(ident) for ident in self.get_identifiers()] 137*cda5da8dSAndroid Build Coastguard Worker 138*cda5da8dSAndroid Build Coastguard Worker def __check_children(self, name): 139*cda5da8dSAndroid Build Coastguard Worker return [_newSymbolTable(st, self._filename) 140*cda5da8dSAndroid Build Coastguard Worker for st in self._table.children 141*cda5da8dSAndroid Build Coastguard Worker if st.name == name] 142*cda5da8dSAndroid Build Coastguard Worker 143*cda5da8dSAndroid Build Coastguard Worker def get_children(self): 144*cda5da8dSAndroid Build Coastguard Worker """Return a list of the nested symbol tables. 145*cda5da8dSAndroid Build Coastguard Worker """ 146*cda5da8dSAndroid Build Coastguard Worker return [_newSymbolTable(st, self._filename) 147*cda5da8dSAndroid Build Coastguard Worker for st in self._table.children] 148*cda5da8dSAndroid Build Coastguard Worker 149*cda5da8dSAndroid Build Coastguard Worker 150*cda5da8dSAndroid Build Coastguard Workerclass Function(SymbolTable): 151*cda5da8dSAndroid Build Coastguard Worker 152*cda5da8dSAndroid Build Coastguard Worker # Default values for instance variables 153*cda5da8dSAndroid Build Coastguard Worker __params = None 154*cda5da8dSAndroid Build Coastguard Worker __locals = None 155*cda5da8dSAndroid Build Coastguard Worker __frees = None 156*cda5da8dSAndroid Build Coastguard Worker __globals = None 157*cda5da8dSAndroid Build Coastguard Worker __nonlocals = None 158*cda5da8dSAndroid Build Coastguard Worker 159*cda5da8dSAndroid Build Coastguard Worker def __idents_matching(self, test_func): 160*cda5da8dSAndroid Build Coastguard Worker return tuple(ident for ident in self.get_identifiers() 161*cda5da8dSAndroid Build Coastguard Worker if test_func(self._table.symbols[ident])) 162*cda5da8dSAndroid Build Coastguard Worker 163*cda5da8dSAndroid Build Coastguard Worker def get_parameters(self): 164*cda5da8dSAndroid Build Coastguard Worker """Return a tuple of parameters to the function. 165*cda5da8dSAndroid Build Coastguard Worker """ 166*cda5da8dSAndroid Build Coastguard Worker if self.__params is None: 167*cda5da8dSAndroid Build Coastguard Worker self.__params = self.__idents_matching(lambda x:x & DEF_PARAM) 168*cda5da8dSAndroid Build Coastguard Worker return self.__params 169*cda5da8dSAndroid Build Coastguard Worker 170*cda5da8dSAndroid Build Coastguard Worker def get_locals(self): 171*cda5da8dSAndroid Build Coastguard Worker """Return a tuple of locals in the function. 172*cda5da8dSAndroid Build Coastguard Worker """ 173*cda5da8dSAndroid Build Coastguard Worker if self.__locals is None: 174*cda5da8dSAndroid Build Coastguard Worker locs = (LOCAL, CELL) 175*cda5da8dSAndroid Build Coastguard Worker test = lambda x: ((x >> SCOPE_OFF) & SCOPE_MASK) in locs 176*cda5da8dSAndroid Build Coastguard Worker self.__locals = self.__idents_matching(test) 177*cda5da8dSAndroid Build Coastguard Worker return self.__locals 178*cda5da8dSAndroid Build Coastguard Worker 179*cda5da8dSAndroid Build Coastguard Worker def get_globals(self): 180*cda5da8dSAndroid Build Coastguard Worker """Return a tuple of globals in the function. 181*cda5da8dSAndroid Build Coastguard Worker """ 182*cda5da8dSAndroid Build Coastguard Worker if self.__globals is None: 183*cda5da8dSAndroid Build Coastguard Worker glob = (GLOBAL_IMPLICIT, GLOBAL_EXPLICIT) 184*cda5da8dSAndroid Build Coastguard Worker test = lambda x:((x >> SCOPE_OFF) & SCOPE_MASK) in glob 185*cda5da8dSAndroid Build Coastguard Worker self.__globals = self.__idents_matching(test) 186*cda5da8dSAndroid Build Coastguard Worker return self.__globals 187*cda5da8dSAndroid Build Coastguard Worker 188*cda5da8dSAndroid Build Coastguard Worker def get_nonlocals(self): 189*cda5da8dSAndroid Build Coastguard Worker """Return a tuple of nonlocals in the function. 190*cda5da8dSAndroid Build Coastguard Worker """ 191*cda5da8dSAndroid Build Coastguard Worker if self.__nonlocals is None: 192*cda5da8dSAndroid Build Coastguard Worker self.__nonlocals = self.__idents_matching(lambda x:x & DEF_NONLOCAL) 193*cda5da8dSAndroid Build Coastguard Worker return self.__nonlocals 194*cda5da8dSAndroid Build Coastguard Worker 195*cda5da8dSAndroid Build Coastguard Worker def get_frees(self): 196*cda5da8dSAndroid Build Coastguard Worker """Return a tuple of free variables in the function. 197*cda5da8dSAndroid Build Coastguard Worker """ 198*cda5da8dSAndroid Build Coastguard Worker if self.__frees is None: 199*cda5da8dSAndroid Build Coastguard Worker is_free = lambda x:((x >> SCOPE_OFF) & SCOPE_MASK) == FREE 200*cda5da8dSAndroid Build Coastguard Worker self.__frees = self.__idents_matching(is_free) 201*cda5da8dSAndroid Build Coastguard Worker return self.__frees 202*cda5da8dSAndroid Build Coastguard Worker 203*cda5da8dSAndroid Build Coastguard Worker 204*cda5da8dSAndroid Build Coastguard Workerclass Class(SymbolTable): 205*cda5da8dSAndroid Build Coastguard Worker 206*cda5da8dSAndroid Build Coastguard Worker __methods = None 207*cda5da8dSAndroid Build Coastguard Worker 208*cda5da8dSAndroid Build Coastguard Worker def get_methods(self): 209*cda5da8dSAndroid Build Coastguard Worker """Return a tuple of methods declared in the class. 210*cda5da8dSAndroid Build Coastguard Worker """ 211*cda5da8dSAndroid Build Coastguard Worker if self.__methods is None: 212*cda5da8dSAndroid Build Coastguard Worker d = {} 213*cda5da8dSAndroid Build Coastguard Worker for st in self._table.children: 214*cda5da8dSAndroid Build Coastguard Worker d[st.name] = 1 215*cda5da8dSAndroid Build Coastguard Worker self.__methods = tuple(d) 216*cda5da8dSAndroid Build Coastguard Worker return self.__methods 217*cda5da8dSAndroid Build Coastguard Worker 218*cda5da8dSAndroid Build Coastguard Worker 219*cda5da8dSAndroid Build Coastguard Workerclass Symbol: 220*cda5da8dSAndroid Build Coastguard Worker 221*cda5da8dSAndroid Build Coastguard Worker def __init__(self, name, flags, namespaces=None, *, module_scope=False): 222*cda5da8dSAndroid Build Coastguard Worker self.__name = name 223*cda5da8dSAndroid Build Coastguard Worker self.__flags = flags 224*cda5da8dSAndroid Build Coastguard Worker self.__scope = (flags >> SCOPE_OFF) & SCOPE_MASK # like PyST_GetScope() 225*cda5da8dSAndroid Build Coastguard Worker self.__namespaces = namespaces or () 226*cda5da8dSAndroid Build Coastguard Worker self.__module_scope = module_scope 227*cda5da8dSAndroid Build Coastguard Worker 228*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 229*cda5da8dSAndroid Build Coastguard Worker return "<symbol {0!r}>".format(self.__name) 230*cda5da8dSAndroid Build Coastguard Worker 231*cda5da8dSAndroid Build Coastguard Worker def get_name(self): 232*cda5da8dSAndroid Build Coastguard Worker """Return a name of a symbol. 233*cda5da8dSAndroid Build Coastguard Worker """ 234*cda5da8dSAndroid Build Coastguard Worker return self.__name 235*cda5da8dSAndroid Build Coastguard Worker 236*cda5da8dSAndroid Build Coastguard Worker def is_referenced(self): 237*cda5da8dSAndroid Build Coastguard Worker """Return *True* if the symbol is used in 238*cda5da8dSAndroid Build Coastguard Worker its block. 239*cda5da8dSAndroid Build Coastguard Worker """ 240*cda5da8dSAndroid Build Coastguard Worker return bool(self.__flags & _symtable.USE) 241*cda5da8dSAndroid Build Coastguard Worker 242*cda5da8dSAndroid Build Coastguard Worker def is_parameter(self): 243*cda5da8dSAndroid Build Coastguard Worker """Return *True* if the symbol is a parameter. 244*cda5da8dSAndroid Build Coastguard Worker """ 245*cda5da8dSAndroid Build Coastguard Worker return bool(self.__flags & DEF_PARAM) 246*cda5da8dSAndroid Build Coastguard Worker 247*cda5da8dSAndroid Build Coastguard Worker def is_global(self): 248*cda5da8dSAndroid Build Coastguard Worker """Return *True* if the symbol is global. 249*cda5da8dSAndroid Build Coastguard Worker """ 250*cda5da8dSAndroid Build Coastguard Worker return bool(self.__scope in (GLOBAL_IMPLICIT, GLOBAL_EXPLICIT) 251*cda5da8dSAndroid Build Coastguard Worker or (self.__module_scope and self.__flags & DEF_BOUND)) 252*cda5da8dSAndroid Build Coastguard Worker 253*cda5da8dSAndroid Build Coastguard Worker def is_nonlocal(self): 254*cda5da8dSAndroid Build Coastguard Worker """Return *True* if the symbol is nonlocal.""" 255*cda5da8dSAndroid Build Coastguard Worker return bool(self.__flags & DEF_NONLOCAL) 256*cda5da8dSAndroid Build Coastguard Worker 257*cda5da8dSAndroid Build Coastguard Worker def is_declared_global(self): 258*cda5da8dSAndroid Build Coastguard Worker """Return *True* if the symbol is declared global 259*cda5da8dSAndroid Build Coastguard Worker with a global statement.""" 260*cda5da8dSAndroid Build Coastguard Worker return bool(self.__scope == GLOBAL_EXPLICIT) 261*cda5da8dSAndroid Build Coastguard Worker 262*cda5da8dSAndroid Build Coastguard Worker def is_local(self): 263*cda5da8dSAndroid Build Coastguard Worker """Return *True* if the symbol is local. 264*cda5da8dSAndroid Build Coastguard Worker """ 265*cda5da8dSAndroid Build Coastguard Worker return bool(self.__scope in (LOCAL, CELL) 266*cda5da8dSAndroid Build Coastguard Worker or (self.__module_scope and self.__flags & DEF_BOUND)) 267*cda5da8dSAndroid Build Coastguard Worker 268*cda5da8dSAndroid Build Coastguard Worker def is_annotated(self): 269*cda5da8dSAndroid Build Coastguard Worker """Return *True* if the symbol is annotated. 270*cda5da8dSAndroid Build Coastguard Worker """ 271*cda5da8dSAndroid Build Coastguard Worker return bool(self.__flags & DEF_ANNOT) 272*cda5da8dSAndroid Build Coastguard Worker 273*cda5da8dSAndroid Build Coastguard Worker def is_free(self): 274*cda5da8dSAndroid Build Coastguard Worker """Return *True* if a referenced symbol is 275*cda5da8dSAndroid Build Coastguard Worker not assigned to. 276*cda5da8dSAndroid Build Coastguard Worker """ 277*cda5da8dSAndroid Build Coastguard Worker return bool(self.__scope == FREE) 278*cda5da8dSAndroid Build Coastguard Worker 279*cda5da8dSAndroid Build Coastguard Worker def is_imported(self): 280*cda5da8dSAndroid Build Coastguard Worker """Return *True* if the symbol is created from 281*cda5da8dSAndroid Build Coastguard Worker an import statement. 282*cda5da8dSAndroid Build Coastguard Worker """ 283*cda5da8dSAndroid Build Coastguard Worker return bool(self.__flags & DEF_IMPORT) 284*cda5da8dSAndroid Build Coastguard Worker 285*cda5da8dSAndroid Build Coastguard Worker def is_assigned(self): 286*cda5da8dSAndroid Build Coastguard Worker """Return *True* if a symbol is assigned to.""" 287*cda5da8dSAndroid Build Coastguard Worker return bool(self.__flags & DEF_LOCAL) 288*cda5da8dSAndroid Build Coastguard Worker 289*cda5da8dSAndroid Build Coastguard Worker def is_namespace(self): 290*cda5da8dSAndroid Build Coastguard Worker """Returns *True* if name binding introduces new namespace. 291*cda5da8dSAndroid Build Coastguard Worker 292*cda5da8dSAndroid Build Coastguard Worker If the name is used as the target of a function or class 293*cda5da8dSAndroid Build Coastguard Worker statement, this will be true. 294*cda5da8dSAndroid Build Coastguard Worker 295*cda5da8dSAndroid Build Coastguard Worker Note that a single name can be bound to multiple objects. If 296*cda5da8dSAndroid Build Coastguard Worker is_namespace() is true, the name may also be bound to other 297*cda5da8dSAndroid Build Coastguard Worker objects, like an int or list, that does not introduce a new 298*cda5da8dSAndroid Build Coastguard Worker namespace. 299*cda5da8dSAndroid Build Coastguard Worker """ 300*cda5da8dSAndroid Build Coastguard Worker return bool(self.__namespaces) 301*cda5da8dSAndroid Build Coastguard Worker 302*cda5da8dSAndroid Build Coastguard Worker def get_namespaces(self): 303*cda5da8dSAndroid Build Coastguard Worker """Return a list of namespaces bound to this name""" 304*cda5da8dSAndroid Build Coastguard Worker return self.__namespaces 305*cda5da8dSAndroid Build Coastguard Worker 306*cda5da8dSAndroid Build Coastguard Worker def get_namespace(self): 307*cda5da8dSAndroid Build Coastguard Worker """Return the single namespace bound to this name. 308*cda5da8dSAndroid Build Coastguard Worker 309*cda5da8dSAndroid Build Coastguard Worker Raises ValueError if the name is bound to multiple namespaces 310*cda5da8dSAndroid Build Coastguard Worker or no namespace. 311*cda5da8dSAndroid Build Coastguard Worker """ 312*cda5da8dSAndroid Build Coastguard Worker if len(self.__namespaces) == 0: 313*cda5da8dSAndroid Build Coastguard Worker raise ValueError("name is not bound to any namespaces") 314*cda5da8dSAndroid Build Coastguard Worker elif len(self.__namespaces) > 1: 315*cda5da8dSAndroid Build Coastguard Worker raise ValueError("name is bound to multiple namespaces") 316*cda5da8dSAndroid Build Coastguard Worker else: 317*cda5da8dSAndroid Build Coastguard Worker return self.__namespaces[0] 318*cda5da8dSAndroid Build Coastguard Worker 319*cda5da8dSAndroid Build Coastguard Workerif __name__ == "__main__": 320*cda5da8dSAndroid Build Coastguard Worker import os, sys 321*cda5da8dSAndroid Build Coastguard Worker with open(sys.argv[0]) as f: 322*cda5da8dSAndroid Build Coastguard Worker src = f.read() 323*cda5da8dSAndroid Build Coastguard Worker mod = symtable(src, os.path.split(sys.argv[0])[1], "exec") 324*cda5da8dSAndroid Build Coastguard Worker for ident in mod.get_identifiers(): 325*cda5da8dSAndroid Build Coastguard Worker info = mod.lookup(ident) 326*cda5da8dSAndroid Build Coastguard Worker print(info, info.is_local(), info.is_namespace()) 327