[pypy-svn] r26542 - in pypy/dist/pypy: rpython rpython/lltypesystem translator/c translator/c/src translator/c/test
tismer at codespeak.net
tismer at codespeak.net
Sat Apr 29 03:43:25 CEST 2006
Author: tismer
Date: Sat Apr 29 03:43:15 2006
New Revision: 26542
Modified:
pypy/dist/pypy/rpython/lltypesystem/lloperation.py
pypy/dist/pypy/rpython/robject.py
pypy/dist/pypy/translator/c/pyobj.py
pypy/dist/pypy/translator/c/src/pyobj.h
pypy/dist/pypy/translator/c/src/support.h
pypy/dist/pypy/translator/c/test/test_wrapping.py
pypy/dist/pypy/translator/c/wrapper.py
Log:
support for true methods, properties, ...
checking in with a bug right now.
Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Sat Apr 29 03:43:15 2006
@@ -317,6 +317,7 @@
'same_as': LLOp(canfold=True),
'hint': LLOp(),
'check_no_more_arg': LLOp(canraise=(Exception,)),
+ 'check_self_nonzero': LLOp(canraise=(Exception,)),
'decode_arg': LLOp(canraise=(Exception,)),
'decode_arg_def': LLOp(canraise=(Exception,)),
'getslice': LLOp(canraise=(Exception,)),
Modified: pypy/dist/pypy/rpython/robject.py
==============================================================================
--- pypy/dist/pypy/rpython/robject.py (original)
+++ pypy/dist/pypy/rpython/robject.py Sat Apr 29 03:43:15 2006
@@ -1,7 +1,7 @@
from pypy.annotation.pairtype import pairtype
from pypy.annotation import model as annmodel
from pypy.rpython.lltypesystem.lltype import \
- PyObject, Ptr, Void, pyobjectptr, nullptr
+ PyObject, Ptr, Void, pyobjectptr, nullptr, Bool
from pypy.rpython.rmodel import Repr, VoidRepr, inputconst
from pypy.rpython import rclass
from pypy.tool.sourcetools import func_with_new_name
@@ -69,3 +69,10 @@
for opname in annmodel.BINARY_OPERATIONS:
make_operation(opname, pairtype(PyObjRepr, Repr))
make_operation(opname, pairtype(Repr, PyObjRepr))
+
+
+class __extend__(pairtype(PyObjRepr, PyObjRepr)):
+ def rtype_contains((r_seq, r_item), hop):
+ v_seq, v_item = hop.inputargs(r_seq, r_item)
+ return hop.llops.gencapicall('PySequence_Contains_with_exc',
+ [v_seq, v_item], resulttype=Bool)
Modified: pypy/dist/pypy/translator/c/pyobj.py
==============================================================================
--- pypy/dist/pypy/translator/c/pyobj.py (original)
+++ pypy/dist/pypy/translator/c/pyobj.py Sat Apr 29 03:43:15 2006
@@ -81,6 +81,8 @@
self.initcode.append("%s = %s" % (name, pyexpr))
def nameof_object(self, value):
+ if isinstance(object, property):
+ return self.nameof_property(value)
if type(value) is not object:
raise Exception, "nameof(%r)" % (value,)
name = self.uniquename('g_object')
@@ -579,6 +581,15 @@
self.name_for_meth[value] = fname
if self.use_true_methods:
self.is_method[value] = True
+ elif isinstance(value, property):
+ fget, fset, fdel, doc = value.fget, value.fset, value.fdel, value.__doc__
+ for f in fget, fset, fdel:
+ if f and self.use_true_methods:
+ self.is_method[f] = True
+ stuff = [self.nameof(x) for x in fget, fset, fdel, doc]
+ yield '%s.%s = property(%s, %s, %s, %s)' % ((name, key) +
+ tuple(stuff))
+ continue
yield '%s.%s = %s' % (name, key, self.nameof(value))
if not init_seen:
log.WARNING('No __init__ found for %s - you cannot build instances' %
@@ -603,3 +614,13 @@
pycfunctionobj = self.uniquename('gfunc_' + newname)
self.wrappers[pycfunctionobj] = g.func.__name__, self.getvalue(fwrapper), g.func.__doc__
return pycfunctionobj
+
+ def nameof_property(self, p):
+ fget, fset, fdel, doc = p.fget, p.fset, p.fdel, p.__doc__
+ for f in fget, fset, fdel:
+ if f and self.use_true_methods:
+ self.is_method[f] = True
+ stuff = [self.nameof(x) for x in fget, fset, fdel, doc]
+ name = self.uniquename('gprop')
+ expr = 'property(%s, %s, %s, %s)' % (tuple(stuff))
+ self.initcode_python(name, expr)
Modified: pypy/dist/pypy/translator/c/src/pyobj.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/pyobj.h (original)
+++ pypy/dist/pypy/translator/c/src/pyobj.h Sat Apr 29 03:43:15 2006
@@ -225,7 +225,9 @@
#define OP_DECODE_ARG_DEF(fname, pos, name, vargs, vkwds, def, r) \
if (!(r=decode_arg(fname, pos, name, vargs, vkwds, def))) CFAIL()
#define OP_CHECK_NO_MORE_ARG(fname, n, vargs, r) \
- if (check_no_more_arg(fname, n, vargs) < 0) CFAIL()
+ if ((r=check_no_more_arg(fname, n, vargs)) < 0) CFAIL()
+#define OP_CHECK_SELF_NONZERO(fname, self, r) \
+ if ((r=check_self_nonzero(fname, self)) < 0) CFAIL()
unsigned long long RPyLong_AsUnsignedLongLong(PyObject *v);
long long RPyLong_AsLongLong(PyObject *v);
Modified: pypy/dist/pypy/translator/c/src/support.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/support.h (original)
+++ pypy/dist/pypy/translator/c/src/support.h Sat Apr 29 03:43:15 2006
@@ -46,9 +46,10 @@
PyObject* decode_arg(PyObject* fname, int position, PyObject* name,
PyObject* vargs, PyObject* vkwds, PyObject* def);
int check_no_more_arg(PyObject* fname, int n, PyObject* vargs);
+int check_self_nonzero(PyObject* fname, PyObject* self);
PyObject *PyTuple_GetItem_WithIncref(PyObject *tuple, int index);
int PyTuple_SetItem_WithIncref(PyObject *tuple, int index, PyObject *o);
-
+int PySequence_Contains_with_exc(PyObject *seq, PyObject *ob);
/* implementations */
@@ -387,6 +388,17 @@
return 0;
}
+int check_self_nonzero(PyObject* fname, PyObject* self)
+{
+ if (!self) {
+ PyErr_Format(PyExc_TypeError,
+ "%s() expects instance first arg",
+ PyString_AS_STRING(fname));
+ return -1;
+ }
+ return 0;
+}
+
/************************************************************/
PyObject *PyTuple_GetItem_WithIncref(PyObject *tuple, int index)
@@ -402,6 +414,15 @@
return PyTuple_SetItem(tuple, index, o);
}
+int PySequence_Contains_with_exc(PyObject *seq, PyObject *ob)
+{
+ int ret = PySequence_Contains(seq, ob);
+
+ if (ret < 0)
+ CFAIL();
+ return ret;
+}
+
#endif /* PYPY_STANDALONE */
#endif /* PYPY_NOT_MAIN_FILE */
Modified: pypy/dist/pypy/translator/c/test/test_wrapping.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_wrapping.py (original)
+++ pypy/dist/pypy/translator/c/test/test_wrapping.py Sat Apr 29 03:43:15 2006
@@ -4,15 +4,15 @@
from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.annotation import model as annmodel
from pypy.rpython.lltypesystem import lltype
-from pypy.rpython import robject, rclass
+from pypy.rpython import robject, rclass, rint
from pypy.translator.tool.cbuild import enable_fast_compilation
import sys, types
P = False # debug printing
-def get_annotation(func):
- argstypelist = []
+def get_annotation(func, pre=[]):
+ argstypelist = pre[:]
if func.func_defaults:
for spec in func.func_defaults:
if isinstance(spec, tuple):
@@ -46,15 +46,26 @@
for obj in exports:
if isinstance(obj, type):
- clsdef = bk.getuniqueclassdef(obj)
+ cls = obj
+ clsdef = bk.getuniqueclassdef(cls)
rtyper.add_wrapper(clsdef)
+ for obj in cls.__dict__.values():
+ if isinstance(obj, types.FunctionType):
+ if not ann.bookkeeper.getdesc(obj).querycallfamily():
+ # not annotated, so enforce it
+ ann.build_types(obj, get_annotation(obj, [cls]), complete_now=False)
+ elif isinstance(obj, property):
+ for obj in obj.fget, obj.fset, obj.fdel:
+ if obj and not ann.bookkeeper.getdesc(obj).querycallfamily():
+ ann.build_types(obj, get_annotation(obj, [cls]), complete_now=False)
elif isinstance(obj, types.FunctionType):
if not ann.bookkeeper.getdesc(obj).querycallfamily():
# not annotated, so enforce it
- ann.build_types(obj, get_annotation(obj))
+ ann.build_types(obj, get_annotation(obj), complete_now=False)
if obj.__name__ == '__init__':
pyobj_options['use_true_methods'] = True
+ ann.build_types(func, get_annotation(func))
if view:
t.viewcg()
rtyper.specialize()
@@ -172,6 +183,10 @@
#return type(self)(self.a + other.a, self.b + other.b)
return DemoClass(self.a + other.a, self.b + other.b)
+ def ab(self):
+ return self.a + self.b
+ ab = property(ab)
+
# see if we get things exported with subclassing
class DemoSubclass(DemoClass):
def __init__(self, a, b, c):
@@ -252,6 +267,10 @@
def specialize_call(self, hop):
v_idx, = hop.inputargs(*hop.args_r)
+ if hop.args_r[0] <> rint.signed_repr:
+ v_idx = hop.llops.convertvar(v_idx,
+ r_from=hop.args_r[0],
+ r_to=rint.signed_repr)
v_res = hop.llops.gencapicall('postsetup_get_methodname', [v_idx],
resulttype=robject.pyobj_repr)
return v_res
@@ -265,6 +284,12 @@
def specialize_call(self, hop):
v_idx, v_type = hop.inputargs(*hop.args_r)
+ if hop.args_r[0] <> rint.signed_repr:
+ v_idx = hop.llops.convertvar(v_idx,
+ r_from=hop.args_r[0],
+ r_to=rint.signed_repr)
+ assert hop.args_r[1] == robject.pyobj_repr, (
+ 'build_method works for Python types only')
v_res = hop.llops.gencapicall('postsetup_build_method', [v_idx, v_type],
resulttype=robject.pyobj_repr)
return v_res
@@ -278,6 +303,8 @@
def specialize_call(self, hop):
v_type, = hop.inputargs(*hop.args_r)
+ assert hop.args_r[0] == robject.pyobj_repr, (
+ 'get_typedict works for Python types only')
v_res = hop.llops.gencapicall('postsetup_get_typedict', [v_type],
resulttype=robject.pyobj_repr)
return v_res
@@ -307,6 +334,43 @@
dic[methname] = meth
idx += 1
+def __init__(mod):
+ import types
+ import __builtin__ as bltn
+ hasattr = bltn.hasattr
+ isinstance = bltn.isinstance
+
+ funcs = bltn.dict() # no hashing function for PyObject
+ idx = 0
+ while 1:
+ name = get_methodname(idx)
+ if not name:
+ break
+ func = getattr(mod, name)
+ funcs[func] = idx
+ idx += 1
+
+ for name in mod.__all__:
+ obj = getattr(mod, name)
+ if isinstance(obj, type) and hasattr(obj, '__self__'):
+ cls = obj
+ dic = get_typedict(cls)
+ for name, value in dic.items():
+ if isinstance(value, types.BuiltinFunctionType) and value in funcs:
+ idx = funcs[value]
+ meth = build_method(idx, cls)
+ dic[name] = meth
+ elif isinstance(value, property):
+ stuff = [value.fget, value.fset, value.fdel, value.__doc__]
+ for i, fn in enumerate(stuff):
+ if fn in funcs:
+ idx = funcs[fn]
+ stuff[i] = build_method(idx, cls)
+ if not stuff[-1]:
+ # use fget's doc if we don't ahve one
+ stuff[-1] = getattr(stuff[0], '__doc__', None)
+ dic[name] = property(*stuff)
+
# creating an object, wrapping, unwrapping, call function, check whether __del__ is called
def test_wrap_call_dtor():
f = getcompiled(democlass_helper, use_boehm=not True, exports=[DemoSubclass])
@@ -317,7 +381,7 @@
# exposing and using classes from a generasted extension module
def test_expose_classes():
m = get_compiled_module(democlass_helper2, use_boehm=not True, exports=[
- DemoClass, DemoSubclass, DemoNotAnnotated, __init__])
+ DemoClass, DemoSubclass, __init__, DemoNotAnnotated])
obj = m.DemoClass(2, 3)
res = obj.demo()
assert res == DemoClass(2, 3).demo()
Modified: pypy/dist/pypy/translator/c/wrapper.py
==============================================================================
--- pypy/dist/pypy/translator/c/wrapper.py (original)
+++ pypy/dist/pypy/translator/c/wrapper.py Sat Apr 29 03:43:15 2006
@@ -101,12 +101,14 @@
inputconst(Signed, nb_positional_args),
vargs,
]
- newops.genop('check_no_more_arg', vlist)
+ newops.genop('check_no_more_arg', vlist, resulttype=Signed)
# use the rtyper to produce the conversions
inputargs = f._obj.graph.getargs()
if as_method:
varguments.insert(0, vself)
+ vlist = [vfname, vself]
+ newops.genop('check_self_nonzero', vlist, resulttype=Signed)
for i in range(len(varguments)):
if FUNCTYPE.ARGS[i] != PyObjPtr:
# "argument_i = type_conversion_operations(argument_i)"
More information about the Pypy-commit
mailing list