pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/10cbd1fe88d1095a03cce24fb126d479668a67c3

9e07ff8eaaaff3a3.css" /> gh-130947: Add again PySequence_Fast() to the limited C API (#130948) · python/cpython@10cbd1f · GitHub
Skip to content

Commit 10cbd1f

Browse files
authored
gh-130947: Add again PySequence_Fast() to the limited C API (#130948)
Add again PySequence_Fast() to the limited C API. Add unit tests.
1 parent 3a189af commit 10cbd1f

File tree

9 files changed

+90
-13
lines changed

9 files changed

+90
-13
lines changed

Doc/data/stable_abi.dat

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Doc/whatsnew/3.14.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,9 +1598,10 @@ Limited C API changes
15981598
implementation details.
15991599
(Contributed by Victor Stinner in :gh:`120600` and :gh:`124127`.)
16001600

1601-
* Remove :c:func:`PySequence_Fast` from the limited C API, since this function
1602-
has to be used with :c:macro:`PySequence_Fast_GET_ITEM` which never worked
1603-
in the limited C API.
1601+
* Remove the :c:macro:`PySequence_Fast_GET_SIZE`,
1602+
:c:macro:`PySequence_Fast_GET_ITEM` and :c:macro:`PySequence_Fast_ITEMS`
1603+
macros from the limited C API, since these macros never worked in the limited
1604+
C API. Keep :c:func:`PySequence_Fast` in the limited C API.
16041605
(Contributed by Victor Stinner in :gh:`91417`.)
16051606

16061607

Include/abstract.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,15 @@ PyAPI_FUNC(PyObject *) PySequence_Tuple(PyObject *o);
726726
This is equivalent to the Python expression: list(o) */
727727
PyAPI_FUNC(PyObject *) PySequence_List(PyObject *o);
728728

729+
/* Return the sequence 'o' as a list, unless it's already a tuple or list.
730+
731+
Use PySequence_Fast_GET_ITEM to access the members of this list, and
732+
PySequence_Fast_GET_SIZE to get its length.
733+
734+
Returns NULL on failure. If the object does not support iteration, raises a
735+
TypeError exception with 'm' as the message text. */
736+
PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m);
737+
729738
/* Return the number of occurrences on value on 'o', that is, return
730739
the number of keys for which o[key] == value.
731740

Include/cpython/abstract.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,6 @@ PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t);
8686
#define PySequence_ITEM(o, i)\
8787
( Py_TYPE(o)->tp_as_sequence->sq_item((o), (i)) )
8888

89-
/* Return the sequence 'o' as a list, unless it's already a tuple or list.
90-
91-
Use PySequence_Fast_GET_ITEM to access the members of this list, and
92-
PySequence_Fast_GET_SIZE to get its length.
93-
94-
Returns NULL on failure. If the object does not support iteration, raises a
95-
TypeError exception with 'm' as the message text. */
96-
PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m);
97-
9889
/* Return the size of the sequence 'o', assuming that 'o' was returned by
9990
PySequence_Fast and is not NULL. */
10091
#define PySequence_Fast_GET_SIZE(o) \

Lib/test/test_capi/test_abstract.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,42 @@ def test_sequence_tuple(self):
994994
self.assertRaises(TypeError, xtuple, 42)
995995
self.assertRaises(SystemError, xtuple, NULL)
996996

997+
def test_sequence_fast(self):
998+
# Test PySequence_Fast()
999+
sequence_fast = _testlimitedcapi.sequence_fast
1000+
sequence_fast_get_size = _testcapi.sequence_fast_get_size
1001+
sequence_fast_get_item = _testcapi.sequence_fast_get_item
1002+
1003+
tpl = ('a', 'b', 'c')
1004+
fast = sequence_fast(tpl, "err_msg")
1005+
self.assertIs(fast, tpl)
1006+
self.assertEqual(sequence_fast_get_size(fast), 3)
1007+
self.assertEqual(sequence_fast_get_item(fast, 2), 'c')
1008+
1009+
lst = ['a', 'b', 'c']
1010+
fast = sequence_fast(lst, "err_msg")
1011+
self.assertIs(fast, lst)
1012+
self.assertEqual(sequence_fast_get_size(fast), 3)
1013+
self.assertEqual(sequence_fast_get_item(fast, 2), 'c')
1014+
1015+
it = iter(['A', 'B'])
1016+
fast = sequence_fast(it, "err_msg")
1017+
self.assertEqual(fast, ['A', 'B'])
1018+
self.assertEqual(sequence_fast_get_size(fast), 2)
1019+
self.assertEqual(sequence_fast_get_item(fast, 1), 'B')
1020+
1021+
text = 'fast'
1022+
fast = sequence_fast(text, "err_msg")
1023+
self.assertEqual(fast, ['f', 'a', 's', 't'])
1024+
self.assertEqual(sequence_fast_get_size(fast), 4)
1025+
self.assertEqual(sequence_fast_get_item(fast, 0), 'f')
1026+
1027+
self.assertRaises(TypeError, sequence_fast, 42, "err_msg")
1028+
self.assertRaises(SystemError, sequence_fast, NULL, "err_msg")
1029+
1030+
# CRASHES sequence_fast_get_size(NULL)
1031+
# CRASHES sequence_fast_get_item(NULL, 0)
1032+
9971033
def test_object_generichash(self):
9981034
# Test PyObject_GenericHash()
9991035
generichash = _testcapi.object_generichash
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add again :c:func:`PySequence_Fast` to the limited C API.
2+
Patch by Victor Stinner.

Misc/stable_abi.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1253,7 +1253,6 @@
12531253
added = '3.2'
12541254
[function.PySequence_Fast]
12551255
added = '3.2'
1256-
abi_only = true
12571256
[function.PySequence_GetItem]
12581257
added = '3.2'
12591258
[function.PySequence_GetSlice]

Modules/_testcapi/abstract.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,27 @@ pyiter_nextitem(PyObject *self, PyObject *iter)
157157
}
158158

159159

160+
static PyObject *
161+
sequence_fast_get_size(PyObject *self, PyObject *obj)
162+
{
163+
NULLABLE(obj);
164+
return PyLong_FromSsize_t(PySequence_Fast_GET_SIZE(obj));
165+
}
166+
167+
168+
static PyObject *
169+
sequence_fast_get_item(PyObject *self, PyObject *args)
170+
{
171+
PyObject *obj;
172+
Py_ssize_t index;
173+
if (!PyArg_ParseTuple(args, "On", &obj, &index)) {
174+
return NULL;
175+
}
176+
NULLABLE(obj);
177+
return PySequence_Fast_GET_ITEM(obj, index);
178+
}
179+
180+
160181
static PyMethodDef test_methods[] = {
161182
{"object_getoptionalattr", object_getoptionalattr, METH_VARARGS},
162183
{"object_getoptionalattrstring", object_getoptionalattrstring, METH_VARARGS},
@@ -167,6 +188,9 @@ static PyMethodDef test_methods[] = {
167188

168189
{"PyIter_Next", pyiter_next, METH_O},
169190
{"PyIter_NextItem", pyiter_nextitem, METH_O},
191+
192+
{"sequence_fast_get_size", sequence_fast_get_size, METH_O},
193+
{"sequence_fast_get_item", sequence_fast_get_item, METH_VARARGS},
170194
{NULL},
171195
};
172196

Modules/_testlimitedcapi/abstract.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,19 @@ sequence_tuple(PyObject *self, PyObject *obj)
516516
}
517517

518518

519+
static PyObject *
520+
sequence_fast(PyObject *self, PyObject *args)
521+
{
522+
PyObject *obj;
523+
const char *err_msg;
524+
if (!PyArg_ParseTuple(args, "Os", &obj, &err_msg)) {
525+
return NULL;
526+
}
527+
NULLABLE(obj);
528+
return PySequence_Fast(obj, err_msg);
529+
}
530+
531+
519532
static PyMethodDef test_methods[] = {
520533
{"object_repr", object_repr, METH_O},
521534
{"object_ascii", object_ascii, METH_O},
@@ -567,6 +580,7 @@ static PyMethodDef test_methods[] = {
567580
{"sequence_index", sequence_index, METH_VARARGS},
568581
{"sequence_list", sequence_list, METH_O},
569582
{"sequence_tuple", sequence_tuple, METH_O},
583+
{"sequence_fast", sequence_fast, METH_VARARGS},
570584

571585
{NULL},
572586
};

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy