# HG changeset patch # User paulb@localhost.localdomain # Date 1164420474 -3600 # Node ID c835a3579518c42182d69756258520b666d4c5c8 # Parent 20e8405a3ee5c4a036c397368234e562ec01ba7f Introduced type "pruning" for names where non-accesses (attribute accesses which fail because a type cannot provide an attribute) rule out types provided by names. diff -r 20e8405a3ee5 -r c835a3579518 annotate.py --- a/annotate.py Sat Nov 25 01:36:18 2006 +0100 +++ b/annotate.py Sat Nov 25 03:07:54 2006 +0100 @@ -301,6 +301,11 @@ if not attributes: if not attr.type in non_accesses: non_accesses.append(attr) + + # Revoke this type from any name involved. + + self._prune_non_accesses(loadattr, attr) + for attribute, accessor in attributes: if attribute is not None: types.append(attribute) @@ -311,6 +316,11 @@ else: if not attr in non_accesses: non_accesses.append(attr) + + # Revoke this type from any name involved. + + self._prune_non_accesses(loadattr, attr) + if not types: print "No attribute found for", loadattr.name, "given", self.namespace.types self.namespace.set_types(types) @@ -319,6 +329,14 @@ self.annotate(loadattr) return loadattr + def _prune_non_accesses(self, loadattr, attr): + if isinstance(loadattr.expr, LoadName): + self.namespace.revoke(loadattr.expr.name, attr) + elif isinstance(loadattr.expr, LoadAttr): + for expr_attr in loadattr.expr.expr.types: + if hasattr(expr_attr.type, "namespace"): + expr_attr.type.namespace.revoke(loadattr.expr.name, attr) + def visitLoadExc(self, loadexc): self.namespace.types = self.namespace.raises[:] self.annotate(loadexc) @@ -848,6 +866,10 @@ __getitem__ = load + def revoke(self, name, type): + print "Revoke", type, "from", name + self.names[name].remove(type) + def merge_namespace(self, namespace): self.merge_items(namespace.names.items()) combine(self.returns, namespace.returns) diff -r 20e8405a3ee5 -r c835a3579518 tests/logical_attr.py --- a/tests/logical_attr.py Sat Nov 25 01:36:18 2006 +0100 +++ b/tests/logical_attr.py Sat Nov 25 03:07:54 2006 +0100 @@ -6,5 +6,7 @@ b = 3.0 class C: c = 4 -a = X() and Y() or B() and not C() +class D(X): + y = True +a = X() and Y() or B() and not C() or D() b = a.x and a.y or a.b and not a.c