Skip to content

Commit 22d1168

Browse files
authored
Merge branch 'main' into fix-venv-prompt-expansion
2 parents 2b7d995 + 5346059 commit 22d1168

39 files changed

Lines changed: 508 additions & 227 deletions

‎.github/CODEOWNERS‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,12 @@ Lib/_osx_support.py @python/macos-team
172172
Lib/test/test__osx_support.py @python/macos-team
173173

174174
# WebAssembly (Emscripten)
175-
Platforms/emscripten @freakboy3742 @emmatyping
176-
Tools/wasm/emscripten @freakboy3742 @emmatyping
175+
Platforms/emscripten @freakboy3742 @emmatyping @hoodmane
176+
Tools/wasm/emscripten @freakboy3742 @emmatyping @hoodmane
177+
Python/wasm_trampoline.c @hoodmane
178+
Python/emscripten_signal.c @hoodmane
179+
Python/emscripten_syscalls.c @hoodmane
180+
.github/workflows/reusable-emscripten.yml @hoodmane
177181

178182
# WebAssembly (WASI)
179183
Platforms/WASI @brettcannon @emmatyping @savannahostrowski

‎Doc/c-api/code.rst‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ bound into a function.
4444
The old name is deprecated, but will remain available until the
4545
signature changes again.
4646
47+
.. c:function:: PyObject* PyUnstable_Code_GetLocalPlusNames(PyCodeObject *co)
48+
49+
Return a :term:`strong reference` to a tuple of names of the local, cell and
50+
free variables of a code object. The names are in the same order as the
51+
values returned by :c:func:`PyUnstable_InterpreterFrame_GetLocal`.
52+
53+
.. versionadded:: next
54+
4755
.. c:function:: PyCodeObject* PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
4856
4957
Return a new code object. If you need a dummy code object to create a frame,

‎Doc/c-api/frame.rst‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,21 @@ Unless using :pep:`523`, you will not need this.
241241
Return the currently executing line number, or -1 if there is no line number.
242242
243243
.. versionadded:: 3.12
244+
245+
246+
.. c:function:: int PyUnstable_InterpreterFrame_GetLocal(struct _PyInterpreterFrame *frame, Py_ssize_t index, PyObject **result)
247+
248+
Retrieve the local variable at *index*.
249+
To determine the index of a particular variable, use
250+
:c:func:`PyUnstable_InterpreterFrame_GetCode` and
251+
:c:func:`PyUnstable_Code_GetLocalPlusNames`.
252+
253+
Cell and free variables are unboxed to their contents. Free variables are
254+
resolved from the function closure, so this also works on a frame that has
255+
not started executing.
256+
257+
* On success, store a new :term:`strong reference` in *result* and return ``1``.
258+
* If the slot is unset or hidden, store ``NULL`` in *result* and return ``0``.
259+
* On error, raise an exception, store ``NULL`` in *result* and return ``-1``.
260+
261+
.. versionadded:: next

‎Doc/c-api/tuple.rst‎

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,36 @@ Tuple Objects
133133
134134
.. c:function:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize)
135135
136-
Can be used to resize a tuple. *newsize* will be the new length of the tuple.
137-
Because tuples are *supposed* to be immutable, this should only be used if there
138-
is only one reference to the object. Do *not* use this if the tuple may already
139-
be known to some other part of the code. The tuple will always grow or shrink
140-
at the end. Think of this as destroying the old tuple and creating a new one,
141-
only more efficiently. Returns ``0`` on success. Client code should never
142-
assume that the resulting value of ``*p`` will be the same as before calling
143-
this function. If the object referenced by ``*p`` is replaced, the original
144-
``*p`` is destroyed. On failure, returns ``-1`` and sets ``*p`` to ``NULL``, and
145-
raises :exc:`MemoryError` or :exc:`SystemError`.
136+
Resize a tuple.
137+
*newsize* will be the new length of the tuple.
138+
139+
Because tuples are *supposed* to be immutable, this should only be used if
140+
there is only one reference to the object.
141+
Do *not* use this if the tuple may already be known to some other part of
142+
the code.
143+
The tuple hash value must not be computed yet.
144+
145+
The tuple will always grow or shrink at the end.
146+
Think of this as destroying the old tuple and creating a new one, only more
147+
efficiently.
148+
149+
Returns ``0`` on success.
150+
Client code should never assume that the resulting value of ``*p`` will be
151+
the same as before calling this function.
152+
If the object referenced by ``*p`` is replaced, the original ``*p`` is
153+
destroyed.
154+
155+
On failure, returns ``-1`` and sets ``*p`` to ``NULL``, and raises
156+
:exc:`MemoryError` or :exc:`SystemError`.
157+
158+
While tuple objects are usually immutable in Python, this special C API
159+
allows mutating a tuple object in-place.
160+
The returned tuple object can still be mutated using
161+
:c:func:`PyTuple_SetItem`; except if *newsize* is zero in which case it
162+
returns the immutable empty tuple.
163+
164+
.. versionchanged:: next
165+
The function now fails if the tuple hash value was already computed.
146166
147167
148168
.. _struct-sequence-objects:

‎Doc/whatsnew/3.16.rst‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,6 +1394,12 @@ New features
13941394
* Add the :ref:`PyUnicodeWriter API <pyunicodewriter>` to the limited C API.
13951395
(Contributed by Victor Stinner in :gh:`161172`.)
13961396

1397+
* Add :c:func:`PyUnstable_InterpreterFrame_GetLocal` to read a local variable
1398+
of an internal interpreter frame by its localsplus index, and
1399+
:c:func:`PyUnstable_Code_GetLocalPlusNames` to get the matching variable
1400+
names.
1401+
(Contributed by Guilherme Leobas in :gh:`156133`.)
1402+
13971403
Porting to Python 3.16
13981404
----------------------
13991405

‎Include/ceval.h‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,12 @@ PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);
122122
#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \
123123
}
124124

125-
/* Masks and values used by FORMAT_VALUE opcode. */
125+
/* String conversion constants. */
126126
#define FVC_MASK 0x3
127127
#define FVC_NONE 0x0
128128
#define FVC_STR 0x1
129129
#define FVC_REPR 0x2
130130
#define FVC_ASCII 0x3
131-
#define FVS_MASK 0x4
132-
#define FVS_HAVE_SPEC 0x4
133131

134132
#ifndef Py_LIMITED_API
135133
# define Py_CPYTHON_CEVAL_H

‎Include/cpython/code.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ static inline int PyUnstable_Code_GetFirstFree(PyCodeObject *op) {
177177
return op->co_nlocalsplus - op->co_nfreevars;
178178
}
179179

180+
static inline PyObject *PyUnstable_Code_GetLocalPlusNames(PyCodeObject *op) {
181+
assert(PyCode_Check(op));
182+
return Py_NewRef(op->co_localsplusnames);
183+
}
184+
180185
Py_DEPRECATED(3.13) static inline int PyCode_GetFirstFree(PyCodeObject *op) {
181186
return PyUnstable_Code_GetFirstFree(op);
182187
}

‎Include/cpython/pyframe.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,8 @@ PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame
3535
/* Returns the currently executing line number, or -1 if there is no line number.
3636
* Does not raise an exception. */
3737
PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame);
38+
39+
/* Returns a new (strong) reference to the local variable at `index` in the
40+
* frame's localsplus array. */
41+
PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLocal(
42+
struct _PyInterpreterFrame *frame, Py_ssize_t index, PyObject **result);

‎Include/cpython/unicodeobject.h‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,11 @@ typedef struct {
186186
(assert(PyUnicode_Check(op)), \
187187
_Py_CAST(PyASCIIObject*, (op)))
188188
#define _PyCompactUnicodeObject_CAST(op) \
189-
(assert(PyUnicode_Check(op)), \
189+
(assert(!(_PyASCIIObject_CAST(op)->state.ascii \
190+
&& _PyASCIIObject_CAST(op)->state.compact)), \
190191
_Py_CAST(PyCompactUnicodeObject*, (op)))
191192
#define _PyUnicodeObject_CAST(op) \
192-
(assert(PyUnicode_Check(op)), \
193+
(assert(!_PyASCIIObject_CAST(op)->state.compact), \
193194
_Py_CAST(PyUnicodeObject*, (op)))
194195

195196

‎Include/internal/pycore_unicodeobject.h‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extern "C" {
1111
#include "pycore_fileutils.h" // _Py_error_handler
1212
#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI
1313
#include "pycore_runtime.h" // _Py_LATIN1_CHR()
14+
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_PTR_ACQUIRE
1415

1516

1617
// Maximum code point of Unicode 6.0: 0x10ffff (1,114,111).
@@ -106,6 +107,21 @@ _PyUnicode_EnsureUnicode(PyObject *obj)
106107
return 0;
107108
}
108109

110+
static inline char*
111+
_PyUnicode_UTF8(PyObject *op)
112+
{
113+
return FT_ATOMIC_LOAD_PTR_ACQUIRE(_PyCompactUnicodeObject_CAST(op)->utf8);
114+
}
115+
116+
/* true if the Unicode object has an allocated UTF-8 memory block
117+
(not shared with other data) */
118+
static inline int _PyUnicode_HAS_UTF8_MEMORY(PyObject *op)
119+
{
120+
return (!PyUnicode_IS_COMPACT_ASCII(op)
121+
&& _PyUnicode_UTF8(op) != NULL
122+
&& _PyUnicode_UTF8(op) != PyUnicode_DATA(op));
123+
}
124+
109125
#ifndef NDEBUG
110126
static inline int
111127
_PyUnicodeWriter_CanWrite(_PyUnicodeWriter *writer)
@@ -123,6 +139,7 @@ _PyUnicodeWriter_CanWrite(_PyUnicodeWriter *writer)
123139
assert(PyUnstable_Unicode_GET_CACHED_HASH(buffer) == -1);
124140
assert(!PyUnicode_CHECK_INTERNED(buffer));
125141
assert(!_Py_IsImmortal(buffer));
142+
assert(!_PyUnicode_HAS_UTF8_MEMORY(buffer));
126143
return 1;
127144
}
128145
#endif
@@ -439,6 +456,10 @@ extern int _PyUnicode_WideCharString_Opt_Converter(PyObject *, void *);
439456
// Export for test_peg_generator
440457
PyAPI_FUNC(Py_ssize_t) _PyUnicode_ScanIdentifier(PyObject *);
441458

459+
#ifdef Py_DEBUG
460+
PyAPI_FUNC(void) _PyUnicode_Dump(PyObject *op);
461+
#endif
462+
442463
/* --- Runtime lifecycle -------------------------------------------------- */
443464

444465
extern void _PyUnicode_InitState(PyInterpreterState *);

0 commit comments

Comments
 (0)