1.1 --- a/micropython/inspect.py Mon Oct 22 01:44:47 2007 +0200
1.2 +++ b/micropython/inspect.py Tue Oct 23 00:57:29 2007 +0200
1.3 @@ -58,6 +58,18 @@
1.4 else:
1.5 return self.parent_name
1.6
1.7 +class Attr:
1.8 +
1.9 + "An attribute entry."
1.10 +
1.11 + def __init__(self, position, parent, value=None):
1.12 + self.position = position
1.13 + self.parent = parent
1.14 + self.value = value
1.15 +
1.16 + def __repr__(self):
1.17 + return "Attr(%d, %r, %r)" % (self.position, self.parent, self.value)
1.18 +
1.19 class Class(NamespaceDict, Naming):
1.20
1.21 "An inspected class."
1.22 @@ -70,9 +82,9 @@
1.23 self.instattr = set() # instance attributes
1.24 self.instattr_names = [] # from instattr
1.25 self.classattr = None # cache for class_attributes
1.26 - self.classattr_names = [] # from classattr
1.27 + self.classattr_names = None # from classattr
1.28 self.allattr = None # cache for all_attributes
1.29 - self.allattr_names = [] # from allattr
1.30 + self.allattr_names = None # from allattr
1.31
1.32 # Image generation details.
1.33
1.34 @@ -88,7 +100,8 @@
1.35
1.36 "Return the attribute names provided by the class."
1.37
1.38 - self.classattr_names = self.classattr_names or self.class_attributes().keys()
1.39 + if self.classattr_names is None:
1.40 + self.class_attributes()
1.41 return self.classattr_names
1.42
1.43 def class_attributes(self):
1.44 @@ -97,12 +110,18 @@
1.45
1.46 if self.classattr is None:
1.47 self.classattr = {}
1.48 + self.classattr_names = self.namespace.keys()
1.49 +
1.50 reversed_bases = self.bases[:]
1.51 reversed_bases.reverse()
1.52 for cls in reversed_bases:
1.53 self.classattr.update(cls.class_attributes())
1.54 - for name, value in self.namespace.items():
1.55 - self.classattr[name] = value
1.56 +
1.57 + # Record attributes provided by this class, along with their
1.58 + # positions.
1.59 +
1.60 + for i, name in enumerate(self.classattr_names):
1.61 + self.classattr[name] = Attr(i, self, self.namespace[name])
1.62
1.63 return self.classattr
1.64
1.65 @@ -141,7 +160,7 @@
1.66 for i, name in enumerate(self.instance_attribute_names()):
1.67 if self.allattr.has_key(name):
1.68 print "Instance attribute %r in %r overrides class attribute." % (name, self)
1.69 - self.allattr[name] = i
1.70 + self.allattr[name] = Attr(i, None)
1.71 return self.allattr
1.72
1.73 class Function(Naming):
1.74 @@ -208,6 +227,11 @@
1.75 self.namespace = {}
1.76 self.namespace_names = [] # from namespace
1.77
1.78 + # Module attributes.
1.79 +
1.80 + self.modattr = None # cache for module_attributes
1.81 + self.modattr_names = None # from modattr
1.82 +
1.83 # Complete lists of classes and functions.
1.84
1.85 self.all_objects = []
1.86 @@ -267,14 +291,21 @@
1.87
1.88 "Return the module attribute names provided by the module."
1.89
1.90 - self.namespace_names = self.namespace_names or self.namespace.keys()
1.91 - return self.namespace_names
1.92 + if self.modattr_names is None:
1.93 + self.module_attributes()
1.94 + return self.modattr_names
1.95
1.96 def module_attributes(self):
1.97
1.98 "Return a dictionary mapping names to module attributes."
1.99
1.100 - return self.namespace
1.101 + if self.modattr is None:
1.102 + self.modattr = {}
1.103 + self.modattr_names = self.namespace.keys()
1.104 + for i, name in enumerate(self.modattr_names):
1.105 + self.modattr[name] = Attr(i, self, self.namespace[name])
1.106 +
1.107 + return self.modattr
1.108
1.109 # Namespace methods.
1.110