PageRenderTime 29ms CodeModel.GetById 20ms app.highlight 6ms RepoModel.GetById 2ms app.codeStats 0ms

/pypy/module/cpyext/test/test_api.py

https://bitbucket.org/pypy/pypy/
Python | 113 lines | 108 code | 2 blank | 3 comment | 2 complexity | fabc943b60822b1db85af2121e41fc3e MD5 | raw file
  1import py, pytest
  2from rpython.rtyper.lltypesystem import rffi, lltype
  3from pypy.interpreter.baseobjspace import W_Root
  4from pypy.module.cpyext.state import State
  5from pypy.module.cpyext import api
  6from pypy.module.cpyext.test.test_cpyext import freeze_refcnts, LeakCheckingTest
  7PyObject = api.PyObject
  8from pypy.interpreter.error import OperationError
  9from rpython.rlib import rawrefcount
 10import os
 11
 12@api.cpython_api([PyObject], lltype.Void)
 13def PyPy_GetWrapped(space, w_arg):
 14    assert isinstance(w_arg, W_Root)
 15@api.cpython_api([PyObject], lltype.Void)
 16def PyPy_GetReference(space, arg):
 17    assert lltype.typeOf(arg) ==  PyObject
 18
 19class BaseApiTest(LeakCheckingTest):
 20    def setup_class(cls):
 21        space = cls.space
 22        # warm up reference counts:
 23        # - the posix module allocates a HCRYPTPROV on Windows
 24        # - writing to stdout and stderr allocates a file lock
 25        space.getbuiltinmodule("cpyext")
 26        space.getbuiltinmodule(os.name)
 27        space.call_function(space.getattr(space.sys.get("stderr"),
 28                                          space.wrap("write")),
 29                            space.wrap(""))
 30        space.call_function(space.getattr(space.sys.get("stdout"),
 31                                          space.wrap("write")),
 32                            space.wrap(""))
 33
 34        class CAPI:
 35            def __getattr__(self, name):
 36                return getattr(cls.space, name)
 37        cls.api = CAPI()
 38        CAPI.__dict__.update(api.INTERPLEVEL_API)
 39
 40        print 'DONT_FREE_ANY_MORE'
 41        rawrefcount._dont_free_any_more()
 42
 43    def raises(self, space, api, expected_exc, f, *args):
 44        if not callable(f):
 45            raise Exception("%s is not callable" % (f,))
 46        f(*args)
 47        state = space.fromcache(State)
 48        operror = state.operror
 49        if not operror:
 50            raise Exception("DID NOT RAISE")
 51        if getattr(space, 'w_' + expected_exc.__name__) is not operror.w_type:
 52            raise Exception("Wrong exception")
 53        return state.clear_exception()
 54
 55    def setup_method(self, func):
 56        freeze_refcnts(self)
 57
 58    def teardown_method(self, func):
 59        state = self.space.fromcache(State)
 60        try:
 61            state.check_and_raise_exception()
 62        except OperationError as e:
 63            print e.errorstr(self.space)
 64            raise
 65
 66        try:
 67            self.space.getexecutioncontext().cleanup_cpyext_threadstate()
 68        except AttributeError:
 69            pass
 70
 71        if self.check_and_print_leaks():
 72            assert False, "Test leaks or loses object(s)."
 73
 74@api.cpython_api([api.Py_ssize_t], api.Py_ssize_t, error=-1)
 75def PyPy_TypedefTest1(space, arg):
 76    assert lltype.typeOf(arg) == api.Py_ssize_t
 77    return 0
 78
 79@api.cpython_api([api.Py_ssize_tP], api.Py_ssize_tP)
 80def PyPy_TypedefTest2(space, arg):
 81    assert lltype.typeOf(arg) == api.Py_ssize_tP
 82    return None
 83
 84class TestConversion(BaseApiTest):
 85    def test_conversions(self, space, api):
 86        api.PyPy_GetWrapped(space.w_None)
 87        api.PyPy_GetReference(space.w_None)
 88
 89    def test_typedef(self, space):
 90        from rpython.translator.c.database import LowLevelDatabase
 91        db = LowLevelDatabase()
 92        assert (api.c_function_signature(db, api.FUNCTIONS['PyPy_TypedefTest1'])
 93                == ('Py_ssize_t', 'Py_ssize_t arg0'))
 94        assert (api.c_function_signature(db, api.FUNCTIONS['PyPy_TypedefTest2'])
 95                == ('Py_ssize_t *', 'Py_ssize_t *arg0'))
 96
 97        PyPy_TypedefTest1(space, 0)
 98        ppos = lltype.malloc(api.Py_ssize_tP.TO, 1, flavor='raw')
 99        ppos[0] = 0
100        PyPy_TypedefTest2(space, ppos)
101        lltype.free(ppos, flavor='raw')
102
103@pytest.mark.skipif(os.environ.get('USER')=='root', 
104                    reason='root can write to all files')
105def test_copy_header_files(tmpdir):
106    api.copy_header_files(tmpdir, True)
107    def check(name):
108        f = tmpdir.join(name)
109        assert f.check(file=True)
110        py.test.raises(py.error.EACCES, "f.open('w')") # check that it's not writable
111    check('Python.h')
112    check('modsupport.h')
113    check('pypy_decl.h')