# HG changeset patch # User Paul Boddie # Date 1193093849 -7200 # Node ID 2675f922e209c9b353ed8fd6acb756527b0b0c78 # Parent 24aa66f88d9becd84c078060b4af9fcd2f53d4fb Added an Attr class which represents an attribute entry in a class, module or instance, providing position information about the attribute within its parent and encapsulating other knowledge about the attribute. Changed attribute name list generation for class and module attributes, defining such lists in the attribute gathering methods. Changed image generation to include attributes (as Attr objects) literally. diff -r 24aa66f88d9b -r 2675f922e209 micropython/__init__.py --- a/micropython/__init__.py Mon Oct 22 01:44:47 2007 +0200 +++ b/micropython/__init__.py Tue Oct 23 00:57:29 2007 +0200 @@ -84,10 +84,7 @@ for name in module.module_attribute_names(): attr = attributes[name] - if isinstance(attr, (micropython.inspect.Class, micropython.inspect.Module, micropython.inspect.Function)): - image.append(attr) - else: - image.append(None) + image.append(attr) pos += 1 for obj in module.all_objects: @@ -96,10 +93,7 @@ attributes = obj.class_attributes() for name in obj.class_attribute_names(): attr = attributes[name] - if isinstance(attr, (micropython.inspect.Class, micropython.inspect.Module, micropython.inspect.Function)): - image.append(attr) - else: - image.append(None) + image.append(attr) pos += 1 # NOTE: Generate module and function code here. diff -r 24aa66f88d9b -r 2675f922e209 micropython/inspect.py --- a/micropython/inspect.py Mon Oct 22 01:44:47 2007 +0200 +++ b/micropython/inspect.py Tue Oct 23 00:57:29 2007 +0200 @@ -58,6 +58,18 @@ else: return self.parent_name +class Attr: + + "An attribute entry." + + def __init__(self, position, parent, value=None): + self.position = position + self.parent = parent + self.value = value + + def __repr__(self): + return "Attr(%d, %r, %r)" % (self.position, self.parent, self.value) + class Class(NamespaceDict, Naming): "An inspected class." @@ -70,9 +82,9 @@ self.instattr = set() # instance attributes self.instattr_names = [] # from instattr self.classattr = None # cache for class_attributes - self.classattr_names = [] # from classattr + self.classattr_names = None # from classattr self.allattr = None # cache for all_attributes - self.allattr_names = [] # from allattr + self.allattr_names = None # from allattr # Image generation details. @@ -88,7 +100,8 @@ "Return the attribute names provided by the class." - self.classattr_names = self.classattr_names or self.class_attributes().keys() + if self.classattr_names is None: + self.class_attributes() return self.classattr_names def class_attributes(self): @@ -97,12 +110,18 @@ if self.classattr is None: self.classattr = {} + self.classattr_names = self.namespace.keys() + reversed_bases = self.bases[:] reversed_bases.reverse() for cls in reversed_bases: self.classattr.update(cls.class_attributes()) - for name, value in self.namespace.items(): - self.classattr[name] = value + + # Record attributes provided by this class, along with their + # positions. + + for i, name in enumerate(self.classattr_names): + self.classattr[name] = Attr(i, self, self.namespace[name]) return self.classattr @@ -141,7 +160,7 @@ for i, name in enumerate(self.instance_attribute_names()): if self.allattr.has_key(name): print "Instance attribute %r in %r overrides class attribute." % (name, self) - self.allattr[name] = i + self.allattr[name] = Attr(i, None) return self.allattr class Function(Naming): @@ -208,6 +227,11 @@ self.namespace = {} self.namespace_names = [] # from namespace + # Module attributes. + + self.modattr = None # cache for module_attributes + self.modattr_names = None # from modattr + # Complete lists of classes and functions. self.all_objects = [] @@ -267,14 +291,21 @@ "Return the module attribute names provided by the module." - self.namespace_names = self.namespace_names or self.namespace.keys() - return self.namespace_names + if self.modattr_names is None: + self.module_attributes() + return self.modattr_names def module_attributes(self): "Return a dictionary mapping names to module attributes." - return self.namespace + if self.modattr is None: + self.modattr = {} + self.modattr_names = self.namespace.keys() + for i, name in enumerate(self.modattr_names): + self.modattr[name] = Attr(i, self, self.namespace[name]) + + return self.modattr # Namespace methods.