Skip to content

Commit 8459769

Browse files
Add initial tests for _PyTuple_FromPair
1 parent f2d3ab8 commit 8459769

7 files changed

Lines changed: 109 additions & 1 deletion

File tree

Lib/test/test_capi/test_tuple.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import unittest
22
import gc
3+
from sys import getrefcount
34
from test.support import import_helper
45

56
_testcapi = import_helper.import_module('_testcapi')
67
_testlimitedcapi = import_helper.import_module('_testlimitedcapi')
8+
_testinternalcapi = import_helper.import_module('_testinternalcapi')
79

810
NULL = None
911
PY_SSIZE_T_MIN = _testcapi.PY_SSIZE_T_MIN
@@ -118,6 +120,61 @@ def test_tuple_pack(self):
118120
# CRASHES pack(1, NULL)
119121
# CRASHES pack(2, [1])
120122

123+
def test_tuple_from_pair(self):
124+
# Test _PyTuple_FromPair()
125+
tuple_from_pair = _testinternalcapi._tuple_from_pair
126+
127+
self.assertEqual(tuple_from_pair(1, 2), (1, 2))
128+
self.assertEqual(tuple_from_pair(None, None), (None, None))
129+
self.assertEqual(tuple_from_pair(True, False), (True, False))
130+
131+
# user class supports gc
132+
class Temp:
133+
pass
134+
temp = Temp()
135+
temp_rc = getrefcount(temp)
136+
self.assertEqual(tuple_from_pair(temp, temp), (temp, temp))
137+
self.assertEqual(getrefcount(temp), temp_rc)
138+
139+
self.assertRaises(TypeError, tuple_from_pair, 1, 2, 3)
140+
self.assertRaises(TypeError, tuple_from_pair, 1)
141+
self.assertRaises(TypeError, tuple_from_pair)
142+
143+
self.assertFalse(gc.is_tracked(tuple_from_pair(1, 2)))
144+
self.assertFalse(gc.is_tracked(tuple_from_pair(None, None)))
145+
self.assertFalse(gc.is_tracked(tuple_from_pair(True, False)))
146+
self.assertTrue(gc.is_tracked(tuple_from_pair(temp, (1, 2))))
147+
self.assertTrue(gc.is_tracked(tuple_from_pair(temp, 1)))
148+
self.assertTrue(gc.is_tracked(tuple_from_pair([], {})))
149+
150+
def test_tuple_from_pair_steal(self):
151+
# Test _PyTuple_FromPairSteal()
152+
tuple_from_pair = _testinternalcapi._tuple_from_pair_steal
153+
154+
self.assertEqual(tuple_from_pair(1, 2), (1, 2))
155+
self.assertEqual(tuple_from_pair(None, None), (None, None))
156+
self.assertEqual(tuple_from_pair(True, False), (True, False))
157+
158+
# user class supports gc
159+
class Temp:
160+
pass
161+
temp = Temp()
162+
temp_rc = getrefcount(temp)
163+
self.assertEqual(tuple_from_pair(temp, temp), (temp, temp))
164+
self.assertEqual(getrefcount(temp), temp_rc)
165+
166+
self.assertRaises(TypeError, tuple_from_pair, 1, 2, 3)
167+
self.assertRaises(TypeError, tuple_from_pair, 1)
168+
self.assertRaises(TypeError, tuple_from_pair)
169+
170+
self.assertFalse(gc.is_tracked(tuple_from_pair(1, 2)))
171+
self.assertFalse(gc.is_tracked(tuple_from_pair(None, None)))
172+
self.assertFalse(gc.is_tracked(tuple_from_pair(True, False)))
173+
self.assertTrue(gc.is_tracked(tuple_from_pair(temp, (1, 2))))
174+
self.assertTrue(gc.is_tracked(tuple_from_pair(temp, 1)))
175+
self.assertTrue(gc.is_tracked(tuple_from_pair([], {})))
176+
177+
121178
def test_tuple_size(self):
122179
# Test PyTuple_Size()
123180
size = _testlimitedcapi.tuple_size

Modules/Setup.stdlib.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@
174174
@MODULE_XXSUBTYPE_TRUE@xxsubtype xxsubtype.c
175175
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
176176
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
177-
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c _testinternalcapi/test_lock.c _testinternalcapi/pytime.c _testinternalcapi/set.c _testinternalcapi/test_critical_sections.c _testinternalcapi/complex.c _testinternalcapi/interpreter.c
177+
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c _testinternalcapi/test_lock.c _testinternalcapi/pytime.c _testinternalcapi/set.c _testinternalcapi/test_critical_sections.c _testinternalcapi/complex.c _testinternalcapi/interpreter.c _testinternalcapi/tuple.c
178178
@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/complex.c _testcapi/numbers.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyatomic.c _testcapi/run.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/gc.c _testcapi/hash.c _testcapi/time.c _testcapi/bytes.c _testcapi/object.c _testcapi/modsupport.c _testcapi/monitoring.c _testcapi/config.c _testcapi/import.c _testcapi/frame.c _testcapi/type.c _testcapi/function.c _testcapi/module.c
179179
@MODULE__TESTLIMITEDCAPI_TRUE@_testlimitedcapi _testlimitedcapi.c _testlimitedcapi/abstract.c _testlimitedcapi/bytearray.c _testlimitedcapi/bytes.c _testlimitedcapi/codec.c _testlimitedcapi/complex.c _testlimitedcapi/dict.c _testlimitedcapi/eval.c _testlimitedcapi/float.c _testlimitedcapi/heaptype_relative.c _testlimitedcapi/import.c _testlimitedcapi/list.c _testlimitedcapi/long.c _testlimitedcapi/object.c _testlimitedcapi/pyos.c _testlimitedcapi/set.c _testlimitedcapi/sys.c _testlimitedcapi/tuple.c _testlimitedcapi/unicode.c _testlimitedcapi/vectorcall_limited.c _testlimitedcapi/version.c _testlimitedcapi/file.c
180180
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c

Modules/_testinternalcapi.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2981,6 +2981,9 @@ module_exec(PyObject *module)
29812981
if (_PyTestInternalCapi_Init_CriticalSection(module) < 0) {
29822982
return 1;
29832983
}
2984+
if (_PyTestInternalCapi_Init_Tuple(module) < 0) {
2985+
return 1;
2986+
}
29842987

29852988
Py_ssize_t sizeof_gc_head = 0;
29862989
#ifndef Py_GIL_DISABLED

Modules/_testinternalcapi/parts.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ int _PyTestInternalCapi_Init_PyTime(PyObject *module);
1515
int _PyTestInternalCapi_Init_Set(PyObject *module);
1616
int _PyTestInternalCapi_Init_Complex(PyObject *module);
1717
int _PyTestInternalCapi_Init_CriticalSection(PyObject *module);
18+
int _PyTestInternalCapi_Init_Tuple(PyObject *module);
1819

1920
#endif // Py_TESTINTERNALCAPI_PARTS_H

Modules/_testinternalcapi/tuple.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "parts.h"
2+
3+
#include "pycore_tuple.h"
4+
5+
6+
static PyObject *
7+
_tuple_from_pair(PyObject *Py_UNUSED(module), PyObject *args)
8+
{
9+
PyObject *one, *two;
10+
if (!PyArg_ParseTuple(args, "OO", &one, &two)) {
11+
return NULL;
12+
}
13+
14+
return _PyTuple_FromPair(one, two);
15+
}
16+
17+
static PyObject *
18+
_tuple_from_pair_steal(PyObject *Py_UNUSED(module), PyObject *args)
19+
{
20+
PyObject *one, *two;
21+
if (!PyArg_ParseTuple(args, "OO", &one, &two)) {
22+
return NULL;
23+
}
24+
25+
return _PyTuple_FromPairSteal(Py_NewRef(one), Py_NewRef(two));
26+
}
27+
28+
29+
static PyMethodDef test_methods[] = {
30+
{"_tuple_from_pair", _tuple_from_pair, METH_VARARGS},
31+
{"_tuple_from_pair_steal", _tuple_from_pair_steal, METH_VARARGS},
32+
{NULL},
33+
};
34+
35+
int
36+
_PyTestInternalCapi_Init_Tuple(PyObject *m)
37+
{
38+
if (PyModule_AddFunctions(m, test_methods) < 0) {
39+
return -1;
40+
}
41+
42+
return 0;
43+
}

PCbuild/_testinternalcapi.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
<ClCompile Include="..\Modules\_testinternalcapi\set.c" />
101101
<ClCompile Include="..\Modules\_testinternalcapi\complex.c" />
102102
<ClCompile Include="..\Modules\_testinternalcapi\interpreter.c" />
103+
<ClCompile Include="..\Modules\_testinternalcapi\tuple.c" />
103104
</ItemGroup>
104105
<ItemGroup>
105106
<ResourceCompile Include="..\PC\python_nt.rc" />

PCbuild/_testinternalcapi.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
<ClCompile Include="..\Modules\_testinternalcapi\complex.c">
2828
<Filter>Source Files</Filter>
2929
</ClCompile>
30+
<ClCompile Include="..\Modules\_testinternalcapi\tuple.c">
31+
<Filter>Source Files</Filter>
32+
</ClCompile>
3033
</ItemGroup>
3134
<ItemGroup>
3235
<ResourceCompile Include="..\PC\python_nt.rc">

0 commit comments

Comments
 (0)