1.1 --- a/micropython/inspect.py Sun Oct 21 23:54:45 2007 +0200
1.2 +++ b/micropython/inspect.py Mon Oct 22 01:44:47 2007 +0200
1.3 @@ -67,27 +67,44 @@
1.4 self.parent_name = parent_name
1.5 self.bases = []
1.6 self.namespace = {}
1.7 - self.instattr = set()
1.8 + self.instattr = set() # instance attributes
1.9 self.instattr_names = [] # from instattr
1.10 + self.classattr = None # cache for class_attributes
1.11 + self.classattr_names = [] # from classattr
1.12 + self.allattr = None # cache for all_attributes
1.13 + self.allattr_names = [] # from allattr
1.14 +
1.15 + # Image generation details.
1.16 +
1.17 + self.location = None
1.18
1.19 def add_base(self, base):
1.20 self.bases.append(base)
1.21
1.22 def __repr__(self):
1.23 - return "Class(%r, %r)" % (self.name, self.parent_name)
1.24 + return "Class(%r, %r, location=%r)" % (self.name, self.parent_name, self.location)
1.25 +
1.26 + def class_attribute_names(self):
1.27 +
1.28 + "Return the attribute names provided by the class."
1.29 +
1.30 + self.classattr_names = self.classattr_names or self.class_attributes().keys()
1.31 + return self.classattr_names
1.32
1.33 def class_attributes(self):
1.34
1.35 "Return all class attributes, indicating the class which provides them."
1.36
1.37 - attr = {}
1.38 - reversed_bases = self.bases[:]
1.39 - reversed_bases.reverse()
1.40 - for cls in reversed_bases:
1.41 - attr.update(cls.class_attributes())
1.42 - for name, value in self.namespace.items():
1.43 - attr[name] = self.full_name()
1.44 - return attr
1.45 + if self.classattr is None:
1.46 + self.classattr = {}
1.47 + reversed_bases = self.bases[:]
1.48 + reversed_bases.reverse()
1.49 + for cls in reversed_bases:
1.50 + self.classattr.update(cls.class_attributes())
1.51 + for name, value in self.namespace.items():
1.52 + self.classattr[name] = value
1.53 +
1.54 + return self.classattr
1.55
1.56 def instance_attribute_names(self):
1.57
1.58 @@ -98,18 +115,34 @@
1.59
1.60 def instance_attributes(self):
1.61
1.62 + "Return instance-only attributes for instances of this class."
1.63 +
1.64 + return self.instattr
1.65 +
1.66 + def all_attribute_names(self):
1.67 +
1.68 + """
1.69 + Return the names of all attributes provided by instances of this class.
1.70 + """
1.71 +
1.72 + self.allattr_names = self.allattr_names or self.all_attributes().keys()
1.73 + return self.allattr_names
1.74 +
1.75 + def all_attributes(self):
1.76 +
1.77 """
1.78 Return all attributes for an instance, indicating either the class which
1.79 provides them or that the instance itself provides them.
1.80 """
1.81
1.82 - attr = {}
1.83 - attr.update(self.class_attributes())
1.84 - for i, name in enumerate(self.instance_attribute_names()):
1.85 - if attr.has_key(name):
1.86 - print "Instance attribute %r in %r overrides class attribute." % (name, self)
1.87 - attr[name] = i
1.88 - return attr
1.89 + if self.allattr is None:
1.90 + self.allattr = {}
1.91 + self.allattr.update(self.class_attributes())
1.92 + for i, name in enumerate(self.instance_attribute_names()):
1.93 + if self.allattr.has_key(name):
1.94 + print "Instance attribute %r in %r overrides class attribute." % (name, self)
1.95 + self.allattr[name] = i
1.96 + return self.allattr
1.97
1.98 class Function(Naming):
1.99
1.100 @@ -122,9 +155,13 @@
1.101 self.has_star = has_star
1.102 self.has_dstar = has_dstar
1.103
1.104 + # Image generation details.
1.105 +
1.106 + self.location = None
1.107 +
1.108 def __repr__(self):
1.109 - return "Function(%r, %r, %r, %r, %r)" % (
1.110 - self.name, self.parent_name, self.argnames, self.has_star, self.has_dstar
1.111 + return "Function(%r, %r, %r, %r, %r, location=%r)" % (
1.112 + self.name, self.parent_name, self.argnames, self.has_star, self.has_dstar, self.location
1.113 )
1.114
1.115 def parameters(self):
1.116 @@ -186,11 +223,21 @@
1.117 self.classes = []
1.118 self.module = None
1.119
1.120 + # Image generation details.
1.121 +
1.122 + self.location = None
1.123 +
1.124 def parse(self, filename):
1.125 +
1.126 + "Parse the file having the given 'filename'."
1.127 +
1.128 module = compiler.parseFile(filename)
1.129 self.process(module)
1.130
1.131 def process(self, module):
1.132 +
1.133 + "Process the given 'module'."
1.134 +
1.135 self.module = module
1.136 processed = self.dispatch(module)
1.137 if self.namespace.has_key("__all__"):
1.138 @@ -201,6 +248,9 @@
1.139 return processed
1.140
1.141 def vacuum(self):
1.142 +
1.143 + "Vacuum the module namespace, removing unloaded module references."
1.144 +
1.145 for name, value in self.namespace.items():
1.146 if isinstance(value, Module) and not value.loaded:
1.147 del self.namespace[name]
1.148 @@ -209,7 +259,7 @@
1.149 return self.name
1.150
1.151 def __repr__(self):
1.152 - return "Module(%r)" % self.name
1.153 + return "Module(%r, location=%r)" % (self.name, self.location)
1.154
1.155 # Attribute methods.
1.156
1.157 @@ -222,15 +272,9 @@
1.158
1.159 def module_attributes(self):
1.160
1.161 - """
1.162 - Return a dictionary mapping module attributes to a position in the
1.163 - module's namespace.
1.164 - """
1.165 + "Return a dictionary mapping names to module attributes."
1.166
1.167 - attributes = {}
1.168 - for i, name in enumerate(self.module_attribute_names()):
1.169 - attributes[name] = i
1.170 - return attributes
1.171 + return self.namespace
1.172
1.173 # Namespace methods.
1.174