Skip to content

Commit a7e6515

Browse files
committed
[GR-23218] Make test_descr pass - slots and dict.
PullRequest: graalpython/1272
2 parents e600869 + 7fe262b commit a7e6515

File tree

15 files changed

+456
-86
lines changed

15 files changed

+456
-86
lines changed

graalpython/com.oracle.graal.python.cext/src/bytesobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
// taken from CPython "Objects/bytesobject.c"
4747
#define PyBytesObject_SIZE (offsetof(PyBytesObject, ob_sval) + 1)
4848

49-
PyTypeObject PyBytes_Type = PY_TRUFFLE_TYPE("bytes", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_BYTES_SUBCLASS, PyBytesObject_SIZE);
49+
PyTypeObject PyBytes_Type = PY_TRUFFLE_TYPE_WITH_ITEMSIZE("bytes", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_BYTES_SUBCLASS, PyBytesObject_SIZE, sizeof(char));
5050

5151
typedef PyObject* (*fromStringAndSize_fun_t)(int8_t* str, int64_t sz);
5252

graalpython/com.oracle.graal.python.cext/src/capi.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,11 @@ void initialize_hashes();
315315
JWRAPPER_O : \
316316
JWRAPPER_UNSUPPORTED)))))))
317317

318-
#define PY_TRUFFLE_TYPE_GENERIC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, __ALLOC__, __DEALLOC__, __FREE__, __VCALL_OFFSET__) {\
318+
#define PY_TRUFFLE_TYPE_GENERIC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, __ITEMSIZE__, __ALLOC__, __DEALLOC__, __FREE__, __VCALL_OFFSET__) {\
319319
PyVarObject_HEAD_INIT((__SUPER_TYPE__), 0)\
320320
__TYPE_NAME__, /* tp_name */\
321321
(__SIZE__), /* tp_basicsize */\
322-
0, /* tp_itemsize */\
322+
(__ITEMSIZE__), /* tp_itemsize */\
323323
(__DEALLOC__), /* tp_dealloc */\
324324
(__VCALL_OFFSET__), /* tp_vectorcall_offset */\
325325
0, /* tp_getattr */\
@@ -358,9 +358,10 @@ void initialize_hashes();
358358
0, /* tp_is_gc */\
359359
}
360360

361-
#define PY_TRUFFLE_TYPE_WITH_VECTORCALL(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, __VCALL_OFFSET__) PY_TRUFFLE_TYPE_GENERIC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, 0, 0, 0, __VCALL_OFFSET__)
362-
#define PY_TRUFFLE_TYPE_WITH_ALLOC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, __ALLOC__, __DEALLOC__, __FREE__) PY_TRUFFLE_TYPE_GENERIC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, __ALLOC__, __DEALLOC__, __FREE__, 0)
363-
#define PY_TRUFFLE_TYPE(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__) PY_TRUFFLE_TYPE_GENERIC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, 0, 0, 0, 0)
361+
#define PY_TRUFFLE_TYPE_WITH_VECTORCALL(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, __VCALL_OFFSET__) PY_TRUFFLE_TYPE_GENERIC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, 0, 0, 0, 0, __VCALL_OFFSET__)
362+
#define PY_TRUFFLE_TYPE_WITH_ALLOC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, __ALLOC__, __DEALLOC__, __FREE__) PY_TRUFFLE_TYPE_GENERIC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, 0, __ALLOC__, __DEALLOC__, __FREE__, 0)
363+
#define PY_TRUFFLE_TYPE(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__) PY_TRUFFLE_TYPE_GENERIC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, 0, 0, 0, 0, 0)
364+
#define PY_TRUFFLE_TYPE_WITH_ITEMSIZE(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, __ITEMSIZE__) PY_TRUFFLE_TYPE_GENERIC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, __ITEMSIZE__, 0, 0, 0, 0)
364365

365366
/** to be used from Java code only; returns a type's basic size */
366367
#define BASICSIZE_GETTER(__typename__)extern Py_ssize_t get_ ## __typename__ ## _basicsize() { \

graalpython/com.oracle.graal.python.cext/src/frameobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -41,7 +41,7 @@
4141

4242
#include "capi.h"
4343

44-
PyTypeObject PyFrame_Type = PY_TRUFFLE_TYPE("frame", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyTypeObject));
44+
PyTypeObject PyFrame_Type = PY_TRUFFLE_TYPE_WITH_ITEMSIZE("frame", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyTypeObject), sizeof(PyObject *));
4545

4646
UPCALL_ID(PyTruffleFrame_New);
4747
PyFrameObject* PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, PyObject *locals) {

graalpython/com.oracle.graal.python.cext/src/longobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
#include <stdbool.h>
4444
#include <stddef.h>
4545

46-
PyTypeObject PyLong_Type = PY_TRUFFLE_TYPE("int", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LONG_SUBCLASS, offsetof(PyLongObject, ob_digit));
46+
PyTypeObject PyLong_Type = PY_TRUFFLE_TYPE_WITH_ITEMSIZE("int", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LONG_SUBCLASS, offsetof(PyLongObject, ob_digit), sizeof(PyObject *));
4747

4848
PyObject * _PyLong_Zero;
4949
PyObject * _PyLong_One;

graalpython/com.oracle.graal.python.cext/src/memoryobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -40,7 +40,7 @@
4040
*/
4141
#include "capi.h"
4242

43-
PyTypeObject PyMemoryView_Type = PY_TRUFFLE_TYPE("memoryview", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, offsetof(PyMemoryViewObject, ob_array));
43+
PyTypeObject PyMemoryView_Type = PY_TRUFFLE_TYPE_WITH_ITEMSIZE("memoryview", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, offsetof(PyMemoryViewObject, ob_array), sizeof(Py_ssize_t));
4444
PyTypeObject PyBuffer_Type = PY_TRUFFLE_TYPE("buffer", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyBufferDecorator));
4545

4646
int bufferdecorator_getbuffer(PyBufferDecorator *self, Py_buffer *view, int flags) {

graalpython/com.oracle.graal.python.cext/src/tupleobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
PyObject* PyTruffle_Tuple_Alloc(PyTypeObject* cls, Py_ssize_t nitems);
4545

4646
/* tuple type */
47-
PyTypeObject PyTuple_Type = PY_TRUFFLE_TYPE_WITH_ALLOC("tuple", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, sizeof(PyTupleObject) - sizeof(PyObject *), PyTruffle_Tuple_Alloc, 0, 0);
47+
PyTypeObject PyTuple_Type = PY_TRUFFLE_TYPE_GENERIC("tuple", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, sizeof(PyTupleObject) - sizeof(PyObject *), sizeof(PyObject *), PyTruffle_Tuple_Alloc, 0, 0, 0);
4848

4949
/* Tuples */
5050
UPCALL_ID(PyTuple_New);

graalpython/com.oracle.graal.python.test/src/tests/test_slot.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,70 @@ class C:
9494
except ValueError:
9595
raised = True
9696
assert raised
97+
98+
def test_bases_have_class_layout_conflict(self):
99+
class A: __slots__ = ["a"]
100+
class B: __slots__ = ["b"]
101+
with self.assertRaisesRegex(TypeError, 'multiple bases have instance lay-out conflict'):
102+
class C(A, B): pass
103+
with self.assertRaisesRegex(TypeError, 'multiple bases have instance lay-out conflict'):
104+
class C(A, B): __slots__ = ["a"]
105+
class B: __slots__ = ["a"]
106+
with self.assertRaisesRegex(TypeError, 'multiple bases have instance lay-out conflict'):
107+
class C(A, B): pass
108+
with self.assertRaisesRegex(TypeError, 'multiple bases have instance lay-out conflict'):
109+
class C(A, B): __slots__ = ["a"]
110+
with self.assertRaisesRegex(TypeError, 'multiple bases have instance lay-out conflict'):
111+
class C(A, B): __slots__ = ["a", "a"]
112+
113+
def test_no_bases_have_class_layout_conflict(self):
114+
class A: __slots__ = ["__dict__"]
115+
class B: __slots__ = ["__dict__"]
116+
class C(A, B): pass
117+
class C(A, B): __slots__ = ["a"]
118+
class C(A, B): __slots__ = ["__weakref__"]
119+
120+
class A: __slots__ = ["__weakref__"]
121+
class B: __slots__ = ["__weakref__"]
122+
class C(A, B): pass
123+
class C(A, B): __slots__ = ["a"]
124+
class C(A, B): __slots__ = ["_dict_"]
125+
126+
def test_slot_disallowed(self):
127+
class A: __slots__ = ["__dict__"]
128+
class B: __slots__ = ["__dict__"]
129+
with self.assertRaisesRegex(TypeError, '__dict__ slot disallowed: we already got one'):
130+
class C(A, B): __slots__ = ["__dict__"]
131+
132+
class A: pass
133+
class B: __slots__ = ["__dict__"]
134+
with self.assertRaisesRegex(TypeError, '__dict__ slot disallowed: we already got one'):
135+
class C(A, B): __slots__ = ["__dict__"]
136+
137+
class A: __slots__ = ["__weakref__"]
138+
class B: __slots__ = ["__weakref__"]
139+
with self.assertRaisesRegex(TypeError, '__weakref__ slot disallowed: either we already got one, or __itemsize__ != 0'):
140+
class C(A, B): __slots__ = ["__weakref__"]
141+
142+
class A: pass
143+
class B: __slots__ = ["__weakref__"]
144+
with self.assertRaisesRegex(TypeError, '__weakref__ slot disallowed: either we already got one, or __itemsize__ != 0'):
145+
class C(A, B): __slots__ = ["__weakref__"]
146+
147+
class A: pass
148+
class B: pass
149+
with self.assertRaisesRegex(TypeError, '__dict__ slot disallowed: we already got one'):
150+
class C(A, B): __slots__ = ["__dict__", "__dict__"]
151+
with self.assertRaisesRegex(TypeError, '__weakref__ slot disallowed: either we already got one, or __itemsize__ != 0'):
152+
class C(A, B): __slots__ = ["__weakref__", "__weakref__"]
153+
154+
def test_itemsize_and_non_empty_slots(self):
155+
raised = False
156+
try:
157+
class C(tuple): __slots__ = ['a']
158+
except TypeError:
159+
raised = True
160+
assert raised
97161

98162
if __name__ == "__main__":
99163
unittest.main()

graalpython/com.oracle.graal.python.test/src/tests/test_type.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,4 +296,37 @@ class SubSlots(BaseSlots, Base):
296296
str(type(SubSlots.__dict__['__dict__'])) == "<class 'get_set_desc'>"
297297
assert SubSlots().__dict__ == {}
298298

299+
def test_itemsize():
300+
assert object.__itemsize__ == 0
301+
assert list.__itemsize__ == 0
302+
assert type.__itemsize__ == 40
303+
assert tuple.__itemsize__ == 8
304+
305+
class C: pass
306+
assert C.__itemsize__ == 0
307+
308+
class C(tuple): pass
309+
assert C.__itemsize__ == 8
310+
311+
312+
raised = False
313+
try:
314+
object.__itemsize__ = 1
315+
except TypeError:
316+
raised = True
317+
assert raised
318+
319+
raised = False
320+
try:
321+
C.__itemsize__ = 1
322+
except AttributeError:
323+
raised = True
324+
assert raised
299325

326+
class C():
327+
__itemsize__ = 'abc'
328+
assert C.__itemsize__ == 0
329+
330+
class C(tuple):
331+
__itemsize__ = 42
332+
assert C.__itemsize__ == 8

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_descr.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@
7272
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_set_class
7373
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_set_dict
7474
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_slices
75+
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_slot_shadows_class_variable
7576
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_slots_descriptor
77+
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_slots_multiple_inheritance
78+
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_slots_special2
7679
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_slots_trash
7780
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_special_unbound_method_types
7881
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_specials
@@ -92,6 +95,9 @@
9295
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_wrapper_segfault
9396
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_wrong_class_slot_wrapper
9497
*graalpython.lib-python.3.test.test_descr.DictProxyTests.test_dict_type_with_metaclass
98+
*graalpython.lib-python.3.test.test_descr.DictProxyTests.test_iter_items
99+
*graalpython.lib-python.3.test.test_descr.DictProxyTests.test_iter_keys
100+
*graalpython.lib-python.3.test.test_descr.DictProxyTests.test_iter_values
95101
*graalpython.lib-python.3.test.test_descr.DictProxyTests.test_repr
96102
*graalpython.lib-python.3.test.test_descr.MroTest.test_incomplete_extend
97103
*graalpython.lib-python.3.test.test_descr.MroTest.test_incomplete_set_bases_on_self

0 commit comments

Comments
 (0)