[pypy-svn] r36124 - in pypy/dist/pypy: rlib/rctypes rlib/rctypes/test rpython
arigo at codespeak.net
arigo at codespeak.net
Wed Jan 3 17:30:24 CET 2007
Author: arigo
Date: Wed Jan 3 17:30:22 2007
New Revision: 36124
Modified:
pypy/dist/pypy/rlib/rctypes/implementation.py
pypy/dist/pypy/rlib/rctypes/rchar_p.py
pypy/dist/pypy/rlib/rctypes/rprimitive.py
pypy/dist/pypy/rlib/rctypes/rstruct.py
pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py
pypy/dist/pypy/rpython/controllerentry.py
Log:
Minimally-tested support for keyword arguments in contructors,
used for the constructor of ctypes Structures.
Modified: pypy/dist/pypy/rlib/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/implementation.py (original)
+++ pypy/dist/pypy/rlib/rctypes/implementation.py Wed Jan 3 17:30:22 2007
@@ -69,6 +69,9 @@
raise TypeError("cannot store a value into a non-primitive ctype")
store_value._annspecialcase_ = 'specialize:arg(0)'
+ def default_ctype_value(self):
+ return self.ctype()
+
# extension to the setattr/setitem support: if the new value is actually
# a CTypeControlled instance as well, reveal it automatically (i.e. turn
# it into an rctypesobject) and call a method with a different name.
@@ -111,7 +114,7 @@
class CTypesCallEntry(ControllerEntry):
- def getcontroller(self, *args_s):
+ def getcontroller(self, *args_s, **kwds_s):
ctype = self.instance
return _build_controller(self._controller_, ctype)
Modified: pypy/dist/pypy/rlib/rctypes/rchar_p.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rchar_p.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rchar_p.py Wed Jan 3 17:30:22 2007
@@ -27,6 +27,9 @@
return_value = get_value
store_value = set_value
+ def default_ctype_value(self):
+ return None
+
def is_true(self, obj):
return obj.get_value() is not None
Modified: pypy/dist/pypy/rlib/rctypes/rprimitive.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rprimitive.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rprimitive.py Wed Jan 3 17:30:22 2007
@@ -80,6 +80,9 @@
return_value = get_value
store_value = set_value
+ def default_ctype_value(self):
+ return self.ctype().value
+
def is_true(self, obj):
llvalue = self.get_value(obj)
if self.is_char_type:
Modified: pypy/dist/pypy/rlib/rctypes/rstruct.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rstruct.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rstruct.py Wed Jan 3 17:30:22 2007
@@ -75,6 +75,61 @@
fieldbox = controller.convert(getattr(x, name))
self.setboxattr(obj, name, fieldbox)
+ def insert_constructor_keywords(self, lst, prefix, kwds):
+ lst = list(lst)
+ kwds = kwds.copy()
+ for index, (name, field_ctype) in enumerate(self.ctype._fields_):
+ if prefix+name in kwds:
+ value = kwds.pop(prefix+name)
+ while len(lst) <= index:
+ lst.append(None)
+ if lst[index] is not None:
+ raise TypeError("duplicate value for argument %r" % name)
+ lst[index] = value
+ if kwds:
+ raise TypeError("unknown keyword(s): %r" % (kwds.keys(),))
+ return lst
+
+ def ctrl_new_ex(self, bookkeeper, *args_s, **kwds_s):
+ if kwds_s:
+ args_s = self.insert_constructor_keywords(args_s, 's_', kwds_s)
+ for i in range(len(args_s)):
+ if args_s[i] is None:
+ name, controller = self.fieldcontrollers[i]
+ x = controller.default_ctype_value()
+ args_s[i] = bookkeeper.immutablevalue(x)
+ return CTypeController.ctrl_new(self, *args_s)
+
+ def rtype_new(self, hop, **kwds_i):
+ if kwds_i:
+ lst = range(hop.nb_args)
+ for key, index in kwds_i.items():
+ lst[index] = None
+ lst = self.insert_constructor_keywords(lst, 'i_', kwds_i)
+ hop2 = hop.copy()
+ hop2.nb_args = len(lst)
+ hop2.args_v = []
+ hop2.args_s = []
+ hop2.args_r = []
+ for i, index in enumerate(lst):
+ if index is not None:
+ v = hop.args_v[index]
+ s = hop.args_s[index]
+ r = hop.args_r[index]
+ else:
+ # must insert a default value
+ from pypy.objspace.flow.model import Constant
+ name, controller = self.fieldcontrollers[i]
+ x = controller.default_ctype_value()
+ v = Constant(x)
+ s = hop.rtyper.annotator.bookkeeper.immutablevalue(x)
+ r = hop.rtyper.getrepr(s)
+ hop2.args_v.append(v)
+ hop2.args_s.append(s)
+ hop2.args_r.append(r)
+ hop = hop2
+ return CTypeController.rtype_new(self, hop)
+
StructCTypeController.register_for_metatype(StructType)
Modified: pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py (original)
+++ pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py Wed Jan 3 17:30:22 2007
@@ -179,26 +179,26 @@
assert res == 289
def test_specialize_constructor_args(self):
- py.test.skip("in-progress")
+ #py.test.skip("in-progress")
class S(Structure):
_fields_ = [('x', c_int),
('y', c_char)]
- def func(x, y):
+ def func(x, y, n):
s0 = S(x)
s1 = S(x, y)
s2 = S(y=y)
s3 = S(x, y=y)
- return (s0, s1, s2, s3)
+ s = [s0, s1, s2, s3][n]
+ return s.x * 100 + ord(s.y)
- res = interpret(func, [4, '?'])
- assert res.item0.c_data.c_x == 4
- assert res.item0.c_data.c_y == '\x00'
- assert res.item1.c_data.c_x == 4
- assert res.item1.c_data.c_y == '?'
- assert res.item2.c_data.c_x == 0
- assert res.item2.c_data.c_y == '?'
- assert res.item3.c_data.c_x == 4
- assert res.item3.c_data.c_y == '?'
+ res = interpret(func, [4, '?', 0])
+ assert res == 400
+ res = interpret(func, [4, '?', 1])
+ assert res == 463
+ res = interpret(func, [4, '?', 2])
+ assert res == 63
+ res = interpret(func, [4, '?', 3])
+ assert res == 463
def test_specialize_bad_constructor_args(self):
py.test.skip("in-progress")
Modified: pypy/dist/pypy/rpython/controllerentry.py
==============================================================================
--- pypy/dist/pypy/rpython/controllerentry.py (original)
+++ pypy/dist/pypy/rpython/controllerentry.py Wed Jan 3 17:30:22 2007
@@ -8,20 +8,19 @@
class ControllerEntry(ExtRegistryEntry):
- def compute_result_annotation(self, *args_s):
- cls = self.instance
- controller = self.getcontroller(*args_s)
- return controller.ctrl_new(*args_s)
+ def compute_result_annotation(self, *args_s, **kwds_s):
+ controller = self.getcontroller(*args_s, **kwds_s)
+ return controller.ctrl_new_ex(self.bookkeeper, *args_s, **kwds_s)
- def getcontroller(self, *args_s):
+ def getcontroller(self, *args_s, **kwds_s):
return self._controller_()
- def specialize_call(self, hop):
+ def specialize_call(self, hop, **kwds_i):
if hop.s_result == annmodel.s_ImpossibleValue:
raise TyperError("object creation always raises: %s" % (
hop.spaceop,))
controller = hop.s_result.controller
- return controller.rtype_new(hop)
+ return controller.rtype_new(hop, **kwds_i)
@@ -65,13 +64,19 @@
return controlled_instance_is_box(self, obj)
is_box._annspecialcase_ = 'specialize:arg(0)'
- def ctrl_new(self, *args_s):
+ def ctrl_new(self, *args_s, **kwds_s):
+ if kwds_s:
+ raise TypeError("cannot handle keyword arguments in %s" % (
+ self.new,))
s_real_obj = delegate(self.new, *args_s)
if s_real_obj == annmodel.s_ImpossibleValue:
return annmodel.s_ImpossibleValue
else:
return SomeControlledInstance(s_real_obj, controller=self)
+ def ctrl_new_ex(self, bookkeeper, *args_s, **kwds_s):
+ return self.ctrl_new(*args_s, **kwds_s)
+
def rtype_new(self, hop):
from pypy.rpython.rcontrollerentry import rtypedelegate
return rtypedelegate(self.new, hop, revealargs=[], revealresult=True)
More information about the Pypy-commit
mailing list