1.1 --- a/annotate.py Sun Jan 21 00:17:09 2007 +0100
1.2 +++ b/annotate.py Sun Jan 21 00:17:44 2007 +0100
1.3 @@ -539,7 +539,7 @@
1.4 if not attributes:
1.5 if not attr in non_accesses:
1.6 non_accesses.append(attr)
1.7 - combine(self.namespace.raises, self.get_builtin_instances("AttributeError"))
1.8 + combine(self.namespace.raises, self.get_builtin_instances(loadattr, "AttributeError"))
1.9
1.10 # Revoke this type from any name involved.
1.11
1.12 @@ -555,7 +555,7 @@
1.13 else:
1.14 if not attr in non_accesses:
1.15 non_accesses.append(attr)
1.16 - combine(self.namespace.raises, self.get_builtin_instances("AttributeError"))
1.17 + combine(self.namespace.raises, self.get_builtin_instances(loadattr, "AttributeError"))
1.18
1.19 # Revoke this type from any name involved.
1.20
1.21 @@ -869,8 +869,8 @@
1.22
1.23 # Utility methods.
1.24
1.25 - def get_builtin_instances(self, name):
1.26 - return [Attribute(None, self._new_instance(attr.type)) for attr in self.builtins.namespace[name]]
1.27 + def get_builtin_instances(self, node, name):
1.28 + return [Attribute(None, self._new_instance(node, attr.type)) for attr in self.builtins.namespace[name]]
1.29
1.30 def new_instance(self, node, reason, target, type):
1.31
1.32 @@ -880,23 +880,22 @@
1.33 node.instances = {}
1.34
1.35 if not node.instances.has_key((reason, target, type)):
1.36 - instance = self._new_instance(type)
1.37 + instance = self._new_instance(node, type)
1.38 node.instances[(reason, target, type)] = instance
1.39
1.40 return node.instances[(reason, target, type)]
1.41
1.42 - def _new_instance(self, type):
1.43 + def _new_instance(self, node, type):
1.44
1.45 - # Insist on a single instance per type.
1.46 - # NOTE: Strategy-dependent instantiation.
1.47 + "For the given 'node', obtain an instance from the given 'type'."
1.48
1.49 - if len(type.instances) == 0:
1.50 + if not type.has_instance(node):
1.51 instance = Instance()
1.52 instance.namespace = Namespace()
1.53 instance.namespace.store("__class__", [Attribute(None, type)])
1.54 - type.instances.append(instance)
1.55 + type.add_instance(node, instance)
1.56 else:
1.57 - instance = type.instances[0]
1.58 + instance = type.get_instance(node)
1.59
1.60 return instance
1.61
2.1 --- a/simplified.py Sun Jan 21 00:17:09 2007 +0100
2.2 +++ b/simplified.py Sun Jan 21 00:17:44 2007 +0100
2.3 @@ -405,26 +405,66 @@
2.4
2.5 class Structure(Node): "A non-program node containing some kind of namespace."
2.6
2.7 -class Class(Structure, WithName):
2.8 +class _Class(Structure, WithName):
2.9
2.10 "A Python class."
2.11
2.12 def __init__(self, *args, **kw):
2.13 Structure.__init__(self, *args, **kw)
2.14 WithName.__init__(self)
2.15 - self.instances = []
2.16
2.17 def full_name(self):
2.18 return "class %s" % self._full_name
2.19
2.20 +class SingleInstanceClass(_Class):
2.21 +
2.22 + "A Python class."
2.23 +
2.24 + def __init__(self, *args, **kw):
2.25 + _Class.__init__(self, *args, **kw)
2.26 + self.instance = None
2.27 +
2.28 + def has_instance(self, node):
2.29 + return self.instance is not None
2.30 +
2.31 + def add_instance(self, node, instance):
2.32 + self.instance = instance
2.33 +
2.34 + def get_instance(self, node):
2.35 + return self.instance
2.36 +
2.37 + def get_instance_name(self, instance):
2.38 + return self._full_name
2.39 +
2.40 +class MultipleInstanceClass(_Class):
2.41 +
2.42 + "A Python class."
2.43 +
2.44 + def __init__(self, *args, **kw):
2.45 + _Class.__init__(self, *args, **kw)
2.46 + self.instances = {}
2.47 +
2.48 + def has_instance(self, node):
2.49 + key = id(node)
2.50 + return self.instances.has_key(key)
2.51 +
2.52 + def add_instance(self, node, instance):
2.53 + key = id(node)
2.54 + self.instances[key] = instance
2.55 +
2.56 + def get_instance(self, node):
2.57 + key = id(node)
2.58 + return self.instances[key]
2.59 +
2.60 + def get_instance_name(self, instance):
2.61 + return name(instance, self._full_name)
2.62 +
2.63 class Instance(Structure):
2.64
2.65 "An instance."
2.66
2.67 def full_name(self):
2.68 - # NOTE: Wrap the result in a call to name(self, ...) where multiple
2.69 - # NOTE: instances per class can occur.
2.70 - return self.get_class()._full_name
2.71 + return self.get_class().get_instance_name(self)
2.72
2.73 def get_class(self):
2.74 return self.namespace.load("__class__")[0].type
2.75 @@ -433,7 +473,8 @@
2.76 return "Instance of type '%s'" % self.full_name()
2.77
2.78 def __eq__(self, other):
2.79 - # NOTE: Assuming that multiple instances of the same class are equal.
2.80 + # NOTE: Single instance: all instances are the same
2.81 + # NOTE: Multiple instances: all instances are different
2.82 return self.full_name() == other.full_name()
2.83
2.84 def __hash__(self):
2.85 @@ -447,4 +488,17 @@
2.86 Instance.__init__(self, *args, **kw)
2.87 self.typename = self.value.__class__.__name__
2.88
2.89 +# Configuration setting.
2.90 +
2.91 +Class = SingleInstanceClass
2.92 +#Class = MultipleInstanceClass
2.93 +
2.94 +def set_single_instance_mode():
2.95 + global Class
2.96 + Class = SingleInstanceClass
2.97 +
2.98 +def set_multiple_instance_mode():
2.99 + global Class
2.100 + Class = MultipleInstanceClass
2.101 +
2.102 # vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/test.py Sun Jan 21 00:17:09 2007 +0100
3.2 +++ b/test.py Sun Jan 21 00:17:44 2007 +0100
3.3 @@ -1,10 +1,17 @@
3.4 #!/usr/bin/env python
3.5
3.6 -import sys, os
3.7 -import viewer
3.8 -from annotate import AnnotationError, Importer, load
3.9 +if __name__ == "__main__":
3.10 + import sys, os
3.11 +
3.12 + import simplified
3.13
3.14 -if __name__ == "__main__":
3.15 + if "-s" in sys.argv:
3.16 + simplified.set_single_instance_mode()
3.17 + elif "-m" in sys.argv:
3.18 + simplified.set_multiple_instance_mode()
3.19 +
3.20 + import viewer
3.21 + from annotate import AnnotationError, Importer, load
3.22
3.23 importer = Importer(sys.path)
3.24 try: