PageRenderTime 65ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/module/cpyext/test/test_typeobject.py

https://bitbucket.org/evelyn559/pypy
Python | 456 lines | 412 code | 29 blank | 15 comment | 0 complexity | 8c535899e7cc22783c5c4058a91fef33 MD5 | raw file
  1. from pypy.rpython.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.typeobject import PyTypeObjectPtr
  6. import py
  7. import sys
  8. class AppTestTypeObject(AppTestCpythonExtensionBase):
  9. def test_typeobject(self):
  10. import sys
  11. module = self.import_module(name='foo')
  12. assert 'foo' in sys.modules
  13. assert "copy" in dir(module.fooType)
  14. obj = module.new()
  15. print obj.foo
  16. assert obj.foo == 42
  17. print "Obj has type", type(obj)
  18. assert type(obj) is module.fooType
  19. print "type of obj has type", type(type(obj))
  20. print "type of type of obj has type", type(type(type(obj)))
  21. def test_typeobject_method_descriptor(self):
  22. module = self.import_module(name='foo')
  23. obj = module.new()
  24. obj2 = obj.copy()
  25. assert module.new().name == "Foo Example"
  26. c = module.fooType.copy
  27. assert not "im_func" in dir(module.fooType.copy)
  28. assert module.fooType.copy.__objclass__ is module.fooType
  29. assert "copy" in repr(module.fooType.copy)
  30. assert repr(module.fooType) == "<type 'foo.foo'>"
  31. assert repr(obj2) == "<Foo>"
  32. assert repr(module.fooType.__call__) == "<slot wrapper '__call__' of 'foo' objects>"
  33. assert obj2(foo=1, bar=2) == dict(foo=1, bar=2)
  34. print obj.foo
  35. assert obj.foo == 42
  36. assert obj.int_member == obj.foo
  37. def test_typeobject_data_member(self):
  38. module = self.import_module(name='foo')
  39. obj = module.new()
  40. obj.int_member = 23
  41. assert obj.int_member == 23
  42. obj.int_member = 42
  43. raises(TypeError, "obj.int_member = 'not a number'")
  44. raises(TypeError, "del obj.int_member")
  45. raises(TypeError, "obj.int_member_readonly = 42")
  46. exc = raises(TypeError, "del obj.int_member_readonly")
  47. assert "readonly" in str(exc.value)
  48. raises(SystemError, "obj.broken_member")
  49. raises(SystemError, "obj.broken_member = 42")
  50. assert module.fooType.broken_member.__doc__ is None
  51. assert module.fooType.object_member.__doc__ == "A Python object."
  52. def test_typeobject_object_member(self):
  53. module = self.import_module(name='foo')
  54. obj = module.new()
  55. assert obj.object_member is None
  56. obj.object_member = "hello"
  57. assert obj.object_member == "hello"
  58. del obj.object_member
  59. del obj.object_member
  60. assert obj.object_member is None
  61. raises(AttributeError, "obj.object_member_ex")
  62. obj.object_member_ex = None
  63. assert obj.object_member_ex is None
  64. obj.object_member_ex = 42
  65. assert obj.object_member_ex == 42
  66. del obj.object_member_ex
  67. raises(AttributeError, "del obj.object_member_ex")
  68. obj.set_foo = 32
  69. assert obj.foo == 32
  70. def test_typeobject_string_member(self):
  71. module = self.import_module(name='foo')
  72. obj = module.new()
  73. assert obj.string_member == "Hello from PyPy"
  74. raises(TypeError, "obj.string_member = 42")
  75. raises(TypeError, "del obj.string_member")
  76. obj.unset_string_member()
  77. assert obj.string_member is None
  78. assert obj.string_member_inplace == "spam"
  79. raises(TypeError, "obj.string_member_inplace = 42")
  80. raises(TypeError, "del obj.string_member_inplace")
  81. assert obj.char_member == "s"
  82. obj.char_member = "a"
  83. assert obj.char_member == "a"
  84. raises(TypeError, "obj.char_member = 'spam'")
  85. raises(TypeError, "obj.char_member = 42")
  86. #
  87. import sys
  88. bignum = sys.maxint - 42
  89. obj.short_member = -12345; assert obj.short_member == -12345
  90. obj.long_member = -bignum; assert obj.long_member == -bignum
  91. obj.ushort_member = 45678; assert obj.ushort_member == 45678
  92. obj.uint_member = 3000000000; assert obj.uint_member == 3000000000
  93. obj.ulong_member = 2*bignum; assert obj.ulong_member == 2*bignum
  94. obj.byte_member = -99; assert obj.byte_member == -99
  95. obj.ubyte_member = 199; assert obj.ubyte_member == 199
  96. obj.bool_member = True; assert obj.bool_member is True
  97. obj.float_member = 9.25; assert obj.float_member == 9.25
  98. obj.double_member = 9.25; assert obj.double_member == 9.25
  99. obj.longlong_member = -2**59; assert obj.longlong_member == -2**59
  100. obj.ulonglong_member = 2**63; assert obj.ulonglong_member == 2**63
  101. #
  102. def test_staticmethod(self):
  103. module = self.import_module(name="foo")
  104. obj = module.fooType.create()
  105. assert obj.foo == 42
  106. obj2 = obj.create()
  107. assert obj2.foo == 42
  108. def test_new(self):
  109. module = self.import_module(name='foo')
  110. obj = module.new()
  111. # call __new__
  112. newobj = module.UnicodeSubtype(u"xyz")
  113. assert newobj == u"xyz"
  114. assert isinstance(newobj, module.UnicodeSubtype)
  115. assert isinstance(module.fooType(), module.fooType)
  116. class bar(module.fooType):
  117. pass
  118. assert isinstance(bar(), bar)
  119. fuu = module.UnicodeSubtype
  120. class fuu2(fuu):
  121. def baz(self):
  122. return self
  123. assert fuu2(u"abc").baz().escape()
  124. raises(TypeError, module.fooType.object_member.__get__, 1)
  125. def test_init(self):
  126. module = self.import_module(name="foo")
  127. newobj = module.UnicodeSubtype()
  128. assert newobj.get_val() == 42
  129. # this subtype should inherit tp_init
  130. newobj = module.UnicodeSubtype2()
  131. assert newobj.get_val() == 42
  132. # this subclass redefines __init__
  133. class UnicodeSubclass2(module.UnicodeSubtype):
  134. def __init__(self):
  135. self.foobar = 32
  136. super(UnicodeSubclass2, self).__init__()
  137. newobj = UnicodeSubclass2()
  138. assert newobj.get_val() == 42
  139. assert newobj.foobar == 32
  140. def test_metatype(self):
  141. module = self.import_module(name='foo')
  142. assert module.MetaType.__mro__ == (module.MetaType, type, object)
  143. x = module.MetaType('name', (), {})
  144. assert isinstance(x, type)
  145. assert isinstance(x, module.MetaType)
  146. x()
  147. def test_metaclass_compatible(self):
  148. # metaclasses should not conflict here
  149. module = self.import_module(name='foo')
  150. assert module.MetaType.__mro__ == (module.MetaType, type, object)
  151. assert type(module.fooType).__mro__ == (type, object)
  152. y = module.MetaType('other', (module.fooType,), {})
  153. assert isinstance(y, module.MetaType)
  154. x = y()
  155. del x, y
  156. def test_sre(self):
  157. module = self.import_module(name='_sre')
  158. import sre_compile
  159. sre_compile._sre = module
  160. assert sre_compile.MAGIC == module.MAGIC
  161. import re
  162. import time
  163. s = u"Foo " * 1000 + u"Bar"
  164. prog = re.compile(ur"Foo.*Bar")
  165. assert prog.match(s)
  166. m = re.search(u"xyz", u"xyzxyz")
  167. assert m
  168. m = re.search("xyz", "xyzxyz")
  169. assert m
  170. assert "groupdict" in dir(m)
  171. re._cache.clear()
  172. re._cache_repl.clear()
  173. del prog, m
  174. def test_init_error(self):
  175. module = self.import_module("foo")
  176. raises(ValueError, module.InitErrType)
  177. def test_cmps(self):
  178. module = self.import_module("comparisons")
  179. cmpr = module.CmpType()
  180. assert cmpr == 3
  181. assert cmpr != 42
  182. def test_richcompare(self):
  183. module = self.import_module("comparisons")
  184. cmpr = module.CmpType()
  185. # should not crash
  186. cmpr < 4
  187. cmpr <= 4
  188. cmpr > 4
  189. cmpr >= 4
  190. assert cmpr.__le__(4) is NotImplemented
  191. def test_tpcompare(self):
  192. module = self.import_module("comparisons")
  193. cmpr = module.OldCmpType()
  194. assert cmpr < cmpr
  195. def test_hash(self):
  196. module = self.import_module("comparisons")
  197. cmpr = module.CmpType()
  198. assert hash(cmpr) == 3
  199. d = {}
  200. d[cmpr] = 72
  201. assert d[cmpr] == 72
  202. assert d[3] == 72
  203. def test_descriptor(self):
  204. module = self.import_module("foo")
  205. prop = module.Property()
  206. class C(object):
  207. x = prop
  208. obj = C()
  209. assert obj.x == (prop, obj, C)
  210. assert C.x == (prop, None, C)
  211. obj.x = 2
  212. assert obj.y == (prop, 2)
  213. del obj.x
  214. assert obj.z == prop
  215. def test_tp_dict(self):
  216. foo = self.import_module("foo")
  217. module = self.import_extension('test', [
  218. ("read_tp_dict", "METH_O",
  219. '''
  220. PyObject *method;
  221. if (!args->ob_type->tp_dict)
  222. {
  223. PyErr_SetNone(PyExc_ValueError);
  224. return NULL;
  225. }
  226. method = PyDict_GetItemString(
  227. args->ob_type->tp_dict, "copy");
  228. Py_INCREF(method);
  229. return method;
  230. '''
  231. )
  232. ])
  233. obj = foo.new()
  234. assert module.read_tp_dict(obj) == foo.fooType.copy
  235. def test_custom_allocation(self):
  236. foo = self.import_module("foo")
  237. obj = foo.newCustom()
  238. assert type(obj) is foo.Custom
  239. assert type(foo.Custom) is foo.MetaType
  240. def test_heaptype(self):
  241. module = self.import_extension('foo', [
  242. ("name_by_heaptype", "METH_O",
  243. '''
  244. PyHeapTypeObject *heaptype = (PyHeapTypeObject *)args;
  245. Py_INCREF(heaptype->ht_name);
  246. return heaptype->ht_name;
  247. '''
  248. )
  249. ])
  250. class C(object):
  251. pass
  252. assert module.name_by_heaptype(C) == "C"
  253. class TestTypes(BaseApiTest):
  254. def test_type_attributes(self, space, api):
  255. w_class = space.appexec([], """():
  256. class A(object):
  257. pass
  258. return A
  259. """)
  260. ref = make_ref(space, w_class)
  261. py_type = rffi.cast(PyTypeObjectPtr, ref)
  262. assert py_type.c_tp_alloc
  263. assert from_ref(space, py_type.c_tp_mro).wrappeditems is w_class.mro_w
  264. api.Py_DecRef(ref)
  265. def test_multiple_inheritance(self, space, api):
  266. w_class = space.appexec([], """():
  267. class A(object):
  268. pass
  269. class B(object):
  270. pass
  271. class C(A, B):
  272. pass
  273. return C
  274. """)
  275. ref = make_ref(space, w_class)
  276. api.Py_DecRef(ref)
  277. def test_lookup(self, space, api):
  278. w_type = space.w_str
  279. w_obj = api._PyType_Lookup(w_type, space.wrap("upper"))
  280. assert space.is_w(w_obj, space.w_str.getdictvalue(space, "upper"))
  281. w_obj = api._PyType_Lookup(w_type, space.wrap("__invalid"))
  282. assert w_obj is None
  283. assert api.PyErr_Occurred() is None
  284. class AppTestSlots(AppTestCpythonExtensionBase):
  285. def test_some_slots(self):
  286. module = self.import_extension('foo', [
  287. ("test_type", "METH_O",
  288. '''
  289. if (!args->ob_type->tp_setattro)
  290. {
  291. PyErr_SetString(PyExc_ValueError, "missing tp_setattro");
  292. return NULL;
  293. }
  294. if (args->ob_type->tp_setattro ==
  295. args->ob_type->tp_base->tp_setattro)
  296. {
  297. PyErr_SetString(PyExc_ValueError, "recursive tp_setattro");
  298. return NULL;
  299. }
  300. Py_RETURN_TRUE;
  301. '''
  302. )
  303. ])
  304. assert module.test_type(type(None))
  305. def test_nb_int(self):
  306. module = self.import_extension('foo', [
  307. ("nb_int", "METH_O",
  308. '''
  309. if (!args->ob_type->tp_as_number ||
  310. !args->ob_type->tp_as_number->nb_int)
  311. {
  312. PyErr_SetNone(PyExc_ValueError);
  313. return NULL;
  314. }
  315. return args->ob_type->tp_as_number->nb_int(args);
  316. '''
  317. )
  318. ])
  319. assert module.nb_int(10) == 10
  320. assert module.nb_int(-12.3) == -12
  321. raises(ValueError, module.nb_int, "123")
  322. def test_tp_call(self):
  323. module = self.import_extension('foo', [
  324. ("tp_call", "METH_VARARGS",
  325. '''
  326. PyObject *obj = PyTuple_GET_ITEM(args, 0);
  327. PyObject *c_args = PyTuple_GET_ITEM(args, 1);
  328. if (!obj->ob_type->tp_call)
  329. {
  330. PyErr_SetNone(PyExc_ValueError);
  331. return NULL;
  332. }
  333. return obj->ob_type->tp_call(obj, c_args, NULL);
  334. '''
  335. )
  336. ])
  337. class C:
  338. def __call__(self, *args):
  339. return args
  340. assert module.tp_call(C(), ('x', 2)) == ('x', 2)
  341. def test_tp_str(self):
  342. module = self.import_extension('foo', [
  343. ("tp_str", "METH_O",
  344. '''
  345. if (!args->ob_type->tp_str)
  346. {
  347. PyErr_SetNone(PyExc_ValueError);
  348. return NULL;
  349. }
  350. return args->ob_type->tp_str(args);
  351. '''
  352. )
  353. ])
  354. class C:
  355. def __str__(self):
  356. return "text"
  357. assert module.tp_str(C()) == "text"
  358. def test_mp_ass_subscript(self):
  359. module = self.import_extension('foo', [
  360. ("new_obj", "METH_NOARGS",
  361. '''
  362. PyObject *obj;
  363. Foo_Type.tp_as_mapping = &tp_as_mapping;
  364. tp_as_mapping.mp_ass_subscript = mp_ass_subscript;
  365. if (PyType_Ready(&Foo_Type) < 0) return NULL;
  366. obj = PyObject_New(PyObject, &Foo_Type);
  367. return obj;
  368. '''
  369. )],
  370. '''
  371. static int
  372. mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value)
  373. {
  374. PyErr_SetNone(PyExc_ZeroDivisionError);
  375. return -1;
  376. }
  377. PyMappingMethods tp_as_mapping;
  378. static PyTypeObject Foo_Type = {
  379. PyVarObject_HEAD_INIT(NULL, 0)
  380. "foo.foo",
  381. };
  382. ''')
  383. obj = module.new_obj()
  384. raises(ZeroDivisionError, obj.__setitem__, 5, None)
  385. def test_tp_iter(self):
  386. module = self.import_extension('foo', [
  387. ("tp_iter", "METH_O",
  388. '''
  389. if (!args->ob_type->tp_iter)
  390. {
  391. PyErr_SetNone(PyExc_ValueError);
  392. return NULL;
  393. }
  394. return args->ob_type->tp_iter(args);
  395. '''
  396. ),
  397. ("tp_iternext", "METH_O",
  398. '''
  399. if (!args->ob_type->tp_iternext)
  400. {
  401. PyErr_SetNone(PyExc_ValueError);
  402. return NULL;
  403. }
  404. return args->ob_type->tp_iternext(args);
  405. '''
  406. )
  407. ])
  408. l = [1]
  409. it = module.tp_iter(l)
  410. assert type(it) is type(iter([]))
  411. assert module.tp_iternext(it) == 1
  412. raises(StopIteration, module.tp_iternext, it)