[pypy-svn] r5269 - in pypy/trunk/src/pypy: annotation objspace/flow translator translator/test
arigo at codespeak.net
arigo at codespeak.net
Thu Jun 24 18:15:03 CEST 2004
Author: arigo
Date: Thu Jun 24 18:15:03 2004
New Revision: 5269
Modified:
pypy/trunk/src/pypy/annotation/builtin.py
pypy/trunk/src/pypy/annotation/model.py
pypy/trunk/src/pypy/annotation/unaryop.py
pypy/trunk/src/pypy/objspace/flow/flowcontext.py
pypy/trunk/src/pypy/objspace/flow/objspace.py
pypy/trunk/src/pypy/translator/annrpython.py
pypy/trunk/src/pypy/translator/test/snippet.py
pypy/trunk/src/pypy/translator/test/test_annrpython.py
pypy/trunk/src/pypy/translator/translator.py
Log:
A lot of minor changes to better support annotating methods:
* Unbound methods are regarded as functions, for Parent.__init__().
* we can flow with constant arguments; used for the 'self' of
constant bound method objects. See test_global_instance().
* int() returns an integer (let's say).
Modified: pypy/trunk/src/pypy/annotation/builtin.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/builtin.py (original)
+++ pypy/trunk/src/pypy/annotation/builtin.py Thu Jun 24 18:15:03 2004
@@ -20,6 +20,12 @@
else:
return SomeObject()
+def builtin_int(s_obj): # we can consider 'int' as a function
+ if isinstance(s_obj, SomeInteger):
+ return s_obj
+ else:
+ return SomeInteger()
+
# collect all functions
import __builtin__
Modified: pypy/trunk/src/pypy/annotation/model.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/model.py (original)
+++ pypy/trunk/src/pypy/annotation/model.py Thu Jun 24 18:15:03 2004
@@ -115,7 +115,8 @@
self.s_self = s_self
class SomeFunction(SomeObject):
- "Stands for a Python function (or some function out of a list)."
+ """Stands for a Python function (or some function out of a list).
+ Alternatively, it can be a constant bound or unbound method."""
knowntype = FunctionType
def __init__(self, funcs):
self.funcs = funcs # set of functions that this one may be
@@ -153,7 +154,7 @@
result = SomeBuiltin(BUILTIN_FUNCTIONS[x])
elif isinstance(x, (type, ClassType)) and x.__module__ != '__builtin__':
result = SomeClass(x)
- elif isinstance(x, FunctionType):
+ elif isinstance(x, (FunctionType, MethodType)):
result = SomeFunction({x: True})
else:
result = SomeObject()
Modified: pypy/trunk/src/pypy/annotation/unaryop.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/unaryop.py (original)
+++ pypy/trunk/src/pypy/annotation/unaryop.py Thu Jun 24 18:15:03 2004
@@ -2,6 +2,7 @@
Unary operations on SomeValues.
"""
+from types import FunctionType
from pypy.annotation.pairtype import pair
from pypy.annotation.model import SomeObject, SomeInteger, SomeBool
from pypy.annotation.model import SomeString, SomeList, SomeDict
@@ -148,6 +149,8 @@
def classattribute(fun, classdef): # function -> unbound method
d = {}
for func in fun.funcs:
+ assert isinstance(func, FunctionType), (
+ "%r should not be read out of class %r" % (func, classdef))
d[func] = classdef
return SomeMethod(d)
Modified: pypy/trunk/src/pypy/objspace/flow/flowcontext.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/flowcontext.py (original)
+++ pypy/trunk/src/pypy/objspace/flow/flowcontext.py Thu Jun 24 18:15:03 2004
@@ -63,15 +63,17 @@
class FlowExecutionContext(ExecutionContext):
- def __init__(self, space, code, globals):
+ def __init__(self, space, code, globals, constargs={}):
ExecutionContext.__init__(self, space)
self.code = code
self.w_globals = w_globals = space.wrap(globals)
frame = self.create_frame()
formalargcount = code.getformalargcount()
dummy = UndefinedConstant()
- arg_list = ([Variable() for i in range(formalargcount)] +
- [dummy] * (len(frame.fastlocals_w) - formalargcount))
+ arg_list = [Variable() for i in range(formalargcount)]
+ for position, value in constargs.items():
+ arg_list[position] = Constant(value)
+ arg_list += [dummy] * (len(frame.fastlocals_w) - formalargcount)
frame.setfastscope(arg_list)
self.joinpoints = {}
for joinpoint in code.getjoinpoints():
Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/objspace.py (original)
+++ pypy/trunk/src/pypy/objspace/flow/objspace.py Thu Jun 24 18:15:03 2004
@@ -67,12 +67,13 @@
#print >> sys.stderr, '*** reraise', etype, evalue
raise OperationError, OperationError(self.wrap(etype), self.wrap(evalue)), etb
- def build_flow(self, func):
+ def build_flow(self, func, constargs={}):
"""
"""
code = func.func_code
code = PyCode()._from_code(code)
- ec = flowcontext.FlowExecutionContext(self, code, func.func_globals)
+ ec = flowcontext.FlowExecutionContext(self, code, func.func_globals,
+ constargs)
self.executioncontext = ec
ec.build_flow()
name = ec.graph.name
@@ -131,6 +132,8 @@
op = issubclass
elif name == 'id':
op = id
+ elif name == 'getattr':
+ op = getattr
else:
if debug: print >> sys.stderr, "XXX missing operator:", name
Modified: pypy/trunk/src/pypy/translator/annrpython.py
==============================================================================
--- pypy/trunk/src/pypy/translator/annrpython.py (original)
+++ pypy/trunk/src/pypy/translator/annrpython.py Thu Jun 24 18:15:03 2004
@@ -35,6 +35,7 @@
if self.translator is None:
from pypy.translator.translator import Translator
self.translator = Translator(func_or_flowgraph)
+ self.translator.annotator = self
flowgraph = self.translator.getflowgraph(func_or_flowgraph)
# make input arguments and set their type
input_arg_types = list(input_arg_types)
Modified: pypy/trunk/src/pypy/translator/test/snippet.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/snippet.py (original)
+++ pypy/trunk/src/pypy/translator/test/snippet.py Thu Jun 24 18:15:03 2004
@@ -328,6 +328,11 @@
def __init__(self, n):
self.a = n
+class WithMoreInit(WithInit):
+ def __init__(self, n, m):
+ WithInit.__init__(self, n)
+ self.b = m
+
def simple_method(v=anytype):
z = Z()
z.my_attribute = v
@@ -337,6 +342,15 @@
z = WithInit(v)
return z.a
+def with_more_init(v=int, w=bool):
+ z = WithMoreInit(v, w)
+
+global_z = Z()
+global_z.my_attribute = 42
+
+def global_instance():
+ return global_z.my_method()
+
def powerset(setsize=int):
"""Powerset
Modified: pypy/trunk/src/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_annrpython.py (original)
+++ pypy/trunk/src/pypy/translator/test/test_annrpython.py Thu Jun 24 18:15:03 2004
@@ -217,6 +217,26 @@
# result should be an integer
self.assertEquals(s.knowntype, int)
+ def test_with_more_init(self):
+ a = RPythonAnnotator()
+ s = a.build_types(snippet.with_more_init, [int, bool])
+ # the user classes should have the following attributes:
+ classes = a.bookkeeper.userclasses
+ # XXX on which class should the attribute 'a' appear? We only
+ # ever flow WithInit.__init__ with a self which is an instance
+ # of WithMoreInit, so currently it appears on WithMoreInit.
+ self.assertEquals(classes[snippet.WithMoreInit].attrs.get('a'),
+ annmodel.SomeInteger())
+ self.assertEquals(classes[snippet.WithMoreInit].attrs.get('b'),
+ annmodel.SomeBool())
+
+ def test_global_instance(self):
+ a = RPythonAnnotator()
+ s = a.build_types(snippet.global_instance, [])
+ # currently this returns the constant 42.
+ # XXX not sure this is the best behavior...
+ self.assertEquals(s, annmodel.immutablevalue(42))
+
def g(n):
return [0,1,2,n]
Modified: pypy/trunk/src/pypy/translator/translator.py
==============================================================================
--- pypy/trunk/src/pypy/translator/translator.py (original)
+++ pypy/trunk/src/pypy/translator/translator.py Thu Jun 24 18:15:03 2004
@@ -43,8 +43,9 @@
class Translator:
- def __init__(self, func):
+ def __init__(self, func, verbose=False):
self.entrypoint = func
+ self.verbose = verbose
self.clear()
def clear(self):
@@ -60,8 +61,17 @@
try:
graph = self.flowgraphs[func]
except KeyError:
+ if self.verbose:
+ print 'getflowgraph:', func.__name__
+ im_func = getattr(func, 'im_func', func)
+ im_self = getattr(func, 'im_self', None)
+ if im_self is not None: # bound method?
+ constargs = {0: im_self}
+ else:
+ constargs = {}
space = FlowObjSpace()
- graph = self.flowgraphs[func] = space.build_flow(func)
+ graph = self.flowgraphs[func] = space.build_flow(im_func,
+ constargs)
self.functions.append(func)
try:
import inspect
More information about the Pypy-commit
mailing list