1.1 --- a/annotate.py Sun Jul 30 16:15:57 2006 +0200
1.2 +++ b/annotate.py Mon Jul 31 01:01:34 2006 +0200
1.3 @@ -1,7 +1,7 @@
1.4 #!/usr/bin/env python
1.5
1.6 """
1.7 -Annotate simplified AST structures. The code in this module operates upon nodes
1.8 +Annotate program node structures. The code in this module operates upon nodes
1.9 which are produced when simplifying AST node trees originating from the compiler
1.10 module.
1.11
1.12 @@ -44,7 +44,7 @@
1.13
1.14 system = System()
1.15
1.16 -# Namespaces and related abstractions.
1.17 +# Namespace-related abstractions.
1.18
1.19 class Namespace:
1.20
1.21 @@ -53,8 +53,7 @@
1.22 locals or the initialisation of a structure.
1.23 """
1.24
1.25 - def __init__(self, structure=None):
1.26 - self.structure = structure
1.27 + def __init__(self):
1.28 self.names = {}
1.29
1.30 def store(self, name, types):
1.31 @@ -65,7 +64,7 @@
1.32
1.33 def merge(self, name, types):
1.34 if not self.names.has_key(name):
1.35 - self.names[name] = types
1.36 + self.names[name] = types[:]
1.37 else:
1.38 existing = self.names[name]
1.39 for type in types:
1.40 @@ -79,6 +78,9 @@
1.41 for name, types in items:
1.42 self.merge(name, types)
1.43
1.44 + def __repr__(self):
1.45 + return repr(self.names)
1.46 +
1.47 class Attribute:
1.48
1.49 """
1.50 @@ -93,10 +95,13 @@
1.51 def __eq__(self, other):
1.52 return hasattr(other, "type") and other.type == self.type or other == self.type
1.53
1.54 -def find_methods(structure, name):
1.55 + def __repr__(self):
1.56 + return "Attribute of type %s (context %s)" % (self.type, self.context)
1.57 +
1.58 +def find_attributes(structure, name):
1.59
1.60 """
1.61 - Find for the given 'structure' all methods for the given 'name', visiting
1.62 + Find for the given 'structure' all attributes for the given 'name', visiting
1.63 base classes where appropriate and returning the methods in order of
1.64 descending precedence for all possible base classes.
1.65 """
1.66 @@ -104,16 +109,43 @@
1.67 try:
1.68 return structure.namespace.load(name)
1.69 except KeyError:
1.70 - methods = []
1.71 - if hasattr(structure, "base_refs"):
1.72 + attributes = []
1.73 + if isinstance(structure, Instance):
1.74 + for cls in structure.namespace.load("__class__"):
1.75 + l = find_attributes(cls, name)
1.76 + for attribute in l:
1.77 + if attribute not in attributes:
1.78 + attributes.append(attribute)
1.79 + elif isinstance(structure, Class):
1.80 for base_refs in structure.base_refs:
1.81 + base_attributes = []
1.82 for base_ref in base_refs:
1.83 - l = find_methods(base_ref, name)
1.84 + l = find_attributes(base_ref, name)
1.85 if l:
1.86 - for method in l:
1.87 - if method not in methods:
1.88 - methods.append(method)
1.89 - return methods
1.90 + for attribute in l:
1.91 + if attribute not in base_attributes:
1.92 + base_attributes.append(attribute)
1.93 + elif None not in base_attributes:
1.94 + base_attributes.append(None)
1.95 + if base_attributes != [None]:
1.96 + attributes += base_attributes
1.97 + return attributes
1.98 +
1.99 +def get_attributes(structure, name):
1.100 +
1.101 + """
1.102 + Return all possible attributes for the given 'structure' having the given
1.103 + 'name', wrapping each attribute in an Attribute object which includes
1.104 + context information for the attribute access.
1.105 + """
1.106 +
1.107 + if isinstance(structure, Attribute):
1.108 + structure = structure.type
1.109 + attributes = find_attributes(structure, name)
1.110 + for i, attribute in enumerate(attributes):
1.111 + if attribute is not None:
1.112 + attributes[i] = Attribute(structure, attribute)
1.113 + return attributes
1.114
1.115 # Annotation.
1.116
1.117 @@ -137,35 +169,49 @@
1.118
1.119 self.visitor = self
1.120
1.121 + def process_all(self, visitor, builtins_visitor=None):
1.122 +
1.123 + # Give constants their own namespace.
1.124 +
1.125 + for value, constant in visitor.constants.items():
1.126 + constant.namespace = Namespace()
1.127 +
1.128 + # Process the module, supplying builtins if possible.
1.129 +
1.130 + if builtins_visitor is not None:
1.131 + return self.process(visitor.result, builtins=builtins_visitor.result.namespace)
1.132 + else:
1.133 + return self.process(visitor.result)
1.134 +
1.135 def process(self, node, locals=None, globals=None, builtins=None):
1.136
1.137 """
1.138 - Process a subprogram or module 'node', indicating any initial 'locals',
1.139 - 'globals' and 'builtins' if any are defined. Return an annotated
1.140 - subprogram or module. Note that this method may mutate nodes in the
1.141 - original program.
1.142 + Process a subprogram or module 'node', indicating any initial 'locals'.
1.143 + Return an annotated subprogram or module. Note that this method may
1.144 + mutate nodes in the original program.
1.145 """
1.146
1.147 - # Obtain a namespace either based on locals or on a structure.
1.148 + # Determine the global namespace.
1.149 + # NOTE: Improve this.
1.150
1.151 - self.namespace = Namespace(structure=getattr(node, "structure", None))
1.152 - if locals is not None:
1.153 - self.namespace.merge_namespace(locals)
1.154 + self.global_namespace = globals or Namespace()
1.155 + self.builtins_namespace = builtins or self.global_namespace
1.156 + self.namespace = locals or self.global_namespace
1.157
1.158 - # Determine the global namespace.
1.159 + # Record the namespace on the node.
1.160 + # NOTE: This may eventually be a specialisation node.
1.161
1.162 - self.global_namespace = globals or self.namespace # NOTE: Improve this.
1.163 - self.builtins_namespace = builtins or self.namespace # NOTE: Improve this.
1.164 node.namespace = self.namespace
1.165
1.166 - # Remember return values.
1.167 + # Remember return values and locals snapshots.
1.168
1.169 self.returns = []
1.170 + self.return_locals = []
1.171
1.172 # Add namespace details to any structure involved.
1.173
1.174 - if hasattr(node, "structure") and node.structure is not None:
1.175 - node.structure.namespace = self.namespace
1.176 + if getattr(node, "structure", None) is not None:
1.177 + node.structure.namespace = Namespace()
1.178
1.179 # Initialise bases where appropriate.
1.180
1.181 @@ -179,7 +225,6 @@
1.182 # Dispatch to the code itself.
1.183
1.184 result = self.dispatch(node)
1.185 -
1.186 return result
1.187
1.188 def annotate(self, node):
1.189 @@ -188,6 +233,14 @@
1.190
1.191 self.system.annotate(node, self.types)
1.192
1.193 + def add_locals_snapshot(self):
1.194 +
1.195 + "Make a snapshot of the locals and remember them."
1.196 +
1.197 + namespace = Namespace()
1.198 + namespace.merge_namespace(self.namespace)
1.199 + self.return_locals.append(namespace)
1.200 +
1.201 # Visitor methods.
1.202
1.203 def default(self, node):
1.204 @@ -208,7 +261,11 @@
1.205 return node
1.206
1.207 def dispatch(self, node, *args):
1.208 - return Visitor.dispatch(self, node, *args)
1.209 + try:
1.210 + return Visitor.dispatch(self, node, *args)
1.211 + except:
1.212 + print "Failed using node", node
1.213 + raise
1.214
1.215 def visitLoadRef(self, loadref):
1.216 self.types = [loadref.ref]
1.217 @@ -260,8 +317,8 @@
1.218 loadattr.expr = self.dispatch(loadattr.expr)
1.219 types = []
1.220 for ref in self.types:
1.221 - for type in ref.namespace.load(loadattr.name):
1.222 - types.append(Attribute(ref, type))
1.223 + for type in get_attributes(ref, loadattr.name):
1.224 + types.append(type)
1.225 self.types = types
1.226 self.annotate(loadattr)
1.227 return loadattr
1.228 @@ -274,10 +331,31 @@
1.229 ref.namespace.store(storeattr.name, expr)
1.230 return storeattr
1.231
1.232 + def visitConditional(self, conditional):
1.233 +
1.234 + # Conditionals keep local namespace changes isolated.
1.235 + # With Return nodes inside the body/else sections, the changes are
1.236 + # communicated to the caller.
1.237 +
1.238 + conditional.test = self.dispatch(conditional.test)
1.239 + saved_namespace = self.namespace
1.240 +
1.241 + self.namespace = Namespace()
1.242 + self.namespace.merge_namespace(saved_namespace)
1.243 + conditional.body = self.dispatches(conditional.body)
1.244 +
1.245 + self.namespace = Namespace()
1.246 + self.namespace.merge_namespace(saved_namespace)
1.247 + conditional.else_ = self.dispatches(conditional.else_)
1.248 +
1.249 + self.namespace = saved_namespace
1.250 + return conditional
1.251 +
1.252 def visitReturn(self, return_):
1.253 if hasattr(return_, "expr"):
1.254 return_.expr = self.dispatch(return_.expr)
1.255 self.returns += self.types
1.256 + self.add_locals_snapshot()
1.257 return return_
1.258
1.259 def visitInvoke(self, invoke):
1.260 @@ -312,36 +390,94 @@
1.261 invoke.args = args
1.262 invoke.types = expr
1.263
1.264 - # NOTE: Now locate and invoke the subprogram.
1.265 + # Now locate and invoke the subprogram. This can be complicated because
1.266 + # the target may be a class or object, and there may be many different
1.267 + # related subprograms.
1.268
1.269 - for subprogram in expr:
1.270 + invocations = []
1.271 +
1.272 + # Visit each callable in turn
1.273 +
1.274 + for callable in expr:
1.275
1.276 - # NOTE: Deal with class invocations by providing instance objects,
1.277 - # NOTE: and with object invocations by using __call__ methods.
1.278 + # Deal with class invocations by providing instance objects.
1.279 + # Here, each class is queried for the __init__ method, which may
1.280 + # exist for some combinations of classes in a hierarchy but not for
1.281 + # others.
1.282 +
1.283 + if isinstance(callable, Class):
1.284 + subprograms = get_attributes(callable, "__init__")
1.285
1.286 - if hasattr(invoke, "same_frame") and invoke.same_frame:
1.287 - namespace = self.namespace
1.288 + # Deal with object invocations by using __call__ methods.
1.289 +
1.290 + elif isinstance(callable, Instance):
1.291 + subprograms = get_attributes(callable, "__call__")
1.292 +
1.293 + # Normal functions or methods are more straightforward.
1.294 +
1.295 else:
1.296 - items = self.make_items(invoke, subprogram)
1.297 - namespace = self.make_namespace(items)
1.298 -
1.299 - annotator = Annotator()
1.300 - annotator.process(subprogram, namespace, self.global_namespace)
1.301 + subprograms = [callable]
1.302
1.303 - # NOTE: Annotate the node with invocation details.
1.304 - # NOTE: This should really be as part of a table of alternatives.
1.305 -
1.306 - if hasattr(subprogram, "returns_value") and subprogram.returns_value:
1.307 - self.types = annotator.returns
1.308 - self.annotate(invoke)
1.309 + for subprogram in subprograms:
1.310 + if subprogram is not None:
1.311 + invocations.append(self.invoke_subprogram(invoke, subprogram))
1.312
1.313 return invoke
1.314
1.315 # Utility methods.
1.316
1.317 - def make_items(self, invocation, subprogram):
1.318 - # NOTE: Support star and dstar.
1.319 - args = invocation.args
1.320 + def invoke_subprogram(self, invoke, subprogram):
1.321 +
1.322 + """
1.323 + Invoke using the given 'invoke' node the given 'subprogram'.
1.324 + """
1.325 +
1.326 + # Test for context information.
1.327 +
1.328 + if hasattr(subprogram, "context"):
1.329 + context = subprogram.context
1.330 + target = subprogram.type
1.331 + else:
1.332 + context = None
1.333 + target = subprogram
1.334 +
1.335 + # Provide the correct namespace for the invocation.
1.336 +
1.337 + if getattr(invoke, "same_frame", 0):
1.338 + namespace = Namespace()
1.339 + namespace.merge_namespace(self.namespace)
1.340 + else:
1.341 + items = self.make_items(invoke, target, context)
1.342 + namespace = self.make_namespace(items)
1.343 +
1.344 + # Process the subprogram.
1.345 +
1.346 + annotator = Annotator()
1.347 + annotator.process(subprogram, namespace, self.global_namespace, self.builtins_namespace)
1.348 +
1.349 + # NOTE: Annotate the node with invocation details.
1.350 + # NOTE: This should really be as part of a table of alternatives.
1.351 +
1.352 + if getattr(subprogram, "returns_value", 0):
1.353 + self.types = annotator.returns
1.354 + self.annotate(invoke)
1.355 +
1.356 + if getattr(invoke, "same_frame", 0):
1.357 + for locals in annotator.return_locals:
1.358 + self.namespace.merge_namespace(locals)
1.359 +
1.360 + def make_items(self, invocation, subprogram, context):
1.361 +
1.362 + """
1.363 + Make an items mapping for the 'invocation' of the 'subprogram' using the
1.364 + given 'context' (which may be None).
1.365 + """
1.366 +
1.367 + if context is not None:
1.368 + args = [context] + invocation.args
1.369 + else:
1.370 + args = invocation.args
1.371 +
1.372 params = subprogram.params
1.373 items = []
1.374 keywords = {}
2.1 --- a/fixnames.py Sun Jul 30 16:15:57 2006 +0200
2.2 +++ b/fixnames.py Mon Jul 31 01:01:34 2006 +0200
2.3 @@ -62,7 +62,7 @@
2.4
2.5 # Obtain a namespace either based on locals or on a structure.
2.6
2.7 - self.namespace = Namespace(structure=getattr(node, "structure", None))
2.8 + self.namespace = NameOrganiser(structure=getattr(node, "structure", None))
2.9
2.10 # Add namespace details to any structure involved.
2.11
2.12 @@ -133,7 +133,7 @@
2.13 self.namespace.store(storename.name)
2.14 return storename
2.15
2.16 -class Namespace:
2.17 +class NameOrganiser:
2.18
2.19 """
2.20 A local namespace which may either relate to a genuine set of function
3.1 --- a/simplified.py Sun Jul 30 16:15:57 2006 +0200
3.2 +++ b/simplified.py Mon Jul 31 01:01:34 2006 +0200
3.3 @@ -159,7 +159,7 @@
3.4 class LoadName(Node): "Load a named object."
3.5 class LoadGlobal(Node): "Load a named global object."
3.6 class LoadAttr(Node): "Load an object attribute."
3.7 -class LoadRef(Node): "Load a reference, typically a subprogram."
3.8 +class LoadRef(Node): "Load a reference, typically a subprogram or a constant."
3.9 class LoadExc(Node): "Load a handled exception."
3.10 class StoreTemp(Node): "Store a temporary value."
3.11 class StoreName(Node): "Associate a name with an object."
3.12 @@ -188,8 +188,24 @@
3.13 else:
3.14 return "%s (at %x)" % (self.__class__, id(self))
3.15
3.16 -class Class(Structure): "A Python class."
3.17 -class Instance(Structure): "An instance."
3.18 -class Constant(Instance): "A constant."
3.19 +class Class(Structure):
3.20 +
3.21 + "A Python class."
3.22 +
3.23 +class Instance(Structure):
3.24 +
3.25 + "An instance."
3.26 +
3.27 + def __init__(self, **kw):
3.28 + Structure.__init__(self, **kw)
3.29 + self.types = [self]
3.30 +
3.31 +class Constant(Instance):
3.32 +
3.33 + "A constant initialised with a type name for future processing."
3.34 +
3.35 + def __init__(self, **kw):
3.36 + Instance.__init__(self, **kw)
3.37 + self.typename = self.value.__class__.__name__
3.38
3.39 # vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/simplify.py Sun Jul 30 16:15:57 2006 +0200
4.2 +++ b/simplify.py Mon Jul 31 01:01:34 2006 +0200
4.3 @@ -44,13 +44,14 @@
4.4 Sub, Yield.
4.5 """
4.6
4.7 - def __init__(self):
4.8 + def __init__(self, builtins=0):
4.9 Visitor.__init__(self)
4.10 self.result = None # The resulting tree.
4.11 self.subprograms = [] # Subprograms outside the tree.
4.12 self.structures = [] # Structures/classes.
4.13 self.constants = {} # Constants.
4.14 self.current_subprograms = [] # Current subprograms being processed.
4.15 + self.builtins = builtins # Whether the builtins are being processed.
4.16
4.17 def process(self, node):
4.18 self.visitor = self
4.19 @@ -77,7 +78,21 @@
4.20
4.21 def visitModule(self, module):
4.22 self.result = Module(module)
4.23 - self.result.code = self.dispatch(module.node)
4.24 + module_code = self.dispatch(module.node)
4.25 +
4.26 + # NOTE: Constant initialisation necessary for annotation but perhaps
4.27 + # NOTE: redundant in the program.
4.28 +
4.29 + init_code = []
4.30 + for value, constant in self.constants.items():
4.31 + init_code.append(StoreAttr(lvalue=LoadRef(ref=constant), name="__class__", expr=LoadName(name=constant.typename)))
4.32 +
4.33 + # NOTE: Hack to ensure correct initialisation of constants.
4.34 +
4.35 + if self.builtins:
4.36 + self.result.code = module_code + init_code
4.37 + else:
4.38 + self.result.code = init_code + module_code
4.39 return self.result
4.40
4.41 def visitGetattr(self, getattr):
4.42 @@ -205,6 +220,8 @@
4.43 self.current_subprograms.pop()
4.44 self.subprograms.append(body_subprogram)
4.45
4.46 + # Always return from conditional sections.
4.47 +
4.48 test.body = [Invoke(stmt, expr=LoadRef(ref=body_subprogram), same_frame=1, star=None, dstar=None, args=[]), Return()]
4.49 nodes.append(test)
4.50
4.51 @@ -219,7 +236,10 @@
4.52 self.current_subprograms.pop()
4.53 self.subprograms.append(else_subprogram)
4.54
4.55 + # Always return from conditional subprograms.
4.56 +
4.57 nodes.append(Invoke(stmt, expr=LoadRef(ref=else_subprogram), same_frame=1, star=None, dstar=None, args=[]))
4.58 + nodes.append(Return())
4.59
4.60 subprogram.code = nodes
4.61
4.62 @@ -258,6 +278,9 @@
4.63 test = Conditional(body=[], else_=[], test=Invoke(expr=LoadName(name="isinstance"), args=[LoadExc(), new_spec], star=None, dstar=None))
4.64 if assign is not None:
4.65 test.body.append(Assign(code=[StoreTemp(expr=LoadExc()), self.dispatch(assign), ReleaseTemp()]))
4.66 +
4.67 + # Always return from conditional sections.
4.68 +
4.69 test.body += self.dispatch(stmt) + [Return()]
4.70 nodes.append(test)
4.71
4.72 @@ -316,6 +339,9 @@
4.73 else:
4.74 raise NotImplementedError, op_name
4.75 nodes.append(StoreTemp(expr=invocation))
4.76 +
4.77 + # Always return from conditional sections/subprograms.
4.78 +
4.79 if op is not last:
4.80 nodes.append(Conditional(test=Not(expr=LoadTemp()), body=[Return(expr=LoadTemp())]))
4.81 nodes.append(ReleaseTemp())
4.82 @@ -348,6 +374,9 @@
4.83 last = and_.nodes[-1]
4.84 for node in and_.nodes:
4.85 expr = self.dispatch(node)
4.86 +
4.87 + # Always return from conditional sections/subprograms.
4.88 +
4.89 if node is not last:
4.90 nodes.append(StoreTemp(expr=expr))
4.91 invocation = Invoke(expr=LoadAttr(expr=LoadTemp(), name="__true__"), args=[], star=None, dstar=None)
4.92 @@ -381,6 +410,9 @@
4.93 last = or_.nodes[-1]
4.94 for node in or_.nodes:
4.95 expr = self.dispatch(node)
4.96 +
4.97 + # Always return from conditional sections/subprograms.
4.98 +
4.99 if node is not last:
4.100 nodes.append(StoreTemp(expr=expr))
4.101 invocation = Invoke(expr=LoadAttr(expr=LoadTemp(), name="__true__"), args=[], star=None, dstar=None)
4.102 @@ -608,12 +640,12 @@
4.103
4.104 # Make a subprogram which initialises the class structure.
4.105
4.106 - subprogram = Subprogram(name=None, structure=structure, params=[], star=None, dstar=None)
4.107 + subprogram = Subprogram(name=None, acquire_locals=1, structure=structure, params=[], star=None, dstar=None)
4.108 self.current_subprograms.append(subprogram)
4.109
4.110 # The class is initialised using the code found inside.
4.111
4.112 - subprogram.code = self.dispatch(class_.code)
4.113 + subprogram.code = self.dispatch(class_.code) + [Return()]
4.114
4.115 self.current_subprograms.pop()
4.116 self.subprograms.append(subprogram)
4.117 @@ -668,9 +700,9 @@
4.118 # Make a subprogram for the function and record it outside the main
4.119 # tree.
4.120
4.121 - subprogram = Subprogram(name=function.name, returns_value=1, star=None, dstar=None)
4.122 + subprogram = Subprogram(name=function.name, acquire_locals=0, returns_value=1, star=None, dstar=None)
4.123 self.current_subprograms.append(subprogram)
4.124 - subprogram.code = self.dispatch(function.code)
4.125 + subprogram.code = self.dispatch(function.code) + [Return()]
4.126 self.current_subprograms.pop()
4.127 self._visitFunction(function, subprogram)
4.128
4.129 @@ -684,7 +716,7 @@
4.130 # Make a subprogram for the function and record it outside the main
4.131 # tree.
4.132
4.133 - subprogram = Subprogram(name=None, returns_value=1, star=None, dstar=None)
4.134 + subprogram = Subprogram(name=None, acquire_locals=0, returns_value=1, star=None, dstar=None)
4.135 self.current_subprograms.append(subprogram)
4.136 subprogram.code = [Return(expr=self.dispatch(lambda_.code))]
4.137 self.current_subprograms.pop()
4.138 @@ -722,10 +754,13 @@
4.139
4.140 continuation = Invoke(same_frame=1, star=None, dstar=None, args=[])
4.141 continuation.expr = LoadRef(ref=subprogram)
4.142 - test.body = self.dispatch(while_.body) + [continuation]
4.143 +
4.144 + # Always return from conditional sections/subprograms.
4.145 +
4.146 + test.body = self.dispatch(while_.body) + [continuation, Return()]
4.147 if while_.else_ is not None:
4.148 test.else_ = self.dispatch(while_.else_)
4.149 - subprogram.code = [test]
4.150 + subprogram.code = [test, Return()]
4.151
4.152 self.current_subprograms.pop()
4.153 self.subprograms.append(subprogram)
4.154 @@ -743,10 +778,12 @@
4.155 subprogram = Subprogram(name=None, acquire_locals=1, returns_value=0, params=[], star=None, dstar=None)
4.156 self.current_subprograms.append(subprogram)
4.157
4.158 + # Always return from conditional sections/subprograms.
4.159 +
4.160 if for_.else_ is not None:
4.161 - else_stmt = self.dispatch(for_.else_)
4.162 + else_stmt = self.dispatch(for_.else_) + [Return()]
4.163 else:
4.164 - else_stmt = []
4.165 + else_stmt = [Return()]
4.166
4.167 # Wrap the assignment in a try...except statement.
4.168
4.169 @@ -768,7 +805,7 @@
4.170 continuation = Invoke(same_frame=1, produces_result=0, star=None, dstar=None, args=[])
4.171 continuation.expr = LoadRef(ref=subprogram)
4.172 try_except.body = [assign] + self.dispatch(for_.body) + [continuation]
4.173 - subprogram.code = [try_except]
4.174 + subprogram.code = [try_except, Return()]
4.175
4.176 self.subprograms.append(subprogram)
4.177 self.current_subprograms.pop()
5.1 --- a/test.py Sun Jul 30 16:15:57 2006 +0200
5.2 +++ b/test.py Mon Jul 31 01:01:34 2006 +0200
5.3 @@ -5,9 +5,9 @@
5.4 a = annotate.Annotator()
5.5 b = compiler.parseFile(os.path.join("lib", "builtins.py"))
5.6 m = compiler.parseFile(sys.argv[1])
5.7 -builtins_simplifier = simplify.Simplifier()
5.8 +vb = builtins_simplifier = simplify.Simplifier(1)
5.9 builtins_simplifier.process(b)
5.10 -module_simplifier = simplify.Simplifier()
5.11 +v = module_simplifier = simplify.Simplifier()
5.12 module_simplifier.process(m)
5.13 builtins_fixer = fixnames.Fixer()
5.14 builtins_fixer.process_all(builtins_simplifier)
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/tests/dynamic_subclass.py Mon Jul 31 01:01:34 2006 +0200
6.3 @@ -0,0 +1,9 @@
6.4 +if 2:
6.5 + class A:
6.6 + def f(self):
6.7 + pass
6.8 +else:
6.9 + class A:
6.10 + pass
6.11 +class B(A):
6.12 + pass
7.1 --- a/tests/subclass.py Sun Jul 30 16:15:57 2006 +0200
7.2 +++ b/tests/subclass.py Mon Jul 31 01:01:34 2006 +0200
7.3 @@ -3,3 +3,4 @@
7.4 class B(A):
7.5 def b(self): pass
7.6 class C(A, B): pass
7.7 +class D(B): pass