2.1 --- a/micropython/inspect.py Wed Oct 17 01:31:33 2007 +0200
2.2 +++ b/micropython/inspect.py Sat Oct 20 01:36:44 2007 +0200
2.3 @@ -32,7 +32,17 @@
2.4
2.5 pass
2.6
2.7 -class Class:
2.8 +class NamespaceDict:
2.9 +
2.10 + "A mix-in providing dictionary methods."
2.11 +
2.12 + def __getitem__(self, name):
2.13 + return self.namespace[name]
2.14 +
2.15 + def keys(self):
2.16 + return self.namespace.keys()
2.17 +
2.18 +class Class(NamespaceDict):
2.19
2.20 "An inspected class."
2.21
2.22 @@ -45,14 +55,26 @@
2.23 def add_base(self, base):
2.24 self.bases.append(base)
2.25
2.26 -class Function:
2.27 +class Function(NamespaceDict):
2.28
2.29 "An inspected function."
2.30
2.31 + def __init__(self, name, argnames, has_star, has_dstar):
2.32 + self.name = name
2.33 + self.argnames = argnames
2.34 + self.has_star = has_star
2.35 + self.has_dstar = has_dstar
2.36 + self.namespace = {}
2.37 +
2.38 +class UnresolvedName(NamespaceDict):
2.39 +
2.40 + "A module, class or function which was mentioned but could not be imported."
2.41 +
2.42 def __init__(self, name):
2.43 self.name = name
2.44 + self.namespace = {}
2.45
2.46 -class Module(ASTVisitor):
2.47 +class Module(ASTVisitor, NamespaceDict):
2.48
2.49 "An inspected module."
2.50
2.51 @@ -67,7 +89,6 @@
2.52 # Module namespace.
2.53
2.54 self.namespace = {}
2.55 - self.namespace.update(builtins_namespace)
2.56
2.57 # Current expression state.
2.58
2.59 @@ -94,11 +115,12 @@
2.60 self.namespace[n.value] = self.importer.add_module(self.name + "." + n.value)
2.61 return processed
2.62
2.63 - def default(self, node, *args):
2.64 - raise InspectError, node.__class__
2.65 + def vacuum(self):
2.66 + for name, value in self.namespace.items():
2.67 + if isinstance(value, Module) and not value.loaded:
2.68 + del self.namespace[name]
2.69
2.70 - def dispatch(self, node, *args):
2.71 - return ASTVisitor.dispatch(self, node, *args)
2.72 + # Namespace methods.
2.73
2.74 def store(self, name, obj):
2.75 if self.in_global:
2.76 @@ -111,6 +133,14 @@
2.77 if self.in_init:
2.78 self.classes[-1].instattr.add(name)
2.79
2.80 + # Visitor methods.
2.81 +
2.82 + def default(self, node, *args):
2.83 + raise InspectError, node.__class__
2.84 +
2.85 + def dispatch(self, node, *args):
2.86 + return ASTVisitor.dispatch(self, node, *args)
2.87 +
2.88 def NOP(self, node):
2.89 return node
2.90
2.91 @@ -186,23 +216,31 @@
2.92
2.93 if module is None:
2.94 print "Warning:", node.modname, "not imported."
2.95 - return None
2.96
2.97 for name, alias in node.names:
2.98 if name != "*":
2.99 - self.namespace[alias or name] = attr = module.namespace[name]
2.100 - if isinstance(attr, Module) and not attr.loaded:
2.101 - self.importer.load(attr.name)
2.102 - else:
2.103 - for n in module.namespace.keys():
2.104 - self.namespace[n] = attr = module.namespace[n]
2.105 + if module is not None:
2.106 + self.namespace[alias or name] = attr = module.namespace[name]
2.107 if isinstance(attr, Module) and not attr.loaded:
2.108 self.importer.load(attr.name)
2.109 + else:
2.110 + self.namespace[alias or name] = UnresolvedName(name)
2.111 + else:
2.112 + if module is not None:
2.113 + for n in module.namespace.keys():
2.114 + self.namespace[n] = attr = module.namespace[n]
2.115 + if isinstance(attr, Module) and not attr.loaded:
2.116 + self.importer.load(attr.name)
2.117
2.118 return None
2.119
2.120 def visitFunction(self, node):
2.121 - self.store(node.name, Function(node.name))
2.122 + function = Function(
2.123 + node.name,
2.124 + node.argnames,
2.125 + has_star=(node.flags & 4 != 0),
2.126 + has_dstar=(node.flags & 8 != 0)
2.127 + )
2.128
2.129 in_global = self.in_global
2.130 self.in_global = 0
2.131 @@ -211,6 +249,8 @@
2.132 self.dispatch(node.code)
2.133 self.in_init = 0
2.134 self.in_global = in_global
2.135 +
2.136 + self.store(node.name, function)
2.137 return None
2.138
2.139 def visitGetattr(self, node):
2.140 @@ -218,7 +258,7 @@
2.141 if expr is not None and isinstance(expr, Module):
2.142 return expr.namespace.get(node.attrname)
2.143 else:
2.144 - return None
2.145 + return builtins_namespace.get(node.attrname)
2.146
2.147 def visitIf(self, node):
2.148 for test, body in node.tests:
2.149 @@ -248,12 +288,16 @@
2.150
2.151 visitMul = NOP
2.152
2.153 + visitMod = NOP
2.154 +
2.155 def visitName(self, node):
2.156 name = node.name
2.157 if name == "self":
2.158 return Self()
2.159 elif self.namespace.has_key(name):
2.160 return self.namespace[name]
2.161 + elif builtins_namespace.has_key(name):
2.162 + return builtins_namespace[name]
2.163 else:
2.164 return None
2.165