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

https://bitbucket.org/pypy/pypy/ · Python · 113 lines · 95 code · 15 blank · 3 comment · 8 complexity · fabc943b60822b1db85af2121e41fc3e MD5 · raw file

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