1.1 --- a/simplify/annotate.py Fri Jun 22 01:06:19 2007 +0200
1.2 +++ b/simplify/annotate.py Fri Jun 22 01:11:12 2007 +0200
1.3 @@ -1379,152 +1379,6 @@
1.4
1.5 # Namespace-related abstractions.
1.6
1.7 -class Namespace:
1.8 -
1.9 - """
1.10 - A local namespace which may either relate to a genuine set of function
1.11 - locals or the initialisation of a structure or module.
1.12 - """
1.13 -
1.14 - def __init__(self):
1.15 -
1.16 - """
1.17 - Initialise the namespace with a mapping of local names to possible
1.18 - types, a list of return values and of possible returned local
1.19 - namespaces. The namespace also tracks the "current" types and a mapping
1.20 - of temporary value names to types.
1.21 - """
1.22 -
1.23 - self.names = {}
1.24 - self.returns = set()
1.25 - self.return_locals = set()
1.26 - self.raises = set()
1.27 - self.temp = {}
1.28 - self.types = set()
1.29 -
1.30 - def set_types(self, types):
1.31 -
1.32 - "Set the current collection of 'types'."
1.33 -
1.34 - self.types = types.copy()
1.35 -
1.36 - def add(self, name, types):
1.37 -
1.38 - "Add to the entry with the given 'name' the specified 'types'."
1.39 -
1.40 - if self.names.has_key(name):
1.41 - self.names[name].update(types)
1.42 - else:
1.43 - self.store(name, types)
1.44 -
1.45 - def store(self, name, types):
1.46 -
1.47 - "Store in (or associate with) the given 'name' the specified 'types'."
1.48 -
1.49 - self.names[name] = types.copy()
1.50 -
1.51 - __setitem__ = store
1.52 -
1.53 - def load(self, name):
1.54 -
1.55 - "Load the types associated with the given 'name'."
1.56 -
1.57 - return self.names[name]
1.58 -
1.59 - __getitem__ = load
1.60 -
1.61 - def has_key(self, name):
1.62 - return self.names.has_key(name)
1.63 -
1.64 - def keys(self):
1.65 - return self.names.keys()
1.66 -
1.67 - def values(self):
1.68 - return self.names.values()
1.69 -
1.70 - def items(self):
1.71 - return self.names.items()
1.72 -
1.73 - def get(self, name, default=None):
1.74 - return self.names.get(name, default)
1.75 -
1.76 - def revoke(self, name, type):
1.77 -
1.78 - "Revoke from the entry for the given 'name' the specified 'type'."
1.79 -
1.80 - new_types = self.names[name].copy()
1.81 - new_types.remove(type)
1.82 - self.names[name] = new_types
1.83 -
1.84 - def revoke_exception_type(self, type):
1.85 -
1.86 - "Revoke the given 'type' from the collection of exception types."
1.87 -
1.88 - if type in self.raises:
1.89 - self.raises.remove(type)
1.90 -
1.91 - def revoke_temp_type(self, index, type):
1.92 -
1.93 - "Revoke from the temporary variable 'index' the given 'type'."
1.94 -
1.95 - new_types = self.temp[index][-1].copy()
1.96 - new_types.remove(type)
1.97 - self.temp[index][-1] = new_types
1.98 -
1.99 - def merge_namespace(self, namespace, everything=1):
1.100 -
1.101 - """
1.102 - Merge items from the given 'namespace' with this namespace. When the
1.103 - optional 'everything' parameter is set to a false value (unlike the
1.104 - default), return values and locals snapshots will not be copied to this
1.105 - namespace.
1.106 - """
1.107 -
1.108 - self.merge_items(namespace.names.items())
1.109 - self.raises.update(namespace.raises)
1.110 - if everything:
1.111 - self.returns.update(namespace.returns)
1.112 - self.return_locals.update(namespace.return_locals)
1.113 - for name, values in namespace.temp.items():
1.114 - if values:
1.115 - if not self.temp.has_key(name) or not self.temp[name]:
1.116 - self.temp[name] = [set()]
1.117 - self.temp[name][-1].update(values[-1])
1.118 -
1.119 - def merge_items(self, items):
1.120 -
1.121 - "Merge the given 'items' with this namespace."
1.122 -
1.123 - for name, types in items:
1.124 - self.merge(name, types)
1.125 -
1.126 - def merge(self, name, types):
1.127 -
1.128 - "Merge the entry for the given 'name' and 'types' with this namespace."
1.129 -
1.130 - if not self.names.has_key(name):
1.131 - self.names[name] = types.copy()
1.132 - else:
1.133 - existing = self.names[name]
1.134 - existing.update(types)
1.135 -
1.136 - def snapshot(self):
1.137 -
1.138 - "Make a snapshot of the locals and remember them."
1.139 -
1.140 - namespace = Namespace()
1.141 - namespace.merge_namespace(self)
1.142 - self.return_locals.add(namespace)
1.143 -
1.144 - def reset(self):
1.145 -
1.146 - "Reset a namespace in preparation for merging with returned locals."
1.147 -
1.148 - self.names = {}
1.149 -
1.150 - def __repr__(self):
1.151 - return repr(self.names) + " (temp) " + repr(self.temp)
1.152 -
1.153 class Importer:
1.154
1.155 "An import machine, searching for and loading modules."
1.156 @@ -1745,6 +1599,7 @@
1.157
1.158 if isinstance(structure, Attribute):
1.159 structure = structure.type
1.160 +
1.161 results = []
1.162 for attribute, accessor in find_attributes(structure, name):
1.163
1.164 @@ -1754,9 +1609,18 @@
1.165 attribute = accessor.get_attribute_for_instance(attribute, structure)
1.166
1.167 # Produce an attribute with the appropriate context.
1.168 + # Modules should not affect the context.
1.169
1.170 - if attribute is not None and isinstance(structure, Structure):
1.171 + if attribute is not None and isinstance(structure, Module):
1.172 + results.append((attribute, accessor))
1.173 +
1.174 + # Access via classes and instances should set those as the context.
1.175 +
1.176 + elif attribute is not None and isinstance(structure, Structure):
1.177 results.append((Attribute(structure, attribute.type), accessor))
1.178 +
1.179 + # Other accesses are returned unmodified.
1.180 +
1.181 else:
1.182 results.append((attribute, accessor))
1.183