# HG changeset patch # User paulb@localhost.localdomain # Date 1169335064 -3600 # Node ID dc85db350f87e87bfc252e5d3981c64585114e03 # Parent 6baf47498438bff8dae0c8751601dd7578df8ad6 Added support for choosing single or multiple instances per class. diff -r 6baf47498438 -r dc85db350f87 annotate.py --- a/annotate.py Sun Jan 21 00:17:09 2007 +0100 +++ b/annotate.py Sun Jan 21 00:17:44 2007 +0100 @@ -539,7 +539,7 @@ if not attributes: if not attr in non_accesses: non_accesses.append(attr) - combine(self.namespace.raises, self.get_builtin_instances("AttributeError")) + combine(self.namespace.raises, self.get_builtin_instances(loadattr, "AttributeError")) # Revoke this type from any name involved. @@ -555,7 +555,7 @@ else: if not attr in non_accesses: non_accesses.append(attr) - combine(self.namespace.raises, self.get_builtin_instances("AttributeError")) + combine(self.namespace.raises, self.get_builtin_instances(loadattr, "AttributeError")) # Revoke this type from any name involved. @@ -869,8 +869,8 @@ # Utility methods. - def get_builtin_instances(self, name): - return [Attribute(None, self._new_instance(attr.type)) for attr in self.builtins.namespace[name]] + def get_builtin_instances(self, node, name): + return [Attribute(None, self._new_instance(node, attr.type)) for attr in self.builtins.namespace[name]] def new_instance(self, node, reason, target, type): @@ -880,23 +880,22 @@ node.instances = {} if not node.instances.has_key((reason, target, type)): - instance = self._new_instance(type) + instance = self._new_instance(node, type) node.instances[(reason, target, type)] = instance return node.instances[(reason, target, type)] - def _new_instance(self, type): + def _new_instance(self, node, type): - # Insist on a single instance per type. - # NOTE: Strategy-dependent instantiation. + "For the given 'node', obtain an instance from the given 'type'." - if len(type.instances) == 0: + if not type.has_instance(node): instance = Instance() instance.namespace = Namespace() instance.namespace.store("__class__", [Attribute(None, type)]) - type.instances.append(instance) + type.add_instance(node, instance) else: - instance = type.instances[0] + instance = type.get_instance(node) return instance diff -r 6baf47498438 -r dc85db350f87 simplified.py --- a/simplified.py Sun Jan 21 00:17:09 2007 +0100 +++ b/simplified.py Sun Jan 21 00:17:44 2007 +0100 @@ -405,26 +405,66 @@ class Structure(Node): "A non-program node containing some kind of namespace." -class Class(Structure, WithName): +class _Class(Structure, WithName): "A Python class." def __init__(self, *args, **kw): Structure.__init__(self, *args, **kw) WithName.__init__(self) - self.instances = [] def full_name(self): return "class %s" % self._full_name +class SingleInstanceClass(_Class): + + "A Python class." + + def __init__(self, *args, **kw): + _Class.__init__(self, *args, **kw) + self.instance = None + + def has_instance(self, node): + return self.instance is not None + + def add_instance(self, node, instance): + self.instance = instance + + def get_instance(self, node): + return self.instance + + def get_instance_name(self, instance): + return self._full_name + +class MultipleInstanceClass(_Class): + + "A Python class." + + def __init__(self, *args, **kw): + _Class.__init__(self, *args, **kw) + self.instances = {} + + def has_instance(self, node): + key = id(node) + return self.instances.has_key(key) + + def add_instance(self, node, instance): + key = id(node) + self.instances[key] = instance + + def get_instance(self, node): + key = id(node) + return self.instances[key] + + def get_instance_name(self, instance): + return name(instance, self._full_name) + class Instance(Structure): "An instance." def full_name(self): - # NOTE: Wrap the result in a call to name(self, ...) where multiple - # NOTE: instances per class can occur. - return self.get_class()._full_name + return self.get_class().get_instance_name(self) def get_class(self): return self.namespace.load("__class__")[0].type @@ -433,7 +473,8 @@ return "Instance of type '%s'" % self.full_name() def __eq__(self, other): - # NOTE: Assuming that multiple instances of the same class are equal. + # NOTE: Single instance: all instances are the same + # NOTE: Multiple instances: all instances are different return self.full_name() == other.full_name() def __hash__(self): @@ -447,4 +488,17 @@ Instance.__init__(self, *args, **kw) self.typename = self.value.__class__.__name__ +# Configuration setting. + +Class = SingleInstanceClass +#Class = MultipleInstanceClass + +def set_single_instance_mode(): + global Class + Class = SingleInstanceClass + +def set_multiple_instance_mode(): + global Class + Class = MultipleInstanceClass + # vim: tabstop=4 expandtab shiftwidth=4 diff -r 6baf47498438 -r dc85db350f87 test.py --- a/test.py Sun Jan 21 00:17:09 2007 +0100 +++ b/test.py Sun Jan 21 00:17:44 2007 +0100 @@ -1,10 +1,17 @@ #!/usr/bin/env python -import sys, os -import viewer -from annotate import AnnotationError, Importer, load +if __name__ == "__main__": + import sys, os + + import simplified -if __name__ == "__main__": + if "-s" in sys.argv: + simplified.set_single_instance_mode() + elif "-m" in sys.argv: + simplified.set_multiple_instance_mode() + + import viewer + from annotate import AnnotationError, Importer, load importer = Importer(sys.path) try: