Skip to content

Commit b0f3192

Browse files
authored
Merge branch 'python:main' into unicodedata-normalize-always-returns-exact-str
2 parents cba7f34 + df4a2f5 commit b0f3192

File tree

12 files changed

+1026
-995
lines changed

12 files changed

+1026
-995
lines changed

Doc/license.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ Project, https://www.wide.ad.jp/. ::
374374
may be used to endorse or promote products derived from this software
375375
without specific prior written permission.
376376

377-
THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
377+
THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS "AS IS" AND
378378
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
379379
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
380380
ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
@@ -583,7 +583,7 @@ interface::
583583
notice, this list of conditions and the following disclaimer in the
584584
documentation and/or other materials provided with the distribution.
585585

586-
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
586+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
587587
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
588588
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
589589
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
@@ -884,7 +884,7 @@ sources unless the build is configured ``--with-system-libffi``::
884884

885885
Permission is hereby granted, free of charge, to any person obtaining
886886
a copy of this software and associated documentation files (the
887-
``Software''), to deal in the Software without restriction, including
887+
"Software"), to deal in the Software without restriction, including
888888
without limitation the rights to use, copy, modify, merge, publish,
889889
distribute, sublicense, and/or sell copies of the Software, and to
890890
permit persons to whom the Software is furnished to do so, subject to
@@ -893,7 +893,7 @@ sources unless the build is configured ``--with-system-libffi``::
893893
The above copyright notice and this permission notice shall be included
894894
in all copies or substantial portions of the Software.
895895

896-
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
896+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
897897
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
898898
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
899899
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
@@ -1122,7 +1122,7 @@ The file is distributed under the 2-Clause BSD License::
11221122
notice, this list of conditions and the following disclaimer in the
11231123
documentation and/or other materials provided with the distribution.
11241124

1125-
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1125+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
11261126
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
11271127
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11281128
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,

Lib/test/test_capi/test_misc.py

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -403,42 +403,6 @@ def test_buildvalue_ints(self):
403403
def test_buildvalue_N(self):
404404
_testcapi.test_buildvalue_N()
405405

406-
def check_negative_refcount(self, code):
407-
# bpo-35059: Check that Py_DECREF() reports the correct filename
408-
# when calling _Py_NegativeRefcount() to abort Python.
409-
code = textwrap.dedent(code)
410-
rc, out, err = assert_python_failure('-c', code)
411-
self.assertRegex(err,
412-
br'_testcapimodule\.c:[0-9]+: '
413-
br'_Py_NegativeRefcount: Assertion failed: '
414-
br'object has negative ref count')
415-
416-
@unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'),
417-
'need _testcapi.negative_refcount()')
418-
def test_negative_refcount(self):
419-
code = """
420-
import _testcapi
421-
from test import support
422-
423-
with support.SuppressCrashReport():
424-
_testcapi.negative_refcount()
425-
"""
426-
self.check_negative_refcount(code)
427-
428-
@unittest.skipUnless(hasattr(_testcapi, 'decref_freed_object'),
429-
'need _testcapi.decref_freed_object()')
430-
@support.skip_if_sanitizer("use after free on purpose",
431-
address=True, memory=True, ub=True)
432-
def test_decref_freed_object(self):
433-
code = """
434-
import _testcapi
435-
from test import support
436-
437-
with support.SuppressCrashReport():
438-
_testcapi.decref_freed_object()
439-
"""
440-
self.check_negative_refcount(code)
441-
442406
def test_trashcan_subclass(self):
443407
# bpo-35983: Check that the trashcan mechanism for "list" is NOT
444408
# activated when its tp_dealloc is being called by a subclass

Lib/test/test_capi/test_object.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import enum
2+
import textwrap
23
import unittest
34
from test import support
45
from test.support import import_helper
56
from test.support import os_helper
67
from test.support import threading_helper
8+
from test.support.script_helper import assert_python_failure
9+
710

811
_testlimitedcapi = import_helper.import_module('_testlimitedcapi')
912
_testcapi = import_helper.import_module('_testcapi')
@@ -170,5 +173,42 @@ def silly_func(obj):
170173
self.assertTrue(_testinternalcapi.has_deferred_refcount(silly_list))
171174

172175

176+
class CAPITest(unittest.TestCase):
177+
def check_negative_refcount(self, code):
178+
# bpo-35059: Check that Py_DECREF() reports the correct filename
179+
# when calling _Py_NegativeRefcount() to abort Python.
180+
code = textwrap.dedent(code)
181+
rc, out, err = assert_python_failure('-c', code)
182+
self.assertRegex(err,
183+
br'object\.c:[0-9]+: '
184+
br'_Py_NegativeRefcount: Assertion failed: '
185+
br'object has negative ref count')
186+
187+
@unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'),
188+
'need _testcapi.negative_refcount()')
189+
def test_negative_refcount(self):
190+
code = """
191+
import _testcapi
192+
from test import support
193+
194+
with support.SuppressCrashReport():
195+
_testcapi.negative_refcount()
196+
"""
197+
self.check_negative_refcount(code)
198+
199+
@unittest.skipUnless(hasattr(_testcapi, 'decref_freed_object'),
200+
'need _testcapi.decref_freed_object()')
201+
@support.skip_if_sanitizer("use after free on purpose",
202+
address=True, memory=True, ub=True)
203+
def test_decref_freed_object(self):
204+
code = """
205+
import _testcapi
206+
from test import support
207+
208+
with support.SuppressCrashReport():
209+
_testcapi.decref_freed_object()
210+
"""
211+
self.check_negative_refcount(code)
212+
173213
if __name__ == "__main__":
174214
unittest.main()

Lib/test/test_socket.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,8 @@ def clientTearDown(self):
520520
@unittest.skipIf(WSL, 'VSOCK does not work on Microsoft WSL')
521521
@unittest.skipUnless(HAVE_SOCKET_VSOCK,
522522
'VSOCK sockets required for this test.')
523+
@unittest.skipUnless(get_cid() != 2, # VMADDR_CID_HOST
524+
"This test can only be run on a virtual guest.")
523525
class ThreadedVSOCKSocketStreamTest(unittest.TestCase, ThreadableTest):
524526

525527
def __init__(self, methodName='runTest'):

Modules/_testcapi/dict.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,83 @@ dict_popstring_null(PyObject *self, PyObject *args)
181181
RETURN_INT(PyDict_PopString(dict, key, NULL));
182182
}
183183

184+
185+
static int
186+
test_dict_inner(PyObject *self, int count)
187+
{
188+
Py_ssize_t pos = 0, iterations = 0;
189+
int i;
190+
PyObject *dict = PyDict_New();
191+
PyObject *v, *k;
192+
193+
if (dict == NULL)
194+
return -1;
195+
196+
for (i = 0; i < count; i++) {
197+
v = PyLong_FromLong(i);
198+
if (v == NULL) {
199+
goto error;
200+
}
201+
if (PyDict_SetItem(dict, v, v) < 0) {
202+
Py_DECREF(v);
203+
goto error;
204+
}
205+
Py_DECREF(v);
206+
}
207+
208+
k = v = UNINITIALIZED_PTR;
209+
while (PyDict_Next(dict, &pos, &k, &v)) {
210+
PyObject *o;
211+
iterations++;
212+
213+
assert(k != UNINITIALIZED_PTR);
214+
assert(v != UNINITIALIZED_PTR);
215+
i = PyLong_AS_LONG(v) + 1;
216+
o = PyLong_FromLong(i);
217+
if (o == NULL) {
218+
goto error;
219+
}
220+
if (PyDict_SetItem(dict, k, o) < 0) {
221+
Py_DECREF(o);
222+
goto error;
223+
}
224+
Py_DECREF(o);
225+
k = v = UNINITIALIZED_PTR;
226+
}
227+
assert(k == UNINITIALIZED_PTR);
228+
assert(v == UNINITIALIZED_PTR);
229+
230+
Py_DECREF(dict);
231+
232+
if (iterations != count) {
233+
PyErr_SetString(
234+
PyExc_AssertionError,
235+
"test_dict_iteration: dict iteration went wrong ");
236+
return -1;
237+
} else {
238+
return 0;
239+
}
240+
error:
241+
Py_DECREF(dict);
242+
return -1;
243+
}
244+
245+
246+
static PyObject*
247+
test_dict_iteration(PyObject* self, PyObject *Py_UNUSED(ignored))
248+
{
249+
int i;
250+
251+
for (i = 0; i < 200; i++) {
252+
if (test_dict_inner(self, i) < 0) {
253+
return NULL;
254+
}
255+
}
256+
257+
Py_RETURN_NONE;
258+
}
259+
260+
184261
static PyMethodDef test_methods[] = {
185262
{"dict_containsstring", dict_containsstring, METH_VARARGS},
186263
{"dict_getitemref", dict_getitemref, METH_VARARGS},
@@ -191,6 +268,7 @@ static PyMethodDef test_methods[] = {
191268
{"dict_pop_null", dict_pop_null, METH_VARARGS},
192269
{"dict_popstring", dict_popstring, METH_VARARGS},
193270
{"dict_popstring_null", dict_popstring_null, METH_VARARGS},
271+
{"test_dict_iteration", test_dict_iteration, METH_NOARGS},
194272
{NULL},
195273
};
196274

Modules/_testcapi/float.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,68 @@ _testcapi_float_unpack_impl(PyObject *module, const char *data,
9999
return PyFloat_FromDouble(d);
100100
}
101101

102+
103+
/* Test PyOS_string_to_double. */
104+
static PyObject *
105+
test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored))
106+
{
107+
double result;
108+
const char *msg;
109+
110+
#define CHECK_STRING(STR, expected) \
111+
do { \
112+
result = PyOS_string_to_double(STR, NULL, NULL); \
113+
if (result == -1.0 && PyErr_Occurred()) { \
114+
return NULL; \
115+
} \
116+
if (result != (double)expected) { \
117+
msg = "conversion of " STR " to float failed"; \
118+
goto fail; \
119+
} \
120+
} while (0)
121+
122+
#define CHECK_INVALID(STR) \
123+
do { \
124+
result = PyOS_string_to_double(STR, NULL, NULL); \
125+
if (result == -1.0 && PyErr_Occurred()) { \
126+
if (PyErr_ExceptionMatches(PyExc_ValueError)) { \
127+
PyErr_Clear(); \
128+
} \
129+
else { \
130+
return NULL; \
131+
} \
132+
} \
133+
else { \
134+
msg = "conversion of " STR " didn't raise ValueError"; \
135+
goto fail; \
136+
} \
137+
} while (0)
138+
139+
CHECK_STRING("0.1", 0.1);
140+
CHECK_STRING("1.234", 1.234);
141+
CHECK_STRING("-1.35", -1.35);
142+
CHECK_STRING(".1e01", 1.0);
143+
CHECK_STRING("2.e-2", 0.02);
144+
145+
CHECK_INVALID(" 0.1");
146+
CHECK_INVALID("\t\n-3");
147+
CHECK_INVALID(".123 ");
148+
CHECK_INVALID("3\n");
149+
CHECK_INVALID("123abc");
150+
151+
Py_RETURN_NONE;
152+
fail:
153+
PyErr_Format(PyExc_AssertionError, "test_string_to_double: %s", msg);
154+
return NULL;
155+
#undef CHECK_STRING
156+
#undef CHECK_INVALID
157+
}
158+
159+
102160
static PyMethodDef test_methods[] = {
103161
_TESTCAPI_FLOAT_PACK_METHODDEF
104162
_TESTCAPI_FLOAT_UNPACK_METHODDEF
163+
{"test_string_to_double", test_string_to_double, METH_NOARGS},
105164
{NULL},
106165
};
107166

Modules/_testcapi/list.c

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,61 @@ list_extend(PyObject* Py_UNUSED(module), PyObject *args)
6060
}
6161

6262

63+
static PyObject*
64+
test_list_api(PyObject *self, PyObject *Py_UNUSED(ignored))
65+
{
66+
PyObject* list;
67+
int i;
68+
69+
/* SF bug 132008: PyList_Reverse segfaults */
70+
#define NLIST 30
71+
list = PyList_New(NLIST);
72+
if (list == (PyObject*)NULL)
73+
return (PyObject*)NULL;
74+
/* list = range(NLIST) */
75+
for (i = 0; i < NLIST; ++i) {
76+
PyObject* anint = PyLong_FromLong(i);
77+
if (anint == (PyObject*)NULL) {
78+
Py_DECREF(list);
79+
return (PyObject*)NULL;
80+
}
81+
PyList_SET_ITEM(list, i, anint);
82+
}
83+
/* list.reverse(), via PyList_Reverse() */
84+
i = PyList_Reverse(list); /* should not blow up! */
85+
if (i != 0) {
86+
Py_DECREF(list);
87+
return (PyObject*)NULL;
88+
}
89+
/* Check that list == range(29, -1, -1) now */
90+
for (i = 0; i < NLIST; ++i) {
91+
PyObject* anint = PyList_GET_ITEM(list, i);
92+
if (PyLong_AS_LONG(anint) != NLIST-1-i) {
93+
PyErr_SetString(PyExc_AssertionError,
94+
"test_list_api: reverse screwed up");
95+
Py_DECREF(list);
96+
return (PyObject*)NULL;
97+
}
98+
}
99+
Py_DECREF(list);
100+
#undef NLIST
101+
102+
Py_RETURN_NONE;
103+
}
104+
105+
63106
static PyMethodDef test_methods[] = {
64107
{"list_get_size", list_get_size, METH_O},
65108
{"list_get_item", list_get_item, METH_VARARGS},
66109
{"list_set_item", list_set_item, METH_VARARGS},
67110
{"list_clear", list_clear, METH_O},
68111
{"list_extend", list_extend, METH_VARARGS},
69-
112+
{"test_list_api", test_list_api, METH_NOARGS},
70113
{NULL},
71114
};
72115

73116
int
74117
_PyTestCapi_Init_List(PyObject *m)
75118
{
76-
if (PyModule_AddFunctions(m, test_methods) < 0) {
77-
return -1;
78-
}
79-
80-
return 0;
119+
return PyModule_AddFunctions(m, test_methods);
81120
}

0 commit comments

Comments
 (0)