Skip to content

Commit 9fd3171

Browse files
authored
Merge branch 'main' into fix_pdb_break
2 parents 3021737 + 202fce0 commit 9fd3171

30 files changed

Lines changed: 4462 additions & 3719 deletions

Doc/c-api/conversion.rst

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,16 +162,33 @@ The following functions provide locale-independent string to number conversions.
162162
.. versionadded:: 3.1
163163
164164
165-
.. c:function:: int PyOS_stricmp(const char *s1, const char *s2)
165+
.. c:function:: int PyOS_mystricmp(const char *str1, const char *str2)
166+
int PyOS_mystrnicmp(const char *str1, const char *str2, Py_ssize_t size)
166167
167-
Case insensitive comparison of strings. The function works almost
168-
identically to :c:func:`!strcmp` except that it ignores the case.
168+
Case insensitive comparison of strings. These functions work almost
169+
identically to :c:func:`!strcmp` and :c:func:`!strncmp` (respectively),
170+
except that they ignore the case of ASCII characters.
169171
172+
Return ``0`` if the strings are equal, a negative value if *str1* sorts
173+
lexicographically before *str2*, or a positive value if it sorts after.
170174
171-
.. c:function:: int PyOS_strnicmp(const char *s1, const char *s2, Py_ssize_t size)
175+
In the *str1* or *str2* arguments, a NUL byte marks the end of the string.
176+
For :c:func:`!PyOS_mystrnicmp`, the *size* argument gives the maximum size
177+
of the string, as if NUL was present at the index given by *size*.
172178
173-
Case insensitive comparison of strings. The function works almost
174-
identically to :c:func:`!strncmp` except that it ignores the case.
179+
These functions do not use the locale.
180+
181+
182+
.. c:function:: int PyOS_stricmp(const char *str1, const char *str2)
183+
int PyOS_strnicmp(const char *str1, const char *str2, Py_ssize_t size)
184+
185+
Case insensitive comparison of strings.
186+
187+
On Windows, these are aliases of :c:func:`!stricmp` and :c:func:`!strnicmp`,
188+
respectively.
189+
190+
On other platforms, they are aliases of :c:func:`PyOS_mystricmp` and
191+
:c:func:`PyOS_mystrnicmp`, respectively.
175192
176193
177194
Character classification and conversion

Doc/c-api/module.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ The available slot types are:
328328
``PyModuleDef`` has non-``NULL`` ``m_traverse``, ``m_clear``,
329329
``m_free``; non-zero ``m_size``; or slots other than ``Py_mod_create``.
330330
331+
.. versionadded:: 3.5
332+
331333
.. c:macro:: Py_mod_exec
332334
333335
Specifies a function that is called to *execute* the module.
@@ -342,6 +344,8 @@ The available slot types are:
342344
If multiple ``Py_mod_exec`` slots are specified, they are processed in the
343345
order they appear in the *m_slots* array.
344346
347+
.. versionadded:: 3.5
348+
345349
.. c:macro:: Py_mod_multiple_interpreters
346350
347351
Specifies one of the following values:

Doc/data/stable_abi.dat

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

Include/object.h

Lines changed: 55 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,12 @@ struct _object {
140140
# endif
141141
};
142142
#else
143-
Py_ssize_t ob_refcnt;
143+
Py_ssize_t ob_refcnt; // part of stable ABI; do not change
144144
#endif
145145
_Py_ALIGNED_DEF(_PyObject_MIN_ALIGNMENT, char) _aligner;
146146
};
147147

148-
PyTypeObject *ob_type;
148+
PyTypeObject *ob_type; // part of stable ABI; do not change
149149
};
150150
#else
151151
// Objects that are not owned by any thread use a thread id (tid) of zero.
@@ -173,7 +173,7 @@ struct _object {
173173
#ifndef _Py_OPAQUE_PYOBJECT
174174
struct PyVarObject {
175175
PyObject ob_base;
176-
Py_ssize_t ob_size; /* Number of items in variable part */
176+
Py_ssize_t ob_size; // Number of items in variable part. Part of stable ABI
177177
};
178178
#endif
179179
typedef struct PyVarObject PyVarObject;
@@ -265,56 +265,72 @@ _Py_IsOwnedByCurrentThread(PyObject *ob)
265265
}
266266
#endif
267267

268-
// Py_TYPE() implementation for the stable ABI
268+
PyAPI_DATA(PyTypeObject) PyLong_Type;
269+
PyAPI_DATA(PyTypeObject) PyBool_Type;
270+
271+
/* Definitions for the stable ABI */
272+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= _Py_PACK_VERSION(3, 14)
269273
PyAPI_FUNC(PyTypeObject*) Py_TYPE(PyObject *ob);
274+
#endif
275+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= _Py_PACK_VERSION(3, 15)
276+
PyAPI_FUNC(Py_ssize_t) Py_SIZE(PyObject *ob);
277+
PyAPI_FUNC(int) Py_IS_TYPE(PyObject *ob, PyTypeObject *type);
278+
PyAPI_FUNC(void) Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size);
279+
#endif
280+
281+
#ifndef _Py_OPAQUE_PYOBJECT
270282

271-
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030e0000
272-
// Stable ABI implements Py_TYPE() as a function call
273-
// on limited C API version 3.14 and newer.
283+
static inline void
284+
Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
285+
{
286+
ob->ob_type = type;
287+
}
288+
289+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < _Py_PACK_VERSION(3, 11)
290+
// Non-limited API & limited API 3.11 & below: use static inline functions and
291+
// use _PyObject_CAST so that users don't need their own casts
292+
# define Py_TYPE(ob) _Py_TYPE_impl(_PyObject_CAST(ob))
293+
# define Py_SIZE(ob) _Py_SIZE_impl(_PyObject_CAST(ob))
294+
# define Py_IS_TYPE(ob, type) _Py_IS_TYPE_impl(_PyObject_CAST(ob), (type))
295+
# define Py_SET_SIZE(ob, size) _Py_SET_SIZE_impl(_PyVarObject_CAST(ob), (size))
296+
# define Py_SET_TYPE(ob, type) Py_SET_TYPE(_PyObject_CAST(ob), type)
297+
#elif Py_LIMITED_API+0 < _Py_PACK_VERSION(3, 15)
298+
// Limited API 3.11-3.14: use static inline functions, without casts
299+
# define Py_SIZE(ob) _Py_SIZE_impl(ob)
300+
# define Py_IS_TYPE(ob, type) _Py_IS_TYPE_impl((ob), (type))
301+
# define Py_SET_SIZE(ob, size) _Py_SET_SIZE_impl((ob), (size))
302+
# if Py_LIMITED_API+0 < _Py_PACK_VERSION(3, 14)
303+
// Py_TYPE() is static inline only on Limited API 3.13 and below
304+
# define Py_TYPE(ob) _Py_TYPE_impl(ob)
305+
# endif
274306
#else
275-
static inline PyTypeObject* _Py_TYPE(PyObject *ob)
276-
{
277-
return ob->ob_type;
278-
}
279-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
280-
# define Py_TYPE(ob) _Py_TYPE(_PyObject_CAST(ob))
281-
#else
282-
# define Py_TYPE(ob) _Py_TYPE(ob)
283-
#endif
307+
// Limited API 3.15+: use function calls
284308
#endif
285309

286-
PyAPI_DATA(PyTypeObject) PyLong_Type;
287-
PyAPI_DATA(PyTypeObject) PyBool_Type;
310+
static inline
311+
PyTypeObject* _Py_TYPE_impl(PyObject *ob)
312+
{
313+
return ob->ob_type;
314+
}
288315

289-
#ifndef _Py_OPAQUE_PYOBJECT
290316
// bpo-39573: The Py_SET_SIZE() function must be used to set an object size.
291-
static inline Py_ssize_t Py_SIZE(PyObject *ob) {
317+
static inline Py_ssize_t
318+
_Py_SIZE_impl(PyObject *ob)
319+
{
292320
assert(Py_TYPE(ob) != &PyLong_Type);
293321
assert(Py_TYPE(ob) != &PyBool_Type);
294322
return _PyVarObject_CAST(ob)->ob_size;
295323
}
296-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
297-
# define Py_SIZE(ob) Py_SIZE(_PyObject_CAST(ob))
298-
#endif
299-
#endif // !defined(_Py_OPAQUE_PYOBJECT)
300324

301-
static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
325+
static inline int
326+
_Py_IS_TYPE_impl(PyObject *ob, PyTypeObject *type)
327+
{
302328
return Py_TYPE(ob) == type;
303329
}
304-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
305-
# define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(ob), (type))
306-
#endif
307330

308-
309-
#ifndef _Py_OPAQUE_PYOBJECT
310-
static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) {
311-
ob->ob_type = type;
312-
}
313-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
314-
# define Py_SET_TYPE(ob, type) Py_SET_TYPE(_PyObject_CAST(ob), type)
315-
#endif
316-
317-
static inline void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) {
331+
static inline void
332+
_Py_SET_SIZE_impl(PyVarObject *ob, Py_ssize_t size)
333+
{
318334
assert(Py_TYPE(_PyObject_CAST(ob)) != &PyLong_Type);
319335
assert(Py_TYPE(_PyObject_CAST(ob)) != &PyBool_Type);
320336
#ifdef Py_GIL_DISABLED
@@ -323,9 +339,7 @@ static inline void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) {
323339
ob->ob_size = size;
324340
#endif
325341
}
326-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
327-
# define Py_SET_SIZE(ob, size) Py_SET_SIZE(_PyVarObject_CAST(ob), (size))
328-
#endif
342+
329343
#endif // !defined(_Py_OPAQUE_PYOBJECT)
330344

331345

Lib/collections/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,6 +1542,8 @@ def format_map(self, mapping):
15421542
return self.data.format_map(mapping)
15431543

15441544
def index(self, sub, start=0, end=_sys.maxsize):
1545+
if isinstance(sub, UserString):
1546+
sub = sub.data
15451547
return self.data.index(sub, start, end)
15461548

15471549
def isalpha(self):
@@ -1610,6 +1612,8 @@ def rfind(self, sub, start=0, end=_sys.maxsize):
16101612
return self.data.rfind(sub, start, end)
16111613

16121614
def rindex(self, sub, start=0, end=_sys.maxsize):
1615+
if isinstance(sub, UserString):
1616+
sub = sub.data
16131617
return self.data.rindex(sub, start, end)
16141618

16151619
def rjust(self, width, *args):

Lib/test/string_tests.py

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ def checkcall(self, obj, methodname, *args):
9090
args = self.fixtype(args)
9191
getattr(obj, methodname)(*args)
9292

93+
def _get_teststrings(self, charset, digits):
94+
base = len(charset)
95+
teststrings = set()
96+
for i in range(base ** digits):
97+
entry = []
98+
for j in range(digits):
99+
i, m = divmod(i, base)
100+
entry.append(charset[m])
101+
teststrings.add(''.join(entry))
102+
teststrings = [self.fixtype(ts) for ts in teststrings]
103+
return teststrings
104+
93105
def test_count(self):
94106
self.checkequal(3, 'aaa', 'count', 'a')
95107
self.checkequal(0, 'aaa', 'count', 'b')
@@ -130,17 +142,7 @@ def test_count(self):
130142
# For a variety of combinations,
131143
# verify that str.count() matches an equivalent function
132144
# replacing all occurrences and then differencing the string lengths
133-
charset = ['', 'a', 'b']
134-
digits = 7
135-
base = len(charset)
136-
teststrings = set()
137-
for i in range(base ** digits):
138-
entry = []
139-
for j in range(digits):
140-
i, m = divmod(i, base)
141-
entry.append(charset[m])
142-
teststrings.add(''.join(entry))
143-
teststrings = [self.fixtype(ts) for ts in teststrings]
145+
teststrings = self._get_teststrings(['', 'a', 'b'], 7)
144146
for i in teststrings:
145147
n = len(i)
146148
for j in teststrings:
@@ -197,17 +199,7 @@ def test_find(self):
197199
# For a variety of combinations,
198200
# verify that str.find() matches __contains__
199201
# and that the found substring is really at that location
200-
charset = ['', 'a', 'b', 'c']
201-
digits = 5
202-
base = len(charset)
203-
teststrings = set()
204-
for i in range(base ** digits):
205-
entry = []
206-
for j in range(digits):
207-
i, m = divmod(i, base)
208-
entry.append(charset[m])
209-
teststrings.add(''.join(entry))
210-
teststrings = [self.fixtype(ts) for ts in teststrings]
202+
teststrings = self._get_teststrings(['', 'a', 'b', 'c'], 5)
211203
for i in teststrings:
212204
for j in teststrings:
213205
loc = i.find(j)
@@ -244,17 +236,7 @@ def test_rfind(self):
244236
# For a variety of combinations,
245237
# verify that str.rfind() matches __contains__
246238
# and that the found substring is really at that location
247-
charset = ['', 'a', 'b', 'c']
248-
digits = 5
249-
base = len(charset)
250-
teststrings = set()
251-
for i in range(base ** digits):
252-
entry = []
253-
for j in range(digits):
254-
i, m = divmod(i, base)
255-
entry.append(charset[m])
256-
teststrings.add(''.join(entry))
257-
teststrings = [self.fixtype(ts) for ts in teststrings]
239+
teststrings = self._get_teststrings(['', 'a', 'b', 'c'], 5)
258240
for i in teststrings:
259241
for j in teststrings:
260242
loc = i.rfind(j)
@@ -295,6 +277,19 @@ def test_index(self):
295277
else:
296278
self.checkraises(TypeError, 'hello', 'index', 42)
297279

280+
# For a variety of combinations,
281+
# verify that str.index() matches __contains__
282+
# and that the found substring is really at that location
283+
teststrings = self._get_teststrings(['', 'a', 'b', 'c'], 5)
284+
for i in teststrings:
285+
for j in teststrings:
286+
if j in i:
287+
loc = i.index(j)
288+
self.assertGreaterEqual(loc, 0)
289+
self.assertEqual(i[loc:loc+len(j)], j)
290+
else:
291+
self.assertRaises(ValueError, i.index, j)
292+
298293
def test_rindex(self):
299294
self.checkequal(12, 'abcdefghiabc', 'rindex', '')
300295
self.checkequal(3, 'abcdefghiabc', 'rindex', 'def')
@@ -321,6 +316,19 @@ def test_rindex(self):
321316
else:
322317
self.checkraises(TypeError, 'hello', 'rindex', 42)
323318

319+
# For a variety of combinations,
320+
# verify that str.rindex() matches __contains__
321+
# and that the found substring is really at that location
322+
teststrings = self._get_teststrings(['', 'a', 'b', 'c'], 5)
323+
for i in teststrings:
324+
for j in teststrings:
325+
if j in i:
326+
loc = i.rindex(j)
327+
self.assertGreaterEqual(loc, 0)
328+
self.assertEqual(i[loc:loc+len(j)], j)
329+
else:
330+
self.assertRaises(ValueError, i.rindex, j)
331+
324332
def test_find_periodic_pattern(self):
325333
"""Cover the special path for periodic patterns."""
326334
def reference_find(p, s):

Lib/test/test_stable_abi_ctypes.py

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

Makefile.pre.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3385,6 +3385,7 @@ MODULE__DECIMAL_DEPS=@LIBMPDEC_INTERNAL@
33853385
MODULE__ELEMENTTREE_DEPS=$(srcdir)/Modules/pyexpat.c @LIBEXPAT_INTERNAL@
33863386
MODULE__HASHLIB_DEPS=$(srcdir)/Modules/hashlib.h
33873387
MODULE__IO_DEPS=$(srcdir)/Modules/_io/_iomodule.h
3388+
MODULE__REMOTE_DEBUGGING_DEPS=$(srcdir)/Modules/_remote_debugging/_remote_debugging.h
33883389

33893390
# HACL*-based cryptographic primitives
33903391
MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_MD5_HEADERS) $(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@)

0 commit comments

Comments
 (0)