PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/module/cpyext/test/test_funcobject.py

https://bitbucket.org/pypy/pypy/
Python | 111 lines | 109 code | 2 blank | 0 comment | 0 complexity | d80807f1410bccb034035393d7ab067e MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.rtyper.lltypesystem import rffi, lltype
  2. from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
  3. from pypy.module.cpyext.test.test_api import BaseApiTest
  4. from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref
  5. from pypy.module.cpyext.funcobject import (
  6. PyFunctionObject, PyCodeObject, CODE_FLAGS)
  7. from pypy.interpreter.function import Function, Method
  8. from pypy.interpreter.pycode import PyCode
  9. globals().update(CODE_FLAGS)
  10. class TestFunctionObject(BaseApiTest):
  11. def test_function(self, space, api):
  12. w_function = space.appexec([], """():
  13. def f(): pass
  14. return f
  15. """)
  16. ref = make_ref(space, w_function)
  17. assert (from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is
  18. space.gettypeobject(Function.typedef))
  19. assert "f" == space.unwrap(
  20. from_ref(space, rffi.cast(PyFunctionObject, ref).c_func_name))
  21. api.Py_DecRef(ref)
  22. def test_method(self, space, api):
  23. w_method = space.appexec([], """():
  24. class C(list):
  25. def method(self): pass
  26. return C().method
  27. """)
  28. w_function = space.getattr(w_method, space.wrap("im_func"))
  29. w_self = space.getattr(w_method, space.wrap("im_self"))
  30. w_class = space.getattr(w_method, space.wrap("im_class"))
  31. assert space.is_w(api.PyMethod_Function(w_method), w_function)
  32. assert space.is_w(api.PyMethod_Self(w_method), w_self)
  33. assert space.is_w(api.PyMethod_Class(w_method), w_class)
  34. w_method2 = api.PyMethod_New(w_function, w_self, w_class)
  35. assert space.eq_w(w_method, w_method2)
  36. def test_getcode(self, space, api):
  37. w_function = space.appexec([], """():
  38. def func(x, y, z): return x
  39. return func
  40. """)
  41. w_code = api.PyFunction_GetCode(w_function)
  42. assert w_code.co_name == "func"
  43. ref = make_ref(space, w_code)
  44. assert (from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is
  45. space.gettypeobject(PyCode.typedef))
  46. assert "func" == space.unwrap(
  47. from_ref(space, rffi.cast(PyCodeObject, ref).c_co_name))
  48. assert 3 == rffi.cast(PyCodeObject, ref).c_co_argcount
  49. api.Py_DecRef(ref)
  50. def test_co_flags(self, space, api):
  51. def get_flags(signature, body="pass"):
  52. w_code = space.appexec([], """():
  53. def func(%s): %s
  54. return func.__code__
  55. """ % (signature, body))
  56. ref = make_ref(space, w_code)
  57. co_flags = rffi.cast(PyCodeObject, ref).c_co_flags
  58. api.Py_DecRef(ref)
  59. return co_flags
  60. assert get_flags("x") == CO_NESTED | CO_OPTIMIZED | CO_NEWLOCALS
  61. assert get_flags("x", "exec x") == CO_NESTED | CO_NEWLOCALS
  62. assert get_flags("x, *args") & CO_VARARGS
  63. assert get_flags("x, **kw") & CO_VARKEYWORDS
  64. assert get_flags("x", "yield x") & CO_GENERATOR
  65. def test_newcode(self, space, api):
  66. filename = rffi.str2charp('filename')
  67. funcname = rffi.str2charp('funcname')
  68. w_code = api.PyCode_NewEmpty(filename, funcname, 3)
  69. assert w_code.co_filename == 'filename'
  70. assert w_code.co_firstlineno == 3
  71. ref = make_ref(space, w_code)
  72. assert "filename" == space.unwrap(
  73. from_ref(space, rffi.cast(PyCodeObject, ref).c_co_filename))
  74. api.Py_DecRef(ref)
  75. rffi.free_charp(filename)
  76. rffi.free_charp(funcname)
  77. def test_getnumfree(self, space, api):
  78. w_function = space.appexec([], """():
  79. a = 5
  80. def method(x): return a, x
  81. return method
  82. """)
  83. assert api.PyCode_GetNumFree(w_function.code) == 1
  84. def test_classmethod(self, space, api):
  85. w_function = space.appexec([], """():
  86. def method(x): return x
  87. return method
  88. """)
  89. w_class = space.call_function(space.w_type, space.wrap("C"),
  90. space.newtuple([]), space.newdict())
  91. w_instance = space.call_function(w_class)
  92. # regular instance method
  93. space.setattr(w_class, space.wrap("method"), w_function)
  94. assert space.is_w(space.call_method(w_instance, "method"), w_instance)
  95. # now a classmethod
  96. w_classmethod = api.PyClassMethod_New(w_function)
  97. space.setattr(w_class, space.wrap("classmethod"), w_classmethod)
  98. assert space.is_w(space.call_method(w_instance, "classmethod"), w_class)