1.1 --- a/micropython/data.py Tue Jun 05 01:30:05 2012 +0200
1.2 +++ b/micropython/data.py Tue Jun 05 01:54:54 2012 +0200
1.3 @@ -1303,6 +1303,7 @@
1.4 self.bases = []
1.5 self.descendants = set()
1.6 self.instattr = set() # instance attributes
1.7 + self.instattr_tentative = set() # tentative/suspected instance attributes
1.8 self.relocated = set() # attributes which do not have the same
1.9 # position as those of the same name in
1.10 # some superclasses
1.11 @@ -1446,8 +1447,11 @@
1.12 self.bases.append(base)
1.13 base.add_descendant(self)
1.14
1.15 - def add_instance_attribute(self, name):
1.16 - self.instattr.add(name)
1.17 + def add_instance_attribute(self, name, tentative=False):
1.18 + if tentative:
1.19 + self.instattr_tentative.add(name)
1.20 + else:
1.21 + self.instattr.add(name)
1.22
1.23 def add_descendant(self, cls):
1.24 self.descendants.add(cls)
1.25 @@ -1553,6 +1557,21 @@
1.26
1.27 "Make sure that the instance attributes are fully defined."
1.28
1.29 + # Eliminate tentative instance attributes that are actually class
1.30 + # attributes.
1.31 +
1.32 + for attrname in self.all_class_attributes().keys():
1.33 + if attrname in self.instattr_tentative:
1.34 + self.instattr_tentative.remove(attrname)
1.35 +
1.36 + for cls in self.descendants:
1.37 + for attrname in cls.class_attribute_names():
1.38 + if attrname in self.instattr_tentative:
1.39 + self.instattr_tentative.remove(attrname)
1.40 +
1.41 + for attrname in self.instattr_tentative:
1.42 + self.instattr.add(attrname)
1.43 +
1.44 # Cache the attributes by converting the positioned attributes into a
1.45 # dictionary.
1.46
2.1 --- a/micropython/inspect.py Tue Jun 05 01:30:05 2012 +0200
2.2 +++ b/micropython/inspect.py Tue Jun 05 01:54:54 2012 +0200
2.3 @@ -327,9 +327,13 @@
2.4 cls.set(name, self.expr, 0)
2.5 self.use_specific_attribute(cls.full_name(), name)
2.6
2.7 - def store_instance_attr(self, name):
2.8 + def store_instance_attr(self, name, tentative=False):
2.9
2.10 - "Record instance attribute 'name' in the current class."
2.11 + """
2.12 + Record instance attribute 'name' in the current class. If 'tentative' is
2.13 + set to a true value, the instance attribute will be discarded if a class
2.14 + attribute is observed.
2.15 + """
2.16
2.17 if self.in_method:
2.18
2.19 @@ -337,7 +341,7 @@
2.20 # Previous namespace is the class.
2.21
2.22 cls = self.namespaces[-2]
2.23 - cls.add_instance_attribute(name)
2.24 + cls.add_instance_attribute(name, tentative)
2.25
2.26 # NOTE: The instance attribute, although defined in a specific
2.27 # NOTE: class, obviously appears in all descendant classes.
2.28 @@ -514,6 +518,12 @@
2.29 # to be an instance.
2.30
2.31 else:
2.32 +
2.33 + # Record any instance attributes.
2.34 +
2.35 + if expr.name == "self":
2.36 + self.store_instance_attr(attrname, tentative=True)
2.37 +
2.38 attr = make_instance()
2.39
2.40 # Note usage of the attribute where a local is involved.