Author: Amaury Forgeot d'Arc <[email protected]>
Branch: kill-faking
Changeset: r59296:206365af3c75
Date: 2012-12-03 22:41 +0100
http://bitbucket.org/pypy/pypy/changeset/206365af3c75/
Log: Fixes for cpyext module: use space.applevel instead of wrapping
everything
diff --git a/pypy/module/cpyext/state.py b/pypy/module/cpyext/state.py
--- a/pypy/module/cpyext/state.py
+++ b/pypy/module/cpyext/state.py
@@ -78,11 +78,7 @@
from pypy.module.cpyext.api import INIT_FUNCTIONS
setup_new_method_def(space)
- if not we_are_translated():
- space.setattr(space.wrap(self),
- space.wrap('api_lib'),
- space.wrap(self.api_lib))
- else:
+ if we_are_translated():
refcountstate = space.fromcache(RefcountState)
refcountstate.init_r2w_from_w2r()
diff --git a/pypy/module/cpyext/test/test_cpyext.py
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -5,7 +5,7 @@
import py
from pypy.interpreter.error import OperationError
-from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.rpython.lltypesystem import rffi, lltype, ll2ctypes
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.translator import platform
@@ -32,7 +32,7 @@
assert 'PyModule_Check' in api.FUNCTIONS
assert api.FUNCTIONS['PyModule_Check'].argtypes == [api.PyObject]
-def compile_module(space, modname, **kwds):
+def compile_extension_module(space, modname, **kwds):
"""
Build an extension module and return the filename of the resulting native
code file.
@@ -43,6 +43,17 @@
Any extra keyword arguments are passed on to ExternalCompilationInfo to
build the module (so specify your source with one of those).
"""
+ state = space.fromcache(State)
+ api_library = state.api_lib
+ if sys.platform == 'win32':
+ kwds["libraries"] = [api_library]
+ # '%s' undefined; assuming extern returning int
+ kwds["compile_extra"] = ["/we4013"]
+ else:
+ kwds["link_files"] = [str(api_library + '.so')]
+ if sys.platform.startswith('linux'):
+ kwds["compile_extra"]=["-Werror=implicit-function-declaration"]
+
modname = modname.split('.')[-1]
eci = ExternalCompilationInfo(
export_symbols=['init%s' % (modname,)],
@@ -71,7 +82,7 @@
class LeakCheckingTest(object):
"""Base class for all cpyext tests."""
spaceconfig = dict(usemodules=['cpyext', 'thread', '_rawffi', 'array',
- 'itertools'])
+ 'itertools', 'rctime', 'binascii'])
enable_leak_checking = True
@staticmethod
@@ -174,111 +185,124 @@
state = cls.space.fromcache(RefcountState)
state.non_heaptypes_w[:] = []
- def compile_module(self, name, **kwds):
- """
- Build an extension module linked against the cpyext api library.
- """
- state = self.space.fromcache(State)
- api_library = state.api_lib
- if sys.platform == 'win32':
- kwds["libraries"] = [api_library]
- # '%s' undefined; assuming extern returning int
- kwds["compile_extra"] = ["/we4013"]
- else:
- kwds["link_files"] = [str(api_library + '.so')]
- if sys.platform.startswith('linux'):
- kwds["compile_extra"]=["-Werror=implicit-function-declaration"]
- return compile_module(self.space, name, **kwds)
+ def setup_method(self, func):
+ @unwrap_spec(name=str)
+ def compile_module(space, name,
+ w_separate_module_files=None,
+ w_separate_module_sources=None):
+ """
+ Build an extension module linked against the cpyext api library.
+ """
+ if not space.is_none(w_separate_module_files):
+ separate_module_files =
space.listview_str(w_separate_module_files)
+ assert separate_module_files is not None
+ else:
+ separate_module_files = []
+ if not space.is_none(w_separate_module_sources):
+ separate_module_sources =
space.listview_str(w_separate_module_sources)
+ assert separate_module_sources is not None
+ else:
+ separate_module_sources = []
+ pydname = compile_extension_module(
+ space, name,
+ separate_module_files=separate_module_files,
+ separate_module_sources=separate_module_sources)
+ return space.wrap(pydname)
+ @unwrap_spec(name=str, init='str_or_None', body=str,
+ load_it=bool, filename='str_or_None')
+ def import_module(space, name, init=None, body='',
+ load_it=True, filename=None):
+ """
+ init specifies the overall template of the module.
- def import_module(self, name, init=None, body='', load_it=True,
filename=None):
- """
- init specifies the overall template of the module.
+ if init is None, the module source will be loaded from a file in
this
+ test direcory, give a name given by the filename parameter.
- if init is None, the module source will be loaded from a file in this
- test direcory, give a name given by the filename parameter.
+ if filename is None, the module name will be used to construct the
+ filename.
+ """
+ if init is not None:
+ code = """
+ #include <Python.h>
+ %(body)s
- if filename is None, the module name will be used to construct the
- filename.
- """
- if init is not None:
- code = """
- #include <Python.h>
- %(body)s
+ void init%(name)s(void) {
+ %(init)s
+ }
+ """ % dict(name=name, init=init, body=body)
+ kwds = dict(separate_module_sources=[code])
+ else:
+ if filename is None:
+ filename = name
+ filename = py.path.local(autopath.pypydir) / 'module' \
+ / 'cpyext'/ 'test' / (filename + ".c")
+ kwds = dict(separate_module_files=[filename])
- void init%(name)s(void) {
- %(init)s
- }
- """ % dict(name=name, init=init, body=body)
- kwds = dict(separate_module_sources=[code])
- else:
- if filename is None:
- filename = name
- filename = py.path.local(autopath.pypydir) / 'module' \
- / 'cpyext'/ 'test' / (filename + ".c")
- kwds = dict(separate_module_files=[filename])
+ mod = compile_extension_module(space, name, **kwds)
- mod = self.compile_module(name, **kwds)
+ if load_it:
+ api.load_extension_module(space, mod, name)
+ self.imported_module_names.append(name)
+ return space.getitem(
+ space.sys.get('modules'),
+ space.wrap(name))
+ else:
+ return os.path.dirname(mod)
- if load_it:
- api.load_extension_module(self.space, mod, name)
+ @unwrap_spec(mod=str, name=str)
+ def reimport_module(space, mod, name):
+ api.load_extension_module(space, mod, name)
+ return space.getitem(
+ space.sys.get('modules'),
+ space.wrap(name))
+
+ @unwrap_spec(modname=str, prologue=str)
+ def import_extension(space, modname, w_functions, prologue=""):
+ functions = space.unwrap(w_functions)
+ methods_table = []
+ codes = []
+ for funcname, flags, code in functions:
+ cfuncname = "%s_%s" % (modname, funcname)
+ methods_table.append("{\"%s\", %s, %s}," %
+ (funcname, cfuncname, flags))
+ func_code = """
+ static PyObject* %s(PyObject* self, PyObject* args)
+ {
+ %s
+ }
+ """ % (cfuncname, code)
+ codes.append(func_code)
+
+ body = prologue + "\n".join(codes) + """
+ static PyMethodDef methods[] = {
+ %s
+ { NULL }
+ };
+ """ % ('\n'.join(methods_table),)
+ init = """Py_InitModule("%s", methods);""" % (modname,)
+ return import_module(space, name=modname, init=init, body=body)
+
+ @unwrap_spec(name=str)
+ def record_imported_module(name):
+ """
+ Record a module imported in a test so that it can be cleaned up in
+ teardown before the check for leaks is done.
+
+ name gives the name of the module in the space's sys.modules.
+ """
self.imported_module_names.append(name)
- return self.space.getitem(
- self.space.sys.get('modules'),
- self.space.wrap(name))
- else:
- return os.path.dirname(mod)
- def reimport_module(self, mod, name):
- api.load_extension_module(self.space, mod, name)
- return self.space.getitem(
- self.space.sys.get('modules'),
- self.space.wrap(name))
-
- def import_extension(self, modname, functions, prologue=""):
- methods_table = []
- codes = []
- for funcname, flags, code in functions:
- cfuncname = "%s_%s" % (modname, funcname)
- methods_table.append("{\"%s\", %s, %s}," %
- (funcname, cfuncname, flags))
- func_code = """
- static PyObject* %s(PyObject* self, PyObject* args)
- {
- %s
- }
- """ % (cfuncname, code)
- codes.append(func_code)
-
- body = prologue + "\n".join(codes) + """
- static PyMethodDef methods[] = {
- %s
- { NULL }
- };
- """ % ('\n'.join(methods_table),)
- init = """Py_InitModule("%s", methods);""" % (modname,)
- return self.import_module(name=modname, init=init, body=body)
-
- def record_imported_module(self, name):
- """
- Record a module imported in a test so that it can be cleaned up in
- teardown before the check for leaks is done.
-
- name gives the name of the module in the space's sys.modules.
- """
- self.imported_module_names.append(name)
-
- def setup_method(self, func):
# A list of modules which the test caused to be imported (in
# self.space). These will be cleaned up automatically in teardown.
self.imported_module_names = []
- self.w_import_module = self.space.wrap(self.import_module)
- self.w_reimport_module = self.space.wrap(self.reimport_module)
- self.w_import_extension = self.space.wrap(self.import_extension)
- self.w_compile_module = self.space.wrap(self.compile_module)
+ self.w_compile_module = self.space.wrap(interp2app(compile_module))
+ self.w_import_module = self.space.wrap(interp2app(import_module))
+ self.w_reimport_module = self.space.wrap(interp2app(reimport_module))
+ self.w_import_extension = self.space.wrap(interp2app(import_extension))
self.w_record_imported_module = self.space.wrap(
- self.record_imported_module)
+ interp2app(record_imported_module))
self.w_here = self.space.wrap(
str(py.path.local(autopath.pypydir)) + '/module/cpyext/test/')
diff --git a/pypy/module/cpyext/test/test_datetime.py
b/pypy/module/cpyext/test/test_datetime.py
--- a/pypy/module/cpyext/test/test_datetime.py
+++ b/pypy/module/cpyext/test/test_datetime.py
@@ -78,6 +78,10 @@
("get_types", "METH_NOARGS",
"""
PyDateTime_IMPORT;
+ if (!PyDateTimeAPI) {
+ PyErr_SetString(PyExc_RuntimeError, "No PyDateTimeAPI");
+ return NULL;
+ }
return PyTuple_Pack(4,
PyDateTimeAPI->DateType,
PyDateTimeAPI->DateTimeType,
diff --git a/pypy/module/cpyext/test/test_floatobject.py
b/pypy/module/cpyext/test/test_floatobject.py
--- a/pypy/module/cpyext/test/test_floatobject.py
+++ b/pypy/module/cpyext/test/test_floatobject.py
@@ -15,11 +15,12 @@
assert space.type(api.PyNumber_Float(space.wrap(3))) is space.w_float
assert space.type(api.PyNumber_Float(space.wrap("3"))) is space.w_float
- class Coerce(object):
- def __float__(self):
- return 42.5
- assert space.eq_w(api.PyNumber_Float(space.wrap(Coerce())),
- space.wrap(42.5))
+ w_obj = space.appexec([], """():
+ class Coerce(object):
+ def __float__(self):
+ return 42.5
+ return Coerce()""")
+ assert space.eq_w(api.PyNumber_Float(w_obj), space.wrap(42.5))
def test_unpack(self, space, api):
with rffi.scoped_str2charp("\x9a\x99\x99?") as ptr:
diff --git a/pypy/module/cpyext/test/test_intobject.py
b/pypy/module/cpyext/test/test_intobject.py
--- a/pypy/module/cpyext/test/test_intobject.py
+++ b/pypy/module/cpyext/test/test_intobject.py
@@ -40,10 +40,12 @@
== 10**30 % (2**64))
def test_coerce(self, space, api):
- class Coerce(object):
- def __int__(self):
- return 42
- assert api.PyInt_AsLong(space.wrap(Coerce())) == 42
+ w_obj = space.appexec([], """():
+ class Coerce(object):
+ def __int__(self):
+ return 42
+ return Coerce()""")
+ assert api.PyInt_AsLong(w_obj) == 42
class AppTestIntObject(AppTestCpythonExtensionBase):
def test_fromstring(self):
diff --git a/pypy/module/cpyext/test/test_iterator.py
b/pypy/module/cpyext/test/test_iterator.py
--- a/pypy/module/cpyext/test/test_iterator.py
+++ b/pypy/module/cpyext/test/test_iterator.py
@@ -3,9 +3,9 @@
class TestIterator(BaseApiTest):
def test_check_iter(self, space, api):
- assert api.PyIter_Check(space.wrap(iter("a")))
- assert api.PyIter_Check(space.wrap(iter([])))
- assert not api.PyIter_Check(space.wrap(type))
+ assert api.PyIter_Check(space.iter(space.wrap("a")))
+ assert api.PyIter_Check(space.iter(space.newlist([])))
+ assert not api.PyIter_Check(space.w_type)
assert not api.PyIter_Check(space.wrap(2))
def test_getIter(self, space, api):
diff --git a/pypy/module/cpyext/test/test_object.py
b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -19,12 +19,14 @@
assert api.PyObject_Not(space.wrap(3.14)) == 0
def test_exception(self, space, api):
- class C:
- def __nonzero__(self):
- raise ValueError
+ w_obj = space.appexec([], """():
+ class C:
+ def __nonzero__(self):
+ raise ValueError
+ return C()""")
- assert api.PyObject_IsTrue(space.wrap(C())) == -1
- assert api.PyObject_Not(space.wrap(C())) == -1
+ assert api.PyObject_IsTrue(w_obj) == -1
+ assert api.PyObject_Not(w_obj) == -1
api.PyErr_Clear()
def test_HasAttr(self, space, api):
@@ -40,20 +42,22 @@
rffi.free_charp(buf)
def test_SetAttr(self, space, api):
- class X:
- pass
- x = X()
- api.PyObject_SetAttr(space.wrap(x), space.wrap('test'), space.wrap(5))
+ w_obj = space.appexec([], """():
+ class C:
+ pass
+ return C()""")
+
+ api.PyObject_SetAttr(w_obj, space.wrap('test'), space.wrap(5))
assert not api.PyErr_Occurred()
- assert x.test == 5
- assert api.PyObject_HasAttr(space.wrap(x), space.wrap('test'))
- api.PyObject_SetAttr(space.wrap(x), space.wrap('test'), space.wrap(10))
- assert x.test == 10
+ assert space.unwrap(space.getattr(w_obj, space.wrap('test'))) == 5
+ assert api.PyObject_HasAttr(w_obj, space.wrap('test'))
+ api.PyObject_SetAttr(w_obj, space.wrap('test'), space.wrap(10))
+ assert space.unwrap(space.getattr(w_obj, space.wrap('test'))) == 10
buf = rffi.str2charp('test')
- api.PyObject_SetAttrString(space.wrap(x), buf, space.wrap(20))
+ api.PyObject_SetAttrString(w_obj, buf, space.wrap(20))
rffi.free_charp(buf)
- assert x.test == 20
+ assert space.unwrap(space.getattr(w_obj, space.wrap('test'))) == 20
def test_getattr(self, space, api):
charp1 = rffi.str2charp("__len__")
diff --git a/pypy/module/cpyext/test/test_sequence.py
b/pypy/module/cpyext/test/test_sequence.py
--- a/pypy/module/cpyext/test/test_sequence.py
+++ b/pypy/module/cpyext/test/test_sequence.py
@@ -132,7 +132,8 @@
assert api.PyErr_Occurred() is space.w_ValueError
api.PyErr_Clear()
- gen = (x ** 2 for x in range(40))
+ w_gen = space.appexec([], """():
+ return (x ** 2 for x in range(40))""")
w_tofind = space.wrap(16)
- result = api.PySequence_Index(space.wrap(gen), w_tofind)
+ result = api.PySequence_Index(w_gen, w_tofind)
assert result == 4
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit