Python-checkins
Threads by month
- ----- 2024 -----
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
March 2023
- 1 participants
- 425 discussions
https://github.com/python/cpython/commit/ba755a245b4c90511da0c1c41cfdbd1a9e…
commit: ba755a245b4c90511da0c1c41cfdbd1a9e7bb5bd
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: miss-islington <31488909+miss-islington(a)users.noreply.github.com>
date: 2023-03-30T01:41:04-07:00
summary:
gh-103099: Link mypy docs from typing.rst (GH-103100)
(cherry picked from commit fda95aa19447fe444ac2670afbf98ec42aca0c6f)
Co-authored-by: Shantanu <12621235+hauntsaninja(a)users.noreply.github.com>
files:
M Doc/library/typing.rst
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index 00f779647e0b..8cf24521ca6c 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -38,6 +38,14 @@ provides backports of these new features to older versions of Python.
.. seealso::
+ For a quick overview of type hints, refer to
+ `this cheat sheet <https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html>`_.
+
+ The "Type System Reference" section of https://mypy.readthedocs.io/ -- since
+ the Python typing system is standardised via PEPs, this reference should
+ broadly apply to most Python type checkers, although some parts may still be
+ specific to mypy.
+
The documentation at https://typing.readthedocs.io/ serves as useful reference
for type system features, useful typing related tools and typing best practices.
1
0
https://github.com/python/cpython/commit/1b40618247b7645b331ed5f42d704a2737…
commit: 1b40618247b7645b331ed5f42d704a2737cd52cb
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: miss-islington <31488909+miss-islington(a)users.noreply.github.com>
date: 2023-03-30T01:39:49-07:00
summary:
gh-103099: Link mypy docs from typing.rst (GH-103100)
(cherry picked from commit fda95aa19447fe444ac2670afbf98ec42aca0c6f)
Co-authored-by: Shantanu <12621235+hauntsaninja(a)users.noreply.github.com>
files:
M Doc/library/typing.rst
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index df6ddb6726cf..60f49d7029df 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -41,10 +41,17 @@ For a summary of deprecated features and a deprecation timeline, please see
.. seealso::
+ For a quick overview of type hints, refer to
+ `this cheat sheet <https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html>`_.
+
+ The "Type System Reference" section of https://mypy.readthedocs.io/ -- since
+ the Python typing system is standardised via PEPs, this reference should
+ broadly apply to most Python type checkers, although some parts may still be
+ specific to mypy.
+
The documentation at https://typing.readthedocs.io/ serves as useful reference
for type system features, useful typing related tools and typing best practices.
-
.. _relevant-peps:
Relevant PEPs
1
0
https://github.com/python/cpython/commit/fda95aa19447fe444ac2670afbf98ec42a…
commit: fda95aa19447fe444ac2670afbf98ec42aca0c6f
branch: main
author: Shantanu <12621235+hauntsaninja(a)users.noreply.github.com>
committer: hauntsaninja <12621235+hauntsaninja(a)users.noreply.github.com>
date: 2023-03-30T01:32:09-07:00
summary:
gh-103099: Link mypy docs from typing.rst (#103100)
files:
M Doc/library/typing.rst
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index 08ffa0310f0f..384458d3aa66 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -41,10 +41,17 @@ For a summary of deprecated features and a deprecation timeline, please see
.. seealso::
+ For a quick overview of type hints, refer to
+ `this cheat sheet <https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html>`_.
+
+ The "Type System Reference" section of https://mypy.readthedocs.io/ -- since
+ the Python typing system is standardised via PEPs, this reference should
+ broadly apply to most Python type checkers, although some parts may still be
+ specific to mypy.
+
The documentation at https://typing.readthedocs.io/ serves as useful reference
for type system features, useful typing related tools and typing best practices.
-
.. _relevant-peps:
Relevant PEPs
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
gh-100227: Make the Global PyModuleDef Cache Safe for Isolated Interpreters (gh-103084)
by ericsnowcurrently 29 Mar '23
by ericsnowcurrently 29 Mar '23
29 Mar '23
https://github.com/python/cpython/commit/dcd6f226d6596b25b6f4004058a67acabe…
commit: dcd6f226d6596b25b6f4004058a67acabe012120
branch: main
author: Eric Snow <ericsnowcurrently(a)gmail.com>
committer: ericsnowcurrently <ericsnowcurrently(a)gmail.com>
date: 2023-03-29T17:15:43-06:00
summary:
gh-100227: Make the Global PyModuleDef Cache Safe for Isolated Interpreters (gh-103084)
Sharing mutable (or non-immortal) objects between interpreters is generally not safe. We can work around that but not easily.
There are two restrictions that are critical for objects that break interpreter isolation.
The first is that the object's state be guarded by a global lock. For now the GIL meets this requirement, but a granular global lock is needed once we have a per-interpreter GIL.
The second restriction is that the object (and, for a container, its items) be deallocated/resized only when the interpreter in which it was allocated is the current one. This is because every interpreter has (or will have, see gh-101660) its own object allocator. Deallocating an object with a different allocator can cause crashes.
The dict for the cache of module defs is completely internal, which simplifies what we have to do to meet those requirements. To do so, we do the following:
* add a mechanism for re-using a temporary thread state tied to the main interpreter in an arbitrary thread
* add _PyRuntime.imports.extensions.main_tstate`
* add _PyThreadState_InitDetached() and _PyThreadState_ClearDetached() (pystate.c)
* add _PyThreadState_BindDetached() and _PyThreadState_UnbindDetached() (pystate.c)
* make sure the cache dict (_PyRuntime.imports.extensions.dict) and its items are all owned by the main interpreter)
* add a placeholder using for a granular global lock
Note that the cache is only used for legacy extension modules and not for multi-phase init modules.
https://github.com/python/cpython/issues/100227
files:
M Include/internal/pycore_import.h
M Include/internal/pycore_pystate.h
M Include/internal/pycore_runtime_init.h
M Python/import.c
M Python/pystate.c
diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h
index 69ed6273b7e6..7a78a91aa617 100644
--- a/Include/internal/pycore_import.h
+++ b/Include/internal/pycore_import.h
@@ -14,13 +14,19 @@ struct _import_runtime_state {
which is just about every time an extension module is imported.
See PyInterpreterState.modules_by_index for more info. */
Py_ssize_t last_module_index;
- /* A dict mapping (filename, name) to PyModuleDef for modules.
- Only legacy (single-phase init) extension modules are added
- and only if they support multiple initialization (m_size >- 0)
- or are imported in the main interpreter.
- This is initialized lazily in _PyImport_FixupExtensionObject().
- Modules are added there and looked up in _imp.find_extension(). */
- PyObject *extensions;
+ struct {
+ /* A thread state tied to the main interpreter,
+ used exclusively for when the extensions dict is access/modified
+ from an arbitrary thread. */
+ PyThreadState main_tstate;
+ /* A dict mapping (filename, name) to PyModuleDef for modules.
+ Only legacy (single-phase init) extension modules are added
+ and only if they support multiple initialization (m_size >- 0)
+ or are imported in the main interpreter.
+ This is initialized lazily in _PyImport_FixupExtensionObject().
+ Modules are added there and looked up in _imp.find_extension(). */
+ PyObject *dict;
+ } extensions;
/* Package context -- the full module name for package imports */
const char * pkgcontext;
};
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index 7046ec8d9ada..b5408622d9d4 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -127,6 +127,11 @@ PyAPI_FUNC(void) _PyThreadState_Init(
PyThreadState *tstate);
PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
+extern void _PyThreadState_InitDetached(PyThreadState *, PyInterpreterState *);
+extern void _PyThreadState_ClearDetached(PyThreadState *);
+extern void _PyThreadState_BindDetached(PyThreadState *);
+extern void _PyThreadState_UnbindDetached(PyThreadState *);
+
static inline void
_PyThreadState_UpdateTracingState(PyThreadState *tstate)
diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h
index 7cfa7c0c0249..5b09a45e41cd 100644
--- a/Include/internal/pycore_runtime_init.h
+++ b/Include/internal/pycore_runtime_init.h
@@ -41,6 +41,11 @@ extern PyTypeObject _PyExc_MemoryError;
in accordance with the specification. */ \
.autoTSSkey = Py_tss_NEEDS_INIT, \
.parser = _parser_runtime_state_INIT, \
+ .imports = { \
+ .extensions = { \
+ .main_tstate = _PyThreadState_INIT, \
+ }, \
+ }, \
.ceval = { \
.perf = _PyEval_RUNTIME_PERF_INIT, \
}, \
diff --git a/Python/import.c b/Python/import.c
index c68bd1f7db42..a45b3bfaacb2 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -862,6 +862,18 @@ Generally, when multiple interpreters are involved, some of the above
gets even messier.
*/
+static inline void
+extensions_lock_acquire(void)
+{
+ // XXX For now the GIL is sufficient.
+}
+
+static inline void
+extensions_lock_release(void)
+{
+ // XXX For now the GIL is sufficient.
+}
+
/* Magic for extension modules (built-in as well as dynamically
loaded). To prevent initializing an extension module more than
once, we keep a static dictionary 'extensions' keyed by the tuple
@@ -878,71 +890,170 @@ gets even messier.
dictionary, to avoid loading shared libraries twice.
*/
+static void
+_extensions_cache_init(void)
+{
+ /* The runtime (i.e. main interpreter) must be initializing,
+ so we don't need to worry about the lock. */
+ _PyThreadState_InitDetached(&EXTENSIONS.main_tstate,
+ _PyInterpreterState_Main());
+}
+
static PyModuleDef *
_extensions_cache_get(PyObject *filename, PyObject *name)
{
- PyObject *extensions = EXTENSIONS;
- if (extensions == NULL) {
- return NULL;
- }
+ PyModuleDef *def = NULL;
+ extensions_lock_acquire();
+
PyObject *key = PyTuple_Pack(2, filename, name);
if (key == NULL) {
- return NULL;
+ goto finally;
+ }
+
+ PyObject *extensions = EXTENSIONS.dict;
+ if (extensions == NULL) {
+ goto finally;
}
- PyModuleDef *def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key);
- Py_DECREF(key);
+ def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key);
+
+finally:
+ Py_XDECREF(key);
+ extensions_lock_release();
return def;
}
static int
_extensions_cache_set(PyObject *filename, PyObject *name, PyModuleDef *def)
{
- PyObject *extensions = EXTENSIONS;
+ int res = -1;
+ PyThreadState *oldts = NULL;
+ extensions_lock_acquire();
+
+ /* Swap to the main interpreter, if necessary. This matters if
+ the dict hasn't been created yet or if the item isn't in the
+ dict yet. In both cases we must ensure the relevant objects
+ are created using the main interpreter. */
+ PyThreadState *main_tstate = &EXTENSIONS.main_tstate;
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ if (!_Py_IsMainInterpreter(interp)) {
+ _PyThreadState_BindDetached(main_tstate);
+ oldts = _PyThreadState_Swap(interp->runtime, main_tstate);
+ assert(!_Py_IsMainInterpreter(oldts->interp));
+
+ /* Make sure the name and filename objects are owned
+ by the main interpreter. */
+ name = PyUnicode_InternFromString(PyUnicode_AsUTF8(name));
+ assert(name != NULL);
+ filename = PyUnicode_InternFromString(PyUnicode_AsUTF8(filename));
+ assert(filename != NULL);
+ }
+
+ PyObject *key = PyTuple_Pack(2, filename, name);
+ if (key == NULL) {
+ goto finally;
+ }
+
+ PyObject *extensions = EXTENSIONS.dict;
if (extensions == NULL) {
extensions = PyDict_New();
if (extensions == NULL) {
- return -1;
+ goto finally;
}
- EXTENSIONS = extensions;
+ EXTENSIONS.dict = extensions;
}
- PyObject *key = PyTuple_Pack(2, filename, name);
- if (key == NULL) {
- return -1;
+
+ PyModuleDef *actual = (PyModuleDef *)PyDict_GetItemWithError(extensions, key);
+ if (PyErr_Occurred()) {
+ goto finally;
+ }
+ else if (actual != NULL) {
+ /* We expect it to be static, so it must be the same pointer. */
+ assert(def == actual);
+ res = 0;
+ goto finally;
}
- int res = PyDict_SetItem(extensions, key, (PyObject *)def);
- Py_DECREF(key);
+
+ /* This might trigger a resize, which is why we must switch
+ to the main interpreter. */
+ res = PyDict_SetItem(extensions, key, (PyObject *)def);
if (res < 0) {
- return -1;
+ res = -1;
+ goto finally;
}
- return 0;
+ res = 0;
+
+finally:
+ if (oldts != NULL) {
+ _PyThreadState_Swap(interp->runtime, oldts);
+ _PyThreadState_UnbindDetached(main_tstate);
+ Py_DECREF(name);
+ Py_DECREF(filename);
+ }
+ Py_XDECREF(key);
+ extensions_lock_release();
+ return res;
}
static int
_extensions_cache_delete(PyObject *filename, PyObject *name)
{
- PyObject *extensions = EXTENSIONS;
- if (extensions == NULL) {
- return 0;
- }
+ int res = -1;
+ PyThreadState *oldts = NULL;
+ extensions_lock_acquire();
+
PyObject *key = PyTuple_Pack(2, filename, name);
if (key == NULL) {
- return -1;
+ goto finally;
+ }
+
+ PyObject *extensions = EXTENSIONS.dict;
+ if (extensions == NULL) {
+ res = 0;
+ goto finally;
}
+
+ PyModuleDef *actual = (PyModuleDef *)PyDict_GetItemWithError(extensions, key);
+ if (PyErr_Occurred()) {
+ goto finally;
+ }
+ else if (actual == NULL) {
+ /* It was already removed or never added. */
+ res = 0;
+ goto finally;
+ }
+
+ /* Swap to the main interpreter, if necessary. */
+ PyThreadState *main_tstate = &EXTENSIONS.main_tstate;
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ if (!_Py_IsMainInterpreter(interp)) {
+ _PyThreadState_BindDetached(main_tstate);
+ oldts = _PyThreadState_Swap(interp->runtime, main_tstate);
+ assert(!_Py_IsMainInterpreter(oldts->interp));
+ }
+
if (PyDict_DelItem(extensions, key) < 0) {
- if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
- Py_DECREF(key);
- return -1;
- }
- PyErr_Clear();
+ goto finally;
}
- Py_DECREF(key);
- return 0;
+ res = 0;
+
+finally:
+ if (oldts != NULL) {
+ _PyThreadState_Swap(interp->runtime, oldts);
+ _PyThreadState_UnbindDetached(main_tstate);
+ }
+ Py_XDECREF(key);
+ extensions_lock_release();
+ return res;
}
static void
_extensions_cache_clear_all(void)
{
- Py_CLEAR(EXTENSIONS);
+ /* The runtime (i.e. main interpreter) must be finalizing,
+ so we don't need to worry about the lock. */
+ // XXX assert(_Py_IsMainInterpreter(_PyInterpreterState_GET()));
+ Py_CLEAR(EXTENSIONS.dict);
+ _PyThreadState_ClearDetached(&EXTENSIONS.main_tstate);
}
@@ -2941,6 +3052,10 @@ _PyImport_Fini2(void)
PyStatus
_PyImport_InitCore(PyThreadState *tstate, PyObject *sysmod, int importlib)
{
+ if (_Py_IsMainInterpreter(tstate->interp)) {
+ _extensions_cache_init();
+ }
+
// XXX Initialize here: interp->modules and interp->import_func.
// XXX Initialize here: sys.modules and sys.meta_path.
diff --git a/Python/pystate.c b/Python/pystate.c
index b17efdbefd12..1e59a8c5f897 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1217,8 +1217,7 @@ free_threadstate(PyThreadState *tstate)
static void
init_threadstate(PyThreadState *tstate,
- PyInterpreterState *interp, uint64_t id,
- PyThreadState *next)
+ PyInterpreterState *interp, uint64_t id)
{
if (tstate->_status.initialized) {
Py_FatalError("thread state already initialized");
@@ -1227,18 +1226,13 @@ init_threadstate(PyThreadState *tstate,
assert(interp != NULL);
tstate->interp = interp;
+ // next/prev are set in add_threadstate().
+ assert(tstate->next == NULL);
+ assert(tstate->prev == NULL);
+
assert(id > 0);
tstate->id = id;
- assert(interp->threads.head == tstate);
- assert((next != NULL && id != 1) || (next == NULL && id == 1));
- if (next != NULL) {
- assert(next->prev == NULL || next->prev == tstate);
- next->prev = tstate;
- }
- tstate->next = next;
- assert(tstate->prev == NULL);
-
// thread_id and native_thread_id are set in bind_tstate().
tstate->py_recursion_limit = interp->ceval.recursion_limit,
@@ -1259,6 +1253,22 @@ init_threadstate(PyThreadState *tstate,
tstate->_status.initialized = 1;
}
+static void
+add_threadstate(PyInterpreterState *interp, PyThreadState *tstate,
+ PyThreadState *next)
+{
+ assert(interp->threads.head != tstate);
+ assert((next != NULL && tstate->id != 1) ||
+ (next == NULL && tstate->id == 1));
+ if (next != NULL) {
+ assert(next->prev == NULL || next->prev == tstate);
+ next->prev = tstate;
+ }
+ tstate->next = next;
+ assert(tstate->prev == NULL);
+ interp->threads.head = tstate;
+}
+
static PyThreadState *
new_threadstate(PyInterpreterState *interp)
{
@@ -1298,9 +1308,9 @@ new_threadstate(PyInterpreterState *interp)
&initial._main_interpreter._initial_thread,
sizeof(*tstate));
}
- interp->threads.head = tstate;
- init_threadstate(tstate, interp, id, old_head);
+ init_threadstate(tstate, interp, id);
+ add_threadstate(interp, tstate, old_head);
HEAD_UNLOCK(runtime);
if (!used_newtstate) {
@@ -1347,6 +1357,19 @@ _PyThreadState_Init(PyThreadState *tstate)
Py_FatalError("_PyThreadState_Init() is for internal use only");
}
+
+static void
+clear_datastack(PyThreadState *tstate)
+{
+ _PyStackChunk *chunk = tstate->datastack_chunk;
+ tstate->datastack_chunk = NULL;
+ while (chunk != NULL) {
+ _PyStackChunk *prev = chunk->previous;
+ _PyObject_VirtualFree(chunk, chunk->size);
+ chunk = prev;
+ }
+}
+
void
PyThreadState_Clear(PyThreadState *tstate)
{
@@ -1421,7 +1444,6 @@ PyThreadState_Clear(PyThreadState *tstate)
// XXX Do it as early in the function as possible.
}
-
/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
static void
tstate_delete_common(PyThreadState *tstate)
@@ -1454,18 +1476,11 @@ tstate_delete_common(PyThreadState *tstate)
unbind_tstate(tstate);
// XXX Move to PyThreadState_Clear()?
- _PyStackChunk *chunk = tstate->datastack_chunk;
- tstate->datastack_chunk = NULL;
- while (chunk != NULL) {
- _PyStackChunk *prev = chunk->previous;
- _PyObject_VirtualFree(chunk, chunk->size);
- chunk = prev;
- }
+ clear_datastack(tstate);
tstate->_status.finalized = 1;
}
-
static void
zapthreads(PyInterpreterState *interp)
{
@@ -1552,6 +1567,75 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
}
+//-------------------------
+// "detached" thread states
+//-------------------------
+
+void
+_PyThreadState_InitDetached(PyThreadState *tstate, PyInterpreterState *interp)
+{
+ _PyRuntimeState *runtime = interp->runtime;
+
+ HEAD_LOCK(runtime);
+ interp->threads.next_unique_id += 1;
+ uint64_t id = interp->threads.next_unique_id;
+ HEAD_UNLOCK(runtime);
+
+ init_threadstate(tstate, interp, id);
+ // We do not call add_threadstate().
+}
+
+void
+_PyThreadState_ClearDetached(PyThreadState *tstate)
+{
+ assert(!tstate->_status.bound);
+ assert(!tstate->_status.bound_gilstate);
+ assert(tstate->datastack_chunk == NULL);
+ assert(tstate->thread_id == 0);
+ assert(tstate->native_thread_id == 0);
+ assert(tstate->next == NULL);
+ assert(tstate->prev == NULL);
+
+ PyThreadState_Clear(tstate);
+ clear_datastack(tstate);
+}
+
+void
+_PyThreadState_BindDetached(PyThreadState *tstate)
+{
+ assert(!_Py_IsMainInterpreter(
+ current_fast_get(tstate->interp->runtime)->interp));
+ assert(_Py_IsMainInterpreter(tstate->interp));
+ bind_tstate(tstate);
+ /* Unlike _PyThreadState_Bind(), we do not modify gilstate TSS. */
+}
+
+void
+_PyThreadState_UnbindDetached(PyThreadState *tstate)
+{
+ assert(!_Py_IsMainInterpreter(
+ current_fast_get(tstate->interp->runtime)->interp));
+ assert(_Py_IsMainInterpreter(tstate->interp));
+ assert(tstate_is_alive(tstate));
+ assert(!tstate->_status.active);
+ assert(gilstate_tss_get(tstate->interp->runtime) != tstate);
+
+ unbind_tstate(tstate);
+
+ /* This thread state may be bound/unbound repeatedly,
+ so we must erase evidence that it was ever bound (or unbound). */
+ tstate->_status.bound = 0;
+ tstate->_status.unbound = 0;
+
+ /* We must fully unlink the thread state from any OS thread,
+ to allow it to be bound more than once. */
+ tstate->thread_id = 0;
+#ifdef PY_HAVE_THREAD_NATIVE_ID
+ tstate->native_thread_id = 0;
+#endif
+}
+
+
//----------
// accessors
//----------
1
0
https://github.com/python/cpython/commit/121057aa3600c4d4d392539aeb79e1b09f…
commit: 121057aa3600c4d4d392539aeb79e1b09fd5659d
branch: main
author: Brandt Bucher <brandtbucher(a)microsoft.com>
committer: brandtbucher <brandtbucher(a)gmail.com>
date: 2023-03-29T15:53:30-07:00
summary:
GH-89987: Shrink the BINARY_SUBSCR caches (GH-103022)
files:
A Misc/NEWS.d/next/Core and Builtins/2023-03-24-02-50-33.gh-issue-89987.oraTzh.rst
M Include/cpython/object.h
M Include/internal/pycore_code.h
M Include/internal/pycore_opcode.h
M Lib/importlib/_bootstrap_external.py
M Lib/opcode.py
M Lib/test/test_dis.py
M Lib/test/test_sys.py
M Objects/typeobject.c
M Programs/test_frozenmain.h
M Python/bytecodes.c
M Python/generated_cases.c.h
M Python/opcode_metadata.h
M Python/specialize.c
diff --git a/Include/cpython/object.h b/Include/cpython/object.h
index 859ffb91e223..98cc51cd7fee 100644
--- a/Include/cpython/object.h
+++ b/Include/cpython/object.h
@@ -234,7 +234,18 @@ struct _typeobject {
* It should should be treated as an opaque blob
* by code other than the specializer and interpreter. */
struct _specialization_cache {
+ // In order to avoid bloating the bytecode with lots of inline caches, the
+ // members of this structure have a somewhat unique contract. They are set
+ // by the specialization machinery, and are invalidated by PyType_Modified.
+ // The rules for using them are as follows:
+ // - If getitem is non-NULL, then it is the same Python function that
+ // PyType_Lookup(cls, "__getitem__") would return.
+ // - If getitem is NULL, then getitem_version is meaningless.
+ // - If getitem->func_version == getitem_version, then getitem can be called
+ // with two positional arguments and no keyword arguments, and has neither
+ // *args nor **kwargs (as required by BINARY_SUBSCR_GETITEM):
PyObject *getitem;
+ uint32_t getitem_version;
};
/* The *real* layout of a type object when allocated on the heap */
diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h
index 3359dfd8a499..7f3148a38ff1 100644
--- a/Include/internal/pycore_code.h
+++ b/Include/internal/pycore_code.h
@@ -47,8 +47,6 @@ typedef struct {
typedef struct {
uint16_t counter;
- uint16_t type_version[2];
- uint16_t func_version;
} _PyBinarySubscrCache;
#define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache)
diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h
index 4a0b27a13ae9..22914da07994 100644
--- a/Include/internal/pycore_opcode.h
+++ b/Include/internal/pycore_opcode.h
@@ -41,7 +41,7 @@ static const uint32_t _PyOpcode_Jump[9] = {
};
const uint8_t _PyOpcode_Caches[256] = {
- [BINARY_SUBSCR] = 4,
+ [BINARY_SUBSCR] = 1,
[STORE_SUBSCR] = 1,
[UNPACK_SEQUENCE] = 1,
[FOR_ITER] = 1,
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index 28e55fdc8b7d..9c4c5f907744 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -435,7 +435,9 @@ def _write_atomic(path, data, mode=0o666):
# Python 3.12a6 3519 (Modify SEND instruction)
# Python 3.12a6 3520 (Remove PREP_RERAISE_STAR, add CALL_INTRINSIC_2)
# Python 3.12a7 3521 (Shrink the LOAD_GLOBAL caches)
+# Python 3.12a7 3522 (Removed JUMP_IF_FALSE_OR_POP/JUMP_IF_TRUE_OR_POP)
# Python 3.12a7 3523 (Convert COMPARE_AND_BRANCH back to COMPARE_OP)
+# Python 3.12a7 3524 (Shrink the BINARY_SUBSCR caches)
# Python 3.13 will start with 3550
@@ -452,7 +454,7 @@ def _write_atomic(path, data, mode=0o666):
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.
-MAGIC_NUMBER = (3523).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3524).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 60670f571fdc..16a61dff47b5 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -392,8 +392,6 @@ def pseudo_op(name, op, real_ops):
},
"BINARY_SUBSCR": {
"counter": 1,
- "type_version": 2,
- "func_version": 1,
},
"FOR_ITER": {
"counter": 1,
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index 7cad8d1bfe13..7e501045662f 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -1108,7 +1108,7 @@ def test_binary_specialize(self):
1 2 LOAD_NAME 0 (a)
4 LOAD_CONST 0 (0)
6 %s
- 16 RETURN_VALUE
+ 10 RETURN_VALUE
"""
co_list = compile('a[0]', "<list>", "eval")
self.code_quicken(lambda: exec(co_list, {}, {'a': [0]}))
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index fb578c5ae6e5..d7456d6d9480 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -1556,7 +1556,7 @@ def delx(self): del self.__x
'10P' # PySequenceMethods
'2P' # PyBufferProcs
'6P'
- '1P' # Specializer cache
+ '1PI' # Specializer cache
)
class newstyleclass(object): pass
# Separate block for PyDictKeysObject with 8 keys and 5 entries
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-03-24-02-50-33.gh-issue-89987.oraTzh.rst b/Misc/NEWS.d/next/Core and Builtins/2023-03-24-02-50-33.gh-issue-89987.oraTzh.rst
new file mode 100644
index 000000000000..507f68b0c5af
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-03-24-02-50-33.gh-issue-89987.oraTzh.rst
@@ -0,0 +1,2 @@
+Reduce the number of inline :opcode:`CACHE` entries for
+:opcode:`BINARY_SUBSCR`.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 69e84743f13a..24541bddbbc3 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -510,6 +510,11 @@ PyType_Modified(PyTypeObject *type)
type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
type->tp_version_tag = 0; /* 0 is not a valid version tag */
+ if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
+ // This field *must* be invalidated if the type is modified (see the
+ // comment on struct _specialization_cache):
+ ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL;
+ }
}
static void
@@ -563,6 +568,11 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
clear:
type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
type->tp_version_tag = 0; /* 0 is not a valid version tag */
+ if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
+ // This field *must* be invalidated if the type is modified (see the
+ // comment on struct _specialization_cache):
+ ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL;
+ }
}
static int
diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h
index 8e5055bd7bce..c33bb18f4da8 100644
--- a/Programs/test_frozenmain.h
+++ b/Programs/test_frozenmain.h
@@ -1,39 +1,38 @@
// Auto-generated by Programs/freeze_test_frozenmain.py
unsigned char M_test_frozenmain[] = {
227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,
- 0,0,0,0,0,243,182,0,0,0,151,0,100,0,100,1,
+ 0,0,0,0,0,243,170,0,0,0,151,0,100,0,100,1,
108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2,
100,2,171,1,0,0,0,0,0,0,0,0,1,0,2,0,
101,2,100,3,101,0,106,6,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,171,2,0,0,0,0,
0,0,0,0,1,0,2,0,101,1,106,8,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,0,
- 0,0,0,0,0,0,0,0,100,4,25,0,0,0,0,0,
- 0,0,0,0,90,5,100,5,68,0,93,23,0,0,90,6,
- 2,0,101,2,100,6,101,6,155,0,100,7,101,5,101,6,
- 25,0,0,0,0,0,0,0,0,0,155,0,157,4,171,1,
- 0,0,0,0,0,0,0,0,1,0,140,25,4,0,121,1,
- 41,8,233,0,0,0,0,78,122,18,70,114,111,122,101,110,
- 32,72,101,108,108,111,32,87,111,114,108,100,122,8,115,121,
- 115,46,97,114,103,118,218,6,99,111,110,102,105,103,41,5,
- 218,12,112,114,111,103,114,97,109,95,110,97,109,101,218,10,
- 101,120,101,99,117,116,97,98,108,101,218,15,117,115,101,95,
- 101,110,118,105,114,111,110,109,101,110,116,218,17,99,111,110,
- 102,105,103,117,114,101,95,99,95,115,116,100,105,111,218,14,
- 98,117,102,102,101,114,101,100,95,115,116,100,105,111,122,7,
- 99,111,110,102,105,103,32,122,2,58,32,41,7,218,3,115,
- 121,115,218,17,95,116,101,115,116,105,110,116,101,114,110,97,
- 108,99,97,112,105,218,5,112,114,105,110,116,218,4,97,114,
- 103,118,218,11,103,101,116,95,99,111,110,102,105,103,115,114,
- 3,0,0,0,218,3,107,101,121,169,0,243,0,0,0,0,
- 250,18,116,101,115,116,95,102,114,111,122,101,110,109,97,105,
- 110,46,112,121,250,8,60,109,111,100,117,108,101,62,114,18,
- 0,0,0,1,0,0,0,115,100,0,0,0,240,3,1,1,
- 1,243,8,0,1,11,219,0,24,225,0,5,208,6,26,213,
- 0,27,217,0,5,128,106,144,35,151,40,145,40,213,0,27,
- 216,9,38,208,9,26,215,9,38,209,9,38,212,9,40,168,
- 24,212,9,50,128,6,240,2,6,12,2,242,0,7,1,42,
- 128,67,241,14,0,5,10,208,10,40,144,67,209,10,40,152,
- 54,160,35,156,59,209,10,40,214,4,41,241,15,7,1,42,
- 114,16,0,0,0,
+ 0,0,0,0,0,0,0,0,100,4,25,0,0,0,90,5,
+ 100,5,68,0,93,20,0,0,90,6,2,0,101,2,100,6,
+ 101,6,155,0,100,7,101,5,101,6,25,0,0,0,155,0,
+ 157,4,171,1,0,0,0,0,0,0,0,0,1,0,140,22,
+ 4,0,121,1,41,8,233,0,0,0,0,78,122,18,70,114,
+ 111,122,101,110,32,72,101,108,108,111,32,87,111,114,108,100,
+ 122,8,115,121,115,46,97,114,103,118,218,6,99,111,110,102,
+ 105,103,41,5,218,12,112,114,111,103,114,97,109,95,110,97,
+ 109,101,218,10,101,120,101,99,117,116,97,98,108,101,218,15,
+ 117,115,101,95,101,110,118,105,114,111,110,109,101,110,116,218,
+ 17,99,111,110,102,105,103,117,114,101,95,99,95,115,116,100,
+ 105,111,218,14,98,117,102,102,101,114,101,100,95,115,116,100,
+ 105,111,122,7,99,111,110,102,105,103,32,122,2,58,32,41,
+ 7,218,3,115,121,115,218,17,95,116,101,115,116,105,110,116,
+ 101,114,110,97,108,99,97,112,105,218,5,112,114,105,110,116,
+ 218,4,97,114,103,118,218,11,103,101,116,95,99,111,110,102,
+ 105,103,115,114,3,0,0,0,218,3,107,101,121,169,0,243,
+ 0,0,0,0,250,18,116,101,115,116,95,102,114,111,122,101,
+ 110,109,97,105,110,46,112,121,250,8,60,109,111,100,117,108,
+ 101,62,114,18,0,0,0,1,0,0,0,115,100,0,0,0,
+ 240,3,1,1,1,243,8,0,1,11,219,0,24,225,0,5,
+ 208,6,26,213,0,27,217,0,5,128,106,144,35,151,40,145,
+ 40,213,0,27,216,9,38,208,9,26,215,9,38,209,9,38,
+ 212,9,40,168,24,209,9,50,128,6,240,2,6,12,2,242,
+ 0,7,1,42,128,67,241,14,0,5,10,208,10,40,144,67,
+ 209,10,40,152,54,160,35,153,59,209,10,40,214,4,41,241,
+ 15,7,1,42,114,16,0,0,0,
};
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 2fe85dfeedf4..484f6e6b1a1c 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -292,7 +292,7 @@ dummy_func(
BINARY_SUBSCR_TUPLE_INT,
};
- inst(BINARY_SUBSCR, (unused/4, container, sub -- res)) {
+ inst(BINARY_SUBSCR, (unused/1, container, sub -- res)) {
#if ENABLE_SPECIALIZATION
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -339,7 +339,7 @@ dummy_func(
ERROR_IF(err, error);
}
- inst(BINARY_SUBSCR_LIST_INT, (unused/4, list, sub -- res)) {
+ inst(BINARY_SUBSCR_LIST_INT, (unused/1, list, sub -- res)) {
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR);
@@ -356,7 +356,7 @@ dummy_func(
Py_DECREF(list);
}
- inst(BINARY_SUBSCR_TUPLE_INT, (unused/4, tuple, sub -- res)) {
+ inst(BINARY_SUBSCR_TUPLE_INT, (unused/1, tuple, sub -- res)) {
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR);
@@ -373,7 +373,7 @@ dummy_func(
Py_DECREF(tuple);
}
- inst(BINARY_SUBSCR_DICT, (unused/4, dict, sub -- res)) {
+ inst(BINARY_SUBSCR_DICT, (unused/1, dict, sub -- res)) {
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR);
STAT_INC(BINARY_SUBSCR, hit);
@@ -389,14 +389,16 @@ dummy_func(
DECREF_INPUTS();
}
- inst(BINARY_SUBSCR_GETITEM, (unused/1, type_version/2, func_version/1, container, sub -- unused)) {
+ inst(BINARY_SUBSCR_GETITEM, (unused/1, container, sub -- unused)) {
PyTypeObject *tp = Py_TYPE(container);
- DEOPT_IF(tp->tp_version_tag != type_version, BINARY_SUBSCR);
- assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE);
- PyObject *cached = ((PyHeapTypeObject *)tp)->_spec_cache.getitem;
+ DEOPT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE), BINARY_SUBSCR);
+ PyHeapTypeObject *ht = (PyHeapTypeObject *)tp;
+ PyObject *cached = ht->_spec_cache.getitem;
+ DEOPT_IF(cached == NULL, BINARY_SUBSCR);
assert(PyFunction_Check(cached));
PyFunctionObject *getitem = (PyFunctionObject *)cached;
- DEOPT_IF(getitem->func_version != func_version, BINARY_SUBSCR);
+ uint32_t cached_version = ht->_spec_cache.getitem_version;
+ DEOPT_IF(getitem->func_version != cached_version, BINARY_SUBSCR);
PyCodeObject *code = (PyCodeObject *)getitem->func_code;
assert(code->co_argcount == 2);
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR);
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index d793c1e23bc4..d9c66343430f 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -461,7 +461,7 @@
TARGET(BINARY_SUBSCR) {
PREDICTED(BINARY_SUBSCR);
- static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 4, "incorrect cache size");
+ static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size");
PyObject *sub = stack_pointer[-1];
PyObject *container = stack_pointer[-2];
PyObject *res;
@@ -486,7 +486,7 @@
#line 487 "Python/generated_cases.c.h"
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 4;
+ next_instr += 1;
DISPATCH();
}
@@ -559,7 +559,7 @@
#line 560 "Python/generated_cases.c.h"
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 4;
+ next_instr += 1;
DISPATCH();
}
@@ -585,7 +585,7 @@
#line 586 "Python/generated_cases.c.h"
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 4;
+ next_instr += 1;
DISPATCH();
}
@@ -614,23 +614,23 @@
Py_DECREF(sub);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 4;
+ next_instr += 1;
DISPATCH();
}
TARGET(BINARY_SUBSCR_GETITEM) {
PyObject *sub = stack_pointer[-1];
PyObject *container = stack_pointer[-2];
- uint32_t type_version = read_u32(&next_instr[1].cache);
- uint16_t func_version = read_u16(&next_instr[3].cache);
#line 393 "Python/bytecodes.c"
PyTypeObject *tp = Py_TYPE(container);
- DEOPT_IF(tp->tp_version_tag != type_version, BINARY_SUBSCR);
- assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE);
- PyObject *cached = ((PyHeapTypeObject *)tp)->_spec_cache.getitem;
+ DEOPT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE), BINARY_SUBSCR);
+ PyHeapTypeObject *ht = (PyHeapTypeObject *)tp;
+ PyObject *cached = ht->_spec_cache.getitem;
+ DEOPT_IF(cached == NULL, BINARY_SUBSCR);
assert(PyFunction_Check(cached));
PyFunctionObject *getitem = (PyFunctionObject *)cached;
- DEOPT_IF(getitem->func_version != func_version, BINARY_SUBSCR);
+ uint32_t cached_version = ht->_spec_cache.getitem_version;
+ DEOPT_IF(getitem->func_version != cached_version, BINARY_SUBSCR);
PyCodeObject *code = (PyCodeObject *)getitem->func_code;
assert(code->co_argcount == 2);
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR);
@@ -648,7 +648,7 @@
TARGET(LIST_APPEND) {
PyObject *v = stack_pointer[-1];
PyObject *list = stack_pointer[-(2 + (oparg-1))];
- #line 414 "Python/bytecodes.c"
+ #line 416 "Python/bytecodes.c"
if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) goto pop_1_error;
#line 654 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -659,11 +659,11 @@
TARGET(SET_ADD) {
PyObject *v = stack_pointer[-1];
PyObject *set = stack_pointer[-(2 + (oparg-1))];
- #line 419 "Python/bytecodes.c"
+ #line 421 "Python/bytecodes.c"
int err = PySet_Add(set, v);
#line 665 "Python/generated_cases.c.h"
Py_DECREF(v);
- #line 421 "Python/bytecodes.c"
+ #line 423 "Python/bytecodes.c"
if (err) goto pop_1_error;
#line 669 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -678,7 +678,7 @@
PyObject *container = stack_pointer[-2];
PyObject *v = stack_pointer[-3];
uint16_t counter = read_u16(&next_instr[0].cache);
- #line 432 "Python/bytecodes.c"
+ #line 434 "Python/bytecodes.c"
#if ENABLE_SPECIALIZATION
if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
assert(cframe.use_tracing == 0);
@@ -698,7 +698,7 @@
Py_DECREF(v);
Py_DECREF(container);
Py_DECREF(sub);
- #line 448 "Python/bytecodes.c"
+ #line 450 "Python/bytecodes.c"
if (err) goto pop_3_error;
#line 704 "Python/generated_cases.c.h"
STACK_SHRINK(3);
@@ -710,7 +710,7 @@
PyObject *sub = stack_pointer[-1];
PyObject *list = stack_pointer[-2];
PyObject *value = stack_pointer[-3];
- #line 452 "Python/bytecodes.c"
+ #line 454 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR);
DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR);
@@ -738,7 +738,7 @@
PyObject *sub = stack_pointer[-1];
PyObject *dict = stack_pointer[-2];
PyObject *value = stack_pointer[-3];
- #line 472 "Python/bytecodes.c"
+ #line 474 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR);
STAT_INC(STORE_SUBSCR, hit);
@@ -754,13 +754,13 @@
TARGET(DELETE_SUBSCR) {
PyObject *sub = stack_pointer[-1];
PyObject *container = stack_pointer[-2];
- #line 481 "Python/bytecodes.c"
+ #line 483 "Python/bytecodes.c"
/* del container[sub] */
int err = PyObject_DelItem(container, sub);
#line 761 "Python/generated_cases.c.h"
Py_DECREF(container);
Py_DECREF(sub);
- #line 484 "Python/bytecodes.c"
+ #line 486 "Python/bytecodes.c"
if (err) goto pop_2_error;
#line 766 "Python/generated_cases.c.h"
STACK_SHRINK(2);
@@ -770,12 +770,12 @@
TARGET(CALL_INTRINSIC_1) {
PyObject *value = stack_pointer[-1];
PyObject *res;
- #line 488 "Python/bytecodes.c"
+ #line 490 "Python/bytecodes.c"
assert(oparg <= MAX_INTRINSIC_1);
res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value);
#line 777 "Python/generated_cases.c.h"
Py_DECREF(value);
- #line 491 "Python/bytecodes.c"
+ #line 493 "Python/bytecodes.c"
if (res == NULL) goto pop_1_error;
#line 781 "Python/generated_cases.c.h"
stack_pointer[-1] = res;
@@ -786,13 +786,13 @@
PyObject *value1 = stack_pointer[-1];
PyObject *value2 = stack_pointer[-2];
PyObject *res;
- #line 495 "Python/bytecodes.c"
+ #line 497 "Python/bytecodes.c"
assert(oparg <= MAX_INTRINSIC_2);
res = _PyIntrinsics_BinaryFunctions[oparg](tstate, value2, value1);
#line 793 "Python/generated_cases.c.h"
Py_DECREF(value2);
Py_DECREF(value1);
- #line 498 "Python/bytecodes.c"
+ #line 500 "Python/bytecodes.c"
if (res == NULL) goto pop_2_error;
#line 798 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -802,7 +802,7 @@
TARGET(RAISE_VARARGS) {
PyObject **args = (stack_pointer - oparg);
- #line 502 "Python/bytecodes.c"
+ #line 504 "Python/bytecodes.c"
PyObject *cause = NULL, *exc = NULL;
switch (oparg) {
case 2:
@@ -825,7 +825,7 @@
TARGET(INTERPRETER_EXIT) {
PyObject *retval = stack_pointer[-1];
- #line 522 "Python/bytecodes.c"
+ #line 524 "Python/bytecodes.c"
assert(frame == &entry_frame);
assert(_PyFrame_IsIncomplete(frame));
STACK_SHRINK(1); // Since we're not going to DISPATCH()
@@ -842,7 +842,7 @@
TARGET(RETURN_VALUE) {
PyObject *retval = stack_pointer[-1];
- #line 536 "Python/bytecodes.c"
+ #line 538 "Python/bytecodes.c"
STACK_SHRINK(1);
assert(EMPTY());
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -860,7 +860,7 @@
}
TARGET(RETURN_CONST) {
- #line 552 "Python/bytecodes.c"
+ #line 554 "Python/bytecodes.c"
PyObject *retval = GETITEM(frame->f_code->co_consts, oparg);
Py_INCREF(retval);
assert(EMPTY());
@@ -881,7 +881,7 @@
TARGET(GET_AITER) {
PyObject *obj = stack_pointer[-1];
PyObject *iter;
- #line 569 "Python/bytecodes.c"
+ #line 571 "Python/bytecodes.c"
unaryfunc getter = NULL;
PyTypeObject *type = Py_TYPE(obj);
@@ -896,14 +896,14 @@
type->tp_name);
#line 898 "Python/generated_cases.c.h"
Py_DECREF(obj);
- #line 582 "Python/bytecodes.c"
+ #line 584 "Python/bytecodes.c"
if (true) goto pop_1_error;
}
iter = (*getter)(obj);
#line 905 "Python/generated_cases.c.h"
Py_DECREF(obj);
- #line 587 "Python/bytecodes.c"
+ #line 589 "Python/bytecodes.c"
if (iter == NULL) goto pop_1_error;
if (Py_TYPE(iter)->tp_as_async == NULL ||
@@ -924,7 +924,7 @@
TARGET(GET_ANEXT) {
PyObject *aiter = stack_pointer[-1];
PyObject *awaitable;
- #line 602 "Python/bytecodes.c"
+ #line 604 "Python/bytecodes.c"
unaryfunc getter = NULL;
PyObject *next_iter = NULL;
PyTypeObject *type = Py_TYPE(aiter);
@@ -979,7 +979,7 @@
PREDICTED(GET_AWAITABLE);
PyObject *iterable = stack_pointer[-1];
PyObject *iter;
- #line 649 "Python/bytecodes.c"
+ #line 651 "Python/bytecodes.c"
iter = _PyCoro_GetAwaitableIter(iterable);
if (iter == NULL) {
@@ -988,7 +988,7 @@
#line 990 "Python/generated_cases.c.h"
Py_DECREF(iterable);
- #line 656 "Python/bytecodes.c"
+ #line 658 "Python/bytecodes.c"
if (iter != NULL && PyCoro_CheckExact(iter)) {
PyObject *yf = _PyGen_yf((PyGenObject*)iter);
@@ -1017,7 +1017,7 @@
PyObject *v = stack_pointer[-1];
PyObject *receiver = stack_pointer[-2];
PyObject *retval;
- #line 682 "Python/bytecodes.c"
+ #line 684 "Python/bytecodes.c"
#if ENABLE_SPECIALIZATION
_PySendCache *cache = (_PySendCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -1062,7 +1062,7 @@
TARGET(SEND_GEN) {
PyObject *v = stack_pointer[-1];
PyObject *receiver = stack_pointer[-2];
- #line 720 "Python/bytecodes.c"
+ #line 722 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
PyGenObject *gen = (PyGenObject *)receiver;
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type &&
@@ -1083,7 +1083,7 @@
TARGET(YIELD_VALUE) {
PyObject *retval = stack_pointer[-1];
- #line 738 "Python/bytecodes.c"
+ #line 740 "Python/bytecodes.c"
// NOTE: It's important that YIELD_VALUE never raises an exception!
// The compiler treats any exception raised here as a failed close()
// or throw() call.
@@ -1107,7 +1107,7 @@
TARGET(POP_EXCEPT) {
PyObject *exc_value = stack_pointer[-1];
- #line 759 "Python/bytecodes.c"
+ #line 761 "Python/bytecodes.c"
_PyErr_StackItem *exc_info = tstate->exc_info;
Py_XSETREF(exc_info->exc_value, exc_value);
#line 1114 "Python/generated_cases.c.h"
@@ -1118,7 +1118,7 @@
TARGET(RERAISE) {
PyObject *exc = stack_pointer[-1];
PyObject **values = (stack_pointer - (1 + oparg));
- #line 764 "Python/bytecodes.c"
+ #line 766 "Python/bytecodes.c"
assert(oparg >= 0 && oparg <= 2);
if (oparg) {
PyObject *lasti = values[0];
@@ -1142,13 +1142,13 @@
TARGET(END_ASYNC_FOR) {
PyObject *exc = stack_pointer[-1];
PyObject *awaitable = stack_pointer[-2];
- #line 784 "Python/bytecodes.c"
+ #line 786 "Python/bytecodes.c"
assert(exc && PyExceptionInstance_Check(exc));
if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) {
#line 1149 "Python/generated_cases.c.h"
Py_DECREF(awaitable);
Py_DECREF(exc);
- #line 787 "Python/bytecodes.c"
+ #line 789 "Python/bytecodes.c"
}
else {
Py_INCREF(exc);
@@ -1166,7 +1166,7 @@
PyObject *sub_iter = stack_pointer[-3];
PyObject *none;
PyObject *value;
- #line 796 "Python/bytecodes.c"
+ #line 798 "Python/bytecodes.c"
assert(throwflag);
assert(exc_value && PyExceptionInstance_Check(exc_value));
if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) {
@@ -1175,7 +1175,7 @@
Py_DECREF(sub_iter);
Py_DECREF(last_sent_val);
Py_DECREF(exc_value);
- #line 801 "Python/bytecodes.c"
+ #line 803 "Python/bytecodes.c"
none = Py_NewRef(Py_None);
}
else {
@@ -1191,7 +1191,7 @@
TARGET(LOAD_ASSERTION_ERROR) {
PyObject *value;
- #line 810 "Python/bytecodes.c"
+ #line 812 "Python/bytecodes.c"
value = Py_NewRef(PyExc_AssertionError);
#line 1197 "Python/generated_cases.c.h"
STACK_GROW(1);
@@ -1201,7 +1201,7 @@
TARGET(LOAD_BUILD_CLASS) {
PyObject *bc;
- #line 814 "Python/bytecodes.c"
+ #line 816 "Python/bytecodes.c"
if (PyDict_CheckExact(BUILTINS())) {
bc = _PyDict_GetItemWithError(BUILTINS(),
&_Py_ID(__build_class__));
@@ -1231,7 +1231,7 @@
TARGET(STORE_NAME) {
PyObject *v = stack_pointer[-1];
- #line 838 "Python/bytecodes.c"
+ #line 840 "Python/bytecodes.c"
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
PyObject *ns = LOCALS();
int err;
@@ -1240,7 +1240,7 @@
"no locals found when storing %R", name);
#line 1242 "Python/generated_cases.c.h"
Py_DECREF(v);
- #line 845 "Python/bytecodes.c"
+ #line 847 "Python/bytecodes.c"
if (true) goto pop_1_error;
}
if (PyDict_CheckExact(ns))
@@ -1249,7 +1249,7 @@
err = PyObject_SetItem(ns, name, v);
#line 1251 "Python/generated_cases.c.h"
Py_DECREF(v);
- #line 852 "Python/bytecodes.c"
+ #line 854 "Python/bytecodes.c"
if (err) goto pop_1_error;
#line 1255 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -1257,7 +1257,7 @@
}
TARGET(DELETE_NAME) {
- #line 856 "Python/bytecodes.c"
+ #line 858 "Python/bytecodes.c"
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
PyObject *ns = LOCALS();
int err;
@@ -1282,7 +1282,7 @@
PREDICTED(UNPACK_SEQUENCE);
static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size");
PyObject *seq = stack_pointer[-1];
- #line 882 "Python/bytecodes.c"
+ #line 884 "Python/bytecodes.c"
#if ENABLE_SPECIALIZATION
_PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -1298,7 +1298,7 @@
int res = unpack_iterable(tstate, seq, oparg, -1, top);
#line 1300 "Python/generated_cases.c.h"
Py_DECREF(seq);
- #line 896 "Python/bytecodes.c"
+ #line 898 "Python/bytecodes.c"
if (res == 0) goto pop_1_error;
#line 1304 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -1310,7 +1310,7 @@
TARGET(UNPACK_SEQUENCE_TWO_TUPLE) {
PyObject *seq = stack_pointer[-1];
PyObject **values = stack_pointer - (1);
- #line 900 "Python/bytecodes.c"
+ #line 902 "Python/bytecodes.c"
DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE);
DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE);
assert(oparg == 2);
@@ -1328,7 +1328,7 @@
TARGET(UNPACK_SEQUENCE_TUPLE) {
PyObject *seq = stack_pointer[-1];
PyObject **values = stack_pointer - (1);
- #line 910 "Python/bytecodes.c"
+ #line 912 "Python/bytecodes.c"
DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE);
DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE);
STAT_INC(UNPACK_SEQUENCE, hit);
@@ -1347,7 +1347,7 @@
TARGET(UNPACK_SEQUENCE_LIST) {
PyObject *seq = stack_pointer[-1];
PyObject **values = stack_pointer - (1);
- #line 921 "Python/bytecodes.c"
+ #line 923 "Python/bytecodes.c"
DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE);
DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE);
STAT_INC(UNPACK_SEQUENCE, hit);
@@ -1365,13 +1365,13 @@
TARGET(UNPACK_EX) {
PyObject *seq = stack_pointer[-1];
- #line 932 "Python/bytecodes.c"
+ #line 934 "Python/bytecodes.c"
int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8);
PyObject **top = stack_pointer + totalargs - 1;
int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top);
#line 1373 "Python/generated_cases.c.h"
Py_DECREF(seq);
- #line 936 "Python/bytecodes.c"
+ #line 938 "Python/bytecodes.c"
if (res == 0) goto pop_1_error;
#line 1377 "Python/generated_cases.c.h"
STACK_GROW((oparg & 0xFF) + (oparg >> 8));
@@ -1384,7 +1384,7 @@
PyObject *owner = stack_pointer[-1];
PyObject *v = stack_pointer[-2];
uint16_t counter = read_u16(&next_instr[0].cache);
- #line 947 "Python/bytecodes.c"
+ #line 949 "Python/bytecodes.c"
#if ENABLE_SPECIALIZATION
if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
assert(cframe.use_tracing == 0);
@@ -1404,7 +1404,7 @@
#line 1405 "Python/generated_cases.c.h"
Py_DECREF(v);
Py_DECREF(owner);
- #line 964 "Python/bytecodes.c"
+ #line 966 "Python/bytecodes.c"
if (err) goto pop_2_error;
#line 1410 "Python/generated_cases.c.h"
STACK_SHRINK(2);
@@ -1414,12 +1414,12 @@
TARGET(DELETE_ATTR) {
PyObject *owner = stack_pointer[-1];
- #line 968 "Python/bytecodes.c"
+ #line 970 "Python/bytecodes.c"
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
int err = PyObject_SetAttr(owner, name, (PyObject *)NULL);
#line 1421 "Python/generated_cases.c.h"
Py_DECREF(owner);
- #line 971 "Python/bytecodes.c"
+ #line 973 "Python/bytecodes.c"
if (err) goto pop_1_error;
#line 1425 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -1428,12 +1428,12 @@
TARGET(STORE_GLOBAL) {
PyObject *v = stack_pointer[-1];
- #line 975 "Python/bytecodes.c"
+ #line 977 "Python/bytecodes.c"
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
int err = PyDict_SetItem(GLOBALS(), name, v);
#line 1435 "Python/generated_cases.c.h"
Py_DECREF(v);
- #line 978 "Python/bytecodes.c"
+ #line 980 "Python/bytecodes.c"
if (err) goto pop_1_error;
#line 1439 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -1441,7 +1441,7 @@
}
TARGET(DELETE_GLOBAL) {
- #line 982 "Python/bytecodes.c"
+ #line 984 "Python/bytecodes.c"
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
int err;
err = PyDict_DelItem(GLOBALS(), name);
@@ -1459,7 +1459,7 @@
TARGET(LOAD_NAME) {
PyObject *v;
- #line 996 "Python/bytecodes.c"
+ #line 998 "Python/bytecodes.c"
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
PyObject *locals = LOCALS();
if (locals == NULL) {
@@ -1529,7 +1529,7 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size");
PyObject *null = NULL;
PyObject *v;
- #line 1063 "Python/bytecodes.c"
+ #line 1065 "Python/bytecodes.c"
#if ENABLE_SPECIALIZATION
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -1596,7 +1596,7 @@
PyObject *res;
uint16_t index = read_u16(&next_instr[1].cache);
uint16_t version = read_u16(&next_instr[2].cache);
- #line 1118 "Python/bytecodes.c"
+ #line 1120 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
PyDictObject *dict = (PyDictObject *)GLOBALS();
@@ -1623,7 +1623,7 @@
uint16_t index = read_u16(&next_instr[1].cache);
uint16_t mod_version = read_u16(&next_instr[2].cache);
uint16_t bltn_version = read_u16(&next_instr[3].cache);
- #line 1132 "Python/bytecodes.c"
+ #line 1134 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL);
@@ -1648,7 +1648,7 @@
}
TARGET(DELETE_FAST) {
- #line 1149 "Python/bytecodes.c"
+ #line 1151 "Python/bytecodes.c"
PyObject *v = GETLOCAL(oparg);
if (v == NULL) goto unbound_local_error;
SETLOCAL(oparg, NULL);
@@ -1657,7 +1657,7 @@
}
TARGET(MAKE_CELL) {
- #line 1155 "Python/bytecodes.c"
+ #line 1157 "Python/bytecodes.c"
// "initial" is probably NULL but not if it's an arg (or set
// via PyFrame_LocalsToFast() before MAKE_CELL has run).
PyObject *initial = GETLOCAL(oparg);
@@ -1671,7 +1671,7 @@
}
TARGET(DELETE_DEREF) {
- #line 1166 "Python/bytecodes.c"
+ #line 1168 "Python/bytecodes.c"
PyObject *cell = GETLOCAL(oparg);
PyObject *oldobj = PyCell_GET(cell);
// Can't use ERROR_IF here.
@@ -1688,7 +1688,7 @@
TARGET(LOAD_CLASSDEREF) {
PyObject *value;
- #line 1179 "Python/bytecodes.c"
+ #line 1181 "Python/bytecodes.c"
PyObject *name, *locals = LOCALS();
assert(locals);
assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus);
@@ -1728,7 +1728,7 @@
TARGET(LOAD_DEREF) {
PyObject *value;
- #line 1213 "Python/bytecodes.c"
+ #line 1215 "Python/bytecodes.c"
PyObject *cell = GETLOCAL(oparg);
value = PyCell_GET(cell);
if (value == NULL) {
@@ -1744,7 +1744,7 @@
TARGET(STORE_DEREF) {
PyObject *v = stack_pointer[-1];
- #line 1223 "Python/bytecodes.c"
+ #line 1225 "Python/bytecodes.c"
PyObject *cell = GETLOCAL(oparg);
PyObject *oldobj = PyCell_GET(cell);
PyCell_SET(cell, v);
@@ -1755,7 +1755,7 @@
}
TARGET(COPY_FREE_VARS) {
- #line 1230 "Python/bytecodes.c"
+ #line 1232 "Python/bytecodes.c"
/* Copy closure variables to free variables */
PyCodeObject *co = frame->f_code;
assert(PyFunction_Check(frame->f_funcobj));
@@ -1773,13 +1773,13 @@
TARGET(BUILD_STRING) {
PyObject **pieces = (stack_pointer - oparg);
PyObject *str;
- #line 1243 "Python/bytecodes.c"
+ #line 1245 "Python/bytecodes.c"
str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg);
#line 1779 "Python/generated_cases.c.h"
for (int _i = oparg; --_i >= 0;) {
Py_DECREF(pieces[_i]);
}
- #line 1245 "Python/bytecodes.c"
+ #line 1247 "Python/bytecodes.c"
if (str == NULL) { STACK_SHRINK(oparg); goto error; }
#line 1785 "Python/generated_cases.c.h"
STACK_SHRINK(oparg);
@@ -1791,7 +1791,7 @@
TARGET(BUILD_TUPLE) {
PyObject **values = (stack_pointer - oparg);
PyObject *tup;
- #line 1249 "Python/bytecodes.c"
+ #line 1251 "Python/bytecodes.c"
tup = _PyTuple_FromArraySteal(values, oparg);
if (tup == NULL) { STACK_SHRINK(oparg); goto error; }
#line 1798 "Python/generated_cases.c.h"
@@ -1804,7 +1804,7 @@
TARGET(BUILD_LIST) {
PyObject **values = (stack_pointer - oparg);
PyObject *list;
- #line 1254 "Python/bytecodes.c"
+ #line 1256 "Python/bytecodes.c"
list = _PyList_FromArraySteal(values, oparg);
if (list == NULL) { STACK_SHRINK(oparg); goto error; }
#line 1811 "Python/generated_cases.c.h"
@@ -1817,7 +1817,7 @@
TARGET(LIST_EXTEND) {
PyObject *iterable = stack_pointer[-1];
PyObject *list = stack_pointer[-(2 + (oparg-1))];
- #line 1259 "Python/bytecodes.c"
+ #line 1261 "Python/bytecodes.c"
PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable);
if (none_val == NULL) {
if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) &&
@@ -1830,7 +1830,7 @@
}
#line 1832 "Python/generated_cases.c.h"
Py_DECREF(iterable);
- #line 1270 "Python/bytecodes.c"
+ #line 1272 "Python/bytecodes.c"
if (true) goto pop_1_error;
}
Py_DECREF(none_val);
@@ -1843,11 +1843,11 @@
TARGET(SET_UPDATE) {
PyObject *iterable = stack_pointer[-1];
PyObject *set = stack_pointer[-(2 + (oparg-1))];
- #line 1277 "Python/bytecodes.c"
+ #line 1279 "Python/bytecodes.c"
int err = _PySet_Update(set, iterable);
#line 1849 "Python/generated_cases.c.h"
Py_DECREF(iterable);
- #line 1279 "Python/bytecodes.c"
+ #line 1281 "Python/bytecodes.c"
if (err < 0) goto pop_1_error;
#line 1853 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -1857,7 +1857,7 @@
TARGET(BUILD_SET) {
PyObject **values = (stack_pointer - oparg);
PyObject *set;
- #line 1283 "Python/bytecodes.c"
+ #line 1285 "Python/bytecodes.c"
set = PySet_New(NULL);
if (set == NULL)
goto error;
@@ -1882,7 +1882,7 @@
TARGET(BUILD_MAP) {
PyObject **values = (stack_pointer - oparg*2);
PyObject *map;
- #line 1300 "Python/bytecodes.c"
+ #line 1302 "Python/bytecodes.c"
map = _PyDict_FromItems(
values, 2,
values+1, 2,
@@ -1894,7 +1894,7 @@
for (int _i = oparg*2; --_i >= 0;) {
Py_DECREF(values[_i]);
}
- #line 1308 "Python/bytecodes.c"
+ #line 1310 "Python/bytecodes.c"
if (map == NULL) { STACK_SHRINK(oparg*2); goto error; }
#line 1900 "Python/generated_cases.c.h"
STACK_SHRINK(oparg*2);
@@ -1904,7 +1904,7 @@
}
TARGET(SETUP_ANNOTATIONS) {
- #line 1312 "Python/bytecodes.c"
+ #line 1314 "Python/bytecodes.c"
int err;
PyObject *ann_dict;
if (LOCALS() == NULL) {
@@ -1952,7 +1952,7 @@
PyObject *keys = stack_pointer[-1];
PyObject **values = (stack_pointer - (1 + oparg));
PyObject *map;
- #line 1354 "Python/bytecodes.c"
+ #line 1356 "Python/bytecodes.c"
if (!PyTuple_CheckExact(keys) ||
PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) {
_PyErr_SetString(tstate, PyExc_SystemError,
@@ -1967,7 +1967,7 @@
Py_DECREF(values[_i]);
}
Py_DECREF(keys);
- #line 1364 "Python/bytecodes.c"
+ #line 1366 "Python/bytecodes.c"
if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; }
#line 1973 "Python/generated_cases.c.h"
STACK_SHRINK(oparg);
@@ -1977,7 +1977,7 @@
TARGET(DICT_UPDATE) {
PyObject *update = stack_pointer[-1];
- #line 1368 "Python/bytecodes.c"
+ #line 1370 "Python/bytecodes.c"
PyObject *dict = PEEK(oparg + 1); // update is still on the stack
if (PyDict_Update(dict, update) < 0) {
if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
@@ -1987,7 +1987,7 @@
}
#line 1989 "Python/generated_cases.c.h"
Py_DECREF(update);
- #line 1376 "Python/bytecodes.c"
+ #line 1378 "Python/bytecodes.c"
if (true) goto pop_1_error;
}
#line 1994 "Python/generated_cases.c.h"
@@ -1998,14 +1998,14 @@
TARGET(DICT_MERGE) {
PyObject *update = stack_pointer[-1];
- #line 1382 "Python/bytecodes.c"
+ #line 1384 "Python/bytecodes.c"
PyObject *dict = PEEK(oparg + 1); // update is still on the stack
if (_PyDict_MergeEx(dict, update, 2) < 0) {
format_kwargs_error(tstate, PEEK(3 + oparg), update);
#line 2007 "Python/generated_cases.c.h"
Py_DECREF(update);
- #line 1387 "Python/bytecodes.c"
+ #line 1389 "Python/bytecodes.c"
if (true) goto pop_1_error;
}
#line 2012 "Python/generated_cases.c.h"
@@ -2018,7 +2018,7 @@
TARGET(MAP_ADD) {
PyObject *value = stack_pointer[-1];
PyObject *key = stack_pointer[-2];
- #line 1394 "Python/bytecodes.c"
+ #line 1396 "Python/bytecodes.c"
PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack
assert(PyDict_CheckExact(dict));
/* dict[key] = value */
@@ -2036,7 +2036,7 @@
PyObject *owner = stack_pointer[-1];
PyObject *res2 = NULL;
PyObject *res;
- #line 1417 "Python/bytecodes.c"
+ #line 1419 "Python/bytecodes.c"
#if ENABLE_SPECIALIZATION
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -2073,7 +2073,7 @@
*/
#line 2075 "Python/generated_cases.c.h"
Py_DECREF(owner);
- #line 1452 "Python/bytecodes.c"
+ #line 1454 "Python/bytecodes.c"
if (meth == NULL) goto pop_1_error;
res2 = NULL;
res = meth;
@@ -2084,7 +2084,7 @@
res = PyObject_GetAttr(owner, name);
#line 2086 "Python/generated_cases.c.h"
Py_DECREF(owner);
- #line 1461 "Python/bytecodes.c"
+ #line 1463 "Python/bytecodes.c"
if (res == NULL) goto pop_1_error;
}
#line 2091 "Python/generated_cases.c.h"
@@ -2101,7 +2101,7 @@
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
uint16_t index = read_u16(&next_instr[3].cache);
- #line 1466 "Python/bytecodes.c"
+ #line 1468 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
@@ -2130,7 +2130,7 @@
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
uint16_t index = read_u16(&next_instr[3].cache);
- #line 1483 "Python/bytecodes.c"
+ #line 1485 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR);
PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;
@@ -2159,7 +2159,7 @@
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
uint16_t index = read_u16(&next_instr[3].cache);
- #line 1500 "Python/bytecodes.c"
+ #line 1502 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
@@ -2202,7 +2202,7 @@
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
uint16_t index = read_u16(&next_instr[3].cache);
- #line 1531 "Python/bytecodes.c"
+ #line 1533 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
@@ -2228,7 +2228,7 @@
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
PyObject *descr = read_obj(&next_instr[5].cache);
- #line 1545 "Python/bytecodes.c"
+ #line 1547 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyType_Check(cls), LOAD_ATTR);
@@ -2255,7 +2255,7 @@
uint32_t type_version = read_u32(&next_instr[1].cache);
uint32_t func_version = read_u32(&next_instr[3].cache);
PyObject *fget = read_obj(&next_instr[5].cache);
- #line 1561 "Python/bytecodes.c"
+ #line 1563 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR);
@@ -2287,7 +2287,7 @@
uint32_t type_version = read_u32(&next_instr[1].cache);
uint32_t func_version = read_u32(&next_instr[3].cache);
PyObject *getattribute = read_obj(&next_instr[5].cache);
- #line 1587 "Python/bytecodes.c"
+ #line 1589 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR);
PyTypeObject *cls = Py_TYPE(owner);
@@ -2321,7 +2321,7 @@
PyObject *value = stack_pointer[-2];
uint32_t type_version = read_u32(&next_instr[1].cache);
uint16_t index = read_u16(&next_instr[3].cache);
- #line 1615 "Python/bytecodes.c"
+ #line 1617 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
@@ -2351,7 +2351,7 @@
PyObject *value = stack_pointer[-2];
uint32_t type_version = read_u32(&next_instr[1].cache);
uint16_t hint = read_u16(&next_instr[3].cache);
- #line 1636 "Python/bytecodes.c"
+ #line 1638 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
@@ -2402,7 +2402,7 @@
PyObject *value = stack_pointer[-2];
uint32_t type_version = read_u32(&next_instr[1].cache);
uint16_t index = read_u16(&next_instr[3].cache);
- #line 1678 "Python/bytecodes.c"
+ #line 1680 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
@@ -2425,7 +2425,7 @@
PyObject *right = stack_pointer[-1];
PyObject *left = stack_pointer[-2];
PyObject *res;
- #line 1698 "Python/bytecodes.c"
+ #line 1700 "Python/bytecodes.c"
#if ENABLE_SPECIALIZATION
_PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -2442,7 +2442,7 @@
#line 2443 "Python/generated_cases.c.h"
Py_DECREF(left);
Py_DECREF(right);
- #line 1712 "Python/bytecodes.c"
+ #line 1714 "Python/bytecodes.c"
if (res == NULL) goto pop_2_error;
#line 2448 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -2455,7 +2455,7 @@
PyObject *right = stack_pointer[-1];
PyObject *left = stack_pointer[-2];
PyObject *res;
- #line 1716 "Python/bytecodes.c"
+ #line 1718 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP);
DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP);
@@ -2479,7 +2479,7 @@
PyObject *right = stack_pointer[-1];
PyObject *left = stack_pointer[-2];
PyObject *res;
- #line 1732 "Python/bytecodes.c"
+ #line 1734 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP);
DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP);
@@ -2507,7 +2507,7 @@
PyObject *right = stack_pointer[-1];
PyObject *left = stack_pointer[-2];
PyObject *res;
- #line 1752 "Python/bytecodes.c"
+ #line 1754 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP);
DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP);
@@ -2532,12 +2532,12 @@
PyObject *right = stack_pointer[-1];
PyObject *left = stack_pointer[-2];
PyObject *b;
- #line 1768 "Python/bytecodes.c"
+ #line 1770 "Python/bytecodes.c"
int res = Py_Is(left, right) ^ oparg;
#line 2538 "Python/generated_cases.c.h"
Py_DECREF(left);
Py_DECREF(right);
- #line 1770 "Python/bytecodes.c"
+ #line 1772 "Python/bytecodes.c"
b = Py_NewRef(res ? Py_True : Py_False);
#line 2543 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -2549,12 +2549,12 @@
PyObject *right = stack_pointer[-1];
PyObject *left = stack_pointer[-2];
PyObject *b;
- #line 1774 "Python/bytecodes.c"
+ #line 1776 "Python/bytecodes.c"
int res = PySequence_Contains(right, left);
#line 2555 "Python/generated_cases.c.h"
Py_DECREF(left);
Py_DECREF(right);
- #line 1776 "Python/bytecodes.c"
+ #line 1778 "Python/bytecodes.c"
if (res < 0) goto pop_2_error;
b = Py_NewRef((res^oparg) ? Py_True : Py_False);
#line 2561 "Python/generated_cases.c.h"
@@ -2568,12 +2568,12 @@
PyObject *exc_value = stack_pointer[-2];
PyObject *rest;
PyObject *match;
- #line 1781 "Python/bytecodes.c"
+ #line 1783 "Python/bytecodes.c"
if (check_except_star_type_valid(tstate, match_type) < 0) {
#line 2574 "Python/generated_cases.c.h"
Py_DECREF(exc_value);
Py_DECREF(match_type);
- #line 1783 "Python/bytecodes.c"
+ #line 1785 "Python/bytecodes.c"
if (true) goto pop_2_error;
}
@@ -2584,7 +2584,7 @@
#line 2585 "Python/generated_cases.c.h"
Py_DECREF(exc_value);
Py_DECREF(match_type);
- #line 1791 "Python/bytecodes.c"
+ #line 1793 "Python/bytecodes.c"
if (res < 0) goto pop_2_error;
assert((match == NULL) == (rest == NULL));
@@ -2603,19 +2603,19 @@
PyObject *right = stack_pointer[-1];
PyObject *left = stack_pointer[-2];
PyObject *b;
- #line 1802 "Python/bytecodes.c"
+ #line 1804 "Python/bytecodes.c"
assert(PyExceptionInstance_Check(left));
if (check_except_type_valid(tstate, right) < 0) {
#line 2610 "Python/generated_cases.c.h"
Py_DECREF(right);
- #line 1805 "Python/bytecodes.c"
+ #line 1807 "Python/bytecodes.c"
if (true) goto pop_1_error;
}
int res = PyErr_GivenExceptionMatches(left, right);
#line 2617 "Python/generated_cases.c.h"
Py_DECREF(right);
- #line 1810 "Python/bytecodes.c"
+ #line 1812 "Python/bytecodes.c"
b = Py_NewRef(res ? Py_True : Py_False);
#line 2621 "Python/generated_cases.c.h"
stack_pointer[-1] = b;
@@ -2626,13 +2626,13 @@
PyObject *fromlist = stack_pointer[-1];
PyObject *level = stack_pointer[-2];
PyObject *res;
- #line 1814 "Python/bytecodes.c"
+ #line 1816 "Python/bytecodes.c"
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
res = import_name(tstate, frame, name, fromlist, level);
#line 2633 "Python/generated_cases.c.h"
Py_DECREF(level);
Py_DECREF(fromlist);
- #line 1817 "Python/bytecodes.c"
+ #line 1819 "Python/bytecodes.c"
if (res == NULL) goto pop_2_error;
#line 2638 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -2643,7 +2643,7 @@
TARGET(IMPORT_FROM) {
PyObject *from = stack_pointer[-1];
PyObject *res;
- #line 1821 "Python/bytecodes.c"
+ #line 1823 "Python/bytecodes.c"
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
res = import_from(tstate, from, name);
if (res == NULL) goto error;
@@ -2654,7 +2654,7 @@
}
TARGET(JUMP_FORWARD) {
- #line 1827 "Python/bytecodes.c"
+ #line 1829 "Python/bytecodes.c"
JUMPBY(oparg);
#line 2660 "Python/generated_cases.c.h"
DISPATCH();
@@ -2662,7 +2662,7 @@
TARGET(JUMP_BACKWARD) {
PREDICTED(JUMP_BACKWARD);
- #line 1831 "Python/bytecodes.c"
+ #line 1833 "Python/bytecodes.c"
assert(oparg < INSTR_OFFSET());
JUMPBY(-oparg);
#line 2669 "Python/generated_cases.c.h"
@@ -2673,7 +2673,7 @@
TARGET(POP_JUMP_IF_FALSE) {
PREDICTED(POP_JUMP_IF_FALSE);
PyObject *cond = stack_pointer[-1];
- #line 1837 "Python/bytecodes.c"
+ #line 1839 "Python/bytecodes.c"
if (Py_IsTrue(cond)) {
_Py_DECREF_NO_DEALLOC(cond);
}
@@ -2685,7 +2685,7 @@
int err = PyObject_IsTrue(cond);
#line 2687 "Python/generated_cases.c.h"
Py_DECREF(cond);
- #line 1847 "Python/bytecodes.c"
+ #line 1849 "Python/bytecodes.c"
if (err == 0) {
JUMPBY(oparg);
}
@@ -2700,7 +2700,7 @@
TARGET(POP_JUMP_IF_TRUE) {
PyObject *cond = stack_pointer[-1];
- #line 1857 "Python/bytecodes.c"
+ #line 1859 "Python/bytecodes.c"
if (Py_IsFalse(cond)) {
_Py_DECREF_NO_DEALLOC(cond);
}
@@ -2712,7 +2712,7 @@
int err = PyObject_IsTrue(cond);
#line 2714 "Python/generated_cases.c.h"
Py_DECREF(cond);
- #line 1867 "Python/bytecodes.c"
+ #line 1869 "Python/bytecodes.c"
if (err > 0) {
JUMPBY(oparg);
}
@@ -2727,11 +2727,11 @@
TARGET(POP_JUMP_IF_NOT_NONE) {
PyObject *value = stack_pointer[-1];
- #line 1877 "Python/bytecodes.c"
+ #line 1879 "Python/bytecodes.c"
if (!Py_IsNone(value)) {
#line 2733 "Python/generated_cases.c.h"
Py_DECREF(value);
- #line 1879 "Python/bytecodes.c"
+ #line 1881 "Python/bytecodes.c"
JUMPBY(oparg);
}
else {
@@ -2744,7 +2744,7 @@
TARGET(POP_JUMP_IF_NONE) {
PyObject *value = stack_pointer[-1];
- #line 1887 "Python/bytecodes.c"
+ #line 1889 "Python/bytecodes.c"
if (Py_IsNone(value)) {
_Py_DECREF_NO_DEALLOC(value);
JUMPBY(oparg);
@@ -2752,7 +2752,7 @@
else {
#line 2754 "Python/generated_cases.c.h"
Py_DECREF(value);
- #line 1893 "Python/bytecodes.c"
+ #line 1895 "Python/bytecodes.c"
}
#line 2758 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -2760,7 +2760,7 @@
}
TARGET(JUMP_BACKWARD_NO_INTERRUPT) {
- #line 1897 "Python/bytecodes.c"
+ #line 1899 "Python/bytecodes.c"
/* This bytecode is used in the `yield from` or `await` loop.
* If there is an interrupt, we want it handled in the innermost
* generator or coroutine, so we deliberately do not check it here.
@@ -2774,7 +2774,7 @@
TARGET(GET_LEN) {
PyObject *obj = stack_pointer[-1];
PyObject *len_o;
- #line 1906 "Python/bytecodes.c"
+ #line 1908 "Python/bytecodes.c"
// PUSH(len(TOS))
Py_ssize_t len_i = PyObject_Length(obj);
if (len_i < 0) goto error;
@@ -2791,7 +2791,7 @@
PyObject *type = stack_pointer[-2];
PyObject *subject = stack_pointer[-3];
PyObject *attrs;
- #line 1914 "Python/bytecodes.c"
+ #line 1916 "Python/bytecodes.c"
// Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or
// None on failure.
assert(PyTuple_CheckExact(names));
@@ -2800,7 +2800,7 @@
Py_DECREF(subject);
Py_DECREF(type);
Py_DECREF(names);
- #line 1919 "Python/bytecodes.c"
+ #line 1921 "Python/bytecodes.c"
if (attrs) {
assert(PyTuple_CheckExact(attrs)); // Success!
}
@@ -2817,7 +2817,7 @@
TARGET(MATCH_MAPPING) {
PyObject *subject = stack_pointer[-1];
PyObject *res;
- #line 1929 "Python/bytecodes.c"
+ #line 1931 "Python/bytecodes.c"
int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING;
res = Py_NewRef(match ? Py_True : Py_False);
#line 2824 "Python/generated_cases.c.h"
@@ -2830,7 +2830,7 @@
TARGET(MATCH_SEQUENCE) {
PyObject *subject = stack_pointer[-1];
PyObject *res;
- #line 1935 "Python/bytecodes.c"
+ #line 1937 "Python/bytecodes.c"
int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE;
res = Py_NewRef(match ? Py_True : Py_False);
#line 2837 "Python/generated_cases.c.h"
@@ -2844,7 +2844,7 @@
PyObject *keys = stack_pointer[-1];
PyObject *subject = stack_pointer[-2];
PyObject *values_or_none;
- #line 1941 "Python/bytecodes.c"
+ #line 1943 "Python/bytecodes.c"
// On successful match, PUSH(values). Otherwise, PUSH(None).
values_or_none = match_keys(tstate, subject, keys);
if (values_or_none == NULL) goto error;
@@ -2857,12 +2857,12 @@
TARGET(GET_ITER) {
PyObject *iterable = stack_pointer[-1];
PyObject *iter;
- #line 1947 "Python/bytecodes.c"
+ #line 1949 "Python/bytecodes.c"
/* before: [obj]; after [getiter(obj)] */
iter = PyObject_GetIter(iterable);
#line 2864 "Python/generated_cases.c.h"
Py_DECREF(iterable);
- #line 1950 "Python/bytecodes.c"
+ #line 1952 "Python/bytecodes.c"
if (iter == NULL) goto pop_1_error;
#line 2868 "Python/generated_cases.c.h"
stack_pointer[-1] = iter;
@@ -2872,7 +2872,7 @@
TARGET(GET_YIELD_FROM_ITER) {
PyObject *iterable = stack_pointer[-1];
PyObject *iter;
- #line 1954 "Python/bytecodes.c"
+ #line 1956 "Python/bytecodes.c"
/* before: [obj]; after [getiter(obj)] */
if (PyCoro_CheckExact(iterable)) {
/* `iterable` is a coroutine */
@@ -2897,7 +2897,7 @@
}
#line 2899 "Python/generated_cases.c.h"
Py_DECREF(iterable);
- #line 1977 "Python/bytecodes.c"
+ #line 1979 "Python/bytecodes.c"
}
#line 2903 "Python/generated_cases.c.h"
stack_pointer[-1] = iter;
@@ -2910,7 +2910,7 @@
static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size");
PyObject *iter = stack_pointer[-1];
PyObject *next;
- #line 1996 "Python/bytecodes.c"
+ #line 1998 "Python/bytecodes.c"
#if ENABLE_SPECIALIZATION
_PyForIterCache *cache = (_PyForIterCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -2953,7 +2953,7 @@
TARGET(FOR_ITER_LIST) {
PyObject *iter = stack_pointer[-1];
PyObject *next;
- #line 2031 "Python/bytecodes.c"
+ #line 2033 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER);
_PyListIterObject *it = (_PyListIterObject *)iter;
@@ -2984,7 +2984,7 @@
TARGET(FOR_ITER_TUPLE) {
PyObject *iter = stack_pointer[-1];
PyObject *next;
- #line 2054 "Python/bytecodes.c"
+ #line 2056 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
_PyTupleIterObject *it = (_PyTupleIterObject *)iter;
DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER);
@@ -3015,7 +3015,7 @@
TARGET(FOR_ITER_RANGE) {
PyObject *iter = stack_pointer[-1];
PyObject *next;
- #line 2077 "Python/bytecodes.c"
+ #line 2079 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
_PyRangeIterObject *r = (_PyRangeIterObject *)iter;
DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER);
@@ -3043,7 +3043,7 @@
TARGET(FOR_ITER_GEN) {
PyObject *iter = stack_pointer[-1];
- #line 2098 "Python/bytecodes.c"
+ #line 2100 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
PyGenObject *gen = (PyGenObject *)iter;
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER);
@@ -3065,7 +3065,7 @@
PyObject *mgr = stack_pointer[-1];
PyObject *exit;
PyObject *res;
- #line 2115 "Python/bytecodes.c"
+ #line 2117 "Python/bytecodes.c"
PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__));
if (enter == NULL) {
if (!_PyErr_Occurred(tstate)) {
@@ -3090,7 +3090,7 @@
}
#line 3092 "Python/generated_cases.c.h"
Py_DECREF(mgr);
- #line 2138 "Python/bytecodes.c"
+ #line 2140 "Python/bytecodes.c"
res = _PyObject_CallNoArgs(enter);
Py_DECREF(enter);
if (res == NULL) {
@@ -3109,7 +3109,7 @@
PyObject *mgr = stack_pointer[-1];
PyObject *exit;
PyObject *res;
- #line 2148 "Python/bytecodes.c"
+ #line 2150 "Python/bytecodes.c"
/* pop the context manager, push its __exit__ and the
* value returned from calling its __enter__
*/
@@ -3137,7 +3137,7 @@
}
#line 3139 "Python/generated_cases.c.h"
Py_DECREF(mgr);
- #line 2174 "Python/bytecodes.c"
+ #line 2176 "Python/bytecodes.c"
res = _PyObject_CallNoArgs(enter);
Py_DECREF(enter);
if (res == NULL) {
@@ -3156,7 +3156,7 @@
PyObject *lasti = stack_pointer[-3];
PyObject *exit_func = stack_pointer[-4];
PyObject *res;
- #line 2183 "Python/bytecodes.c"
+ #line 2185 "Python/bytecodes.c"
/* At the top of the stack are 4 values:
- val: TOP = exc_info()
- unused: SECOND = previous exception
@@ -3186,7 +3186,7 @@
TARGET(PUSH_EXC_INFO) {
PyObject *new_exc = stack_pointer[-1];
PyObject *prev_exc;
- #line 2206 "Python/bytecodes.c"
+ #line 2208 "Python/bytecodes.c"
_PyErr_StackItem *exc_info = tstate->exc_info;
if (exc_info->exc_value != NULL) {
prev_exc = exc_info->exc_value;
@@ -3210,7 +3210,7 @@
uint32_t type_version = read_u32(&next_instr[1].cache);
uint32_t keys_version = read_u32(&next_instr[3].cache);
PyObject *descr = read_obj(&next_instr[5].cache);
- #line 2218 "Python/bytecodes.c"
+ #line 2220 "Python/bytecodes.c"
/* Cached method object */
assert(cframe.use_tracing == 0);
PyTypeObject *self_cls = Py_TYPE(self);
@@ -3242,7 +3242,7 @@
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
PyObject *descr = read_obj(&next_instr[5].cache);
- #line 2238 "Python/bytecodes.c"
+ #line 2240 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
PyTypeObject *self_cls = Py_TYPE(self);
DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR);
@@ -3267,7 +3267,7 @@
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
PyObject *descr = read_obj(&next_instr[5].cache);
- #line 2251 "Python/bytecodes.c"
+ #line 2253 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
PyTypeObject *self_cls = Py_TYPE(self);
DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR);
@@ -3291,7 +3291,7 @@
}
TARGET(KW_NAMES) {
- #line 2268 "Python/bytecodes.c"
+ #line 2270 "Python/bytecodes.c"
assert(kwnames == NULL);
assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts));
kwnames = GETITEM(frame->f_code->co_consts, oparg);
@@ -3306,7 +3306,7 @@
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2304 "Python/bytecodes.c"
+ #line 2306 "Python/bytecodes.c"
int is_meth = method != NULL;
int total_args = oparg;
if (is_meth) {
@@ -3390,7 +3390,7 @@
TARGET(CALL_BOUND_METHOD_EXACT_ARGS) {
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *method = stack_pointer[-(2 + oparg)];
- #line 2382 "Python/bytecodes.c"
+ #line 2384 "Python/bytecodes.c"
DEOPT_IF(method != NULL, CALL);
DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
STAT_INC(CALL, hit);
@@ -3409,7 +3409,7 @@
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *method = stack_pointer[-(2 + oparg)];
uint32_t func_version = read_u32(&next_instr[1].cache);
- #line 2394 "Python/bytecodes.c"
+ #line 2396 "Python/bytecodes.c"
assert(kwnames == NULL);
DEOPT_IF(tstate->interp->eval_frame, CALL);
int is_meth = method != NULL;
@@ -3443,7 +3443,7 @@
PyObject *method = stack_pointer[-(2 + oparg)];
uint32_t func_version = read_u32(&next_instr[1].cache);
uint16_t min_args = read_u16(&next_instr[3].cache);
- #line 2421 "Python/bytecodes.c"
+ #line 2423 "Python/bytecodes.c"
assert(kwnames == NULL);
DEOPT_IF(tstate->interp->eval_frame, CALL);
int is_meth = method != NULL;
@@ -3481,7 +3481,7 @@
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *null = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2453 "Python/bytecodes.c"
+ #line 2455 "Python/bytecodes.c"
assert(kwnames == NULL);
assert(cframe.use_tracing == 0);
assert(oparg == 1);
@@ -3505,7 +3505,7 @@
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *null = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2466 "Python/bytecodes.c"
+ #line 2468 "Python/bytecodes.c"
assert(kwnames == NULL);
assert(cframe.use_tracing == 0);
assert(oparg == 1);
@@ -3531,7 +3531,7 @@
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *null = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2481 "Python/bytecodes.c"
+ #line 2483 "Python/bytecodes.c"
assert(kwnames == NULL);
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
@@ -3556,7 +3556,7 @@
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2495 "Python/bytecodes.c"
+ #line 2497 "Python/bytecodes.c"
int is_meth = method != NULL;
int total_args = oparg;
if (is_meth) {
@@ -3592,7 +3592,7 @@
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2520 "Python/bytecodes.c"
+ #line 2522 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
/* Builtin METH_O functions */
assert(kwnames == NULL);
@@ -3635,7 +3635,7 @@
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2552 "Python/bytecodes.c"
+ #line 2554 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
/* Builtin METH_FASTCALL functions, without keywords */
assert(kwnames == NULL);
@@ -3682,7 +3682,7 @@
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2588 "Python/bytecodes.c"
+ #line 2590 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
/* Builtin METH_FASTCALL | METH_KEYWORDS functions */
int is_meth = method != NULL;
@@ -3729,7 +3729,7 @@
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2624 "Python/bytecodes.c"
+ #line 2626 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
assert(kwnames == NULL);
/* len(o) */
@@ -3768,7 +3768,7 @@
PyObject *callable = stack_pointer[-(1 + oparg)];
PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2652 "Python/bytecodes.c"
+ #line 2654 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
assert(kwnames == NULL);
/* isinstance(o, o2) */
@@ -3808,7 +3808,7 @@
PyObject **args = (stack_pointer - oparg);
PyObject *self = stack_pointer[-(1 + oparg)];
PyObject *method = stack_pointer[-(2 + oparg)];
- #line 2683 "Python/bytecodes.c"
+ #line 2685 "Python/bytecodes.c"
assert(cframe.use_tracing == 0);
assert(kwnames == NULL);
assert(oparg == 1);
@@ -3834,7 +3834,7 @@
PyObject **args = (stack_pointer - oparg);
PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2704 "Python/bytecodes.c"
+ #line 2706 "Python/bytecodes.c"
assert(kwnames == NULL);
int is_meth = method != NULL;
int total_args = oparg;
@@ -3878,7 +3878,7 @@
PyObject **args = (stack_pointer - oparg);
PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2738 "Python/bytecodes.c"
+ #line 2740 "Python/bytecodes.c"
int is_meth = method != NULL;
int total_args = oparg;
if (is_meth) {
@@ -3920,7 +3920,7 @@
PyObject **args = (stack_pointer - oparg);
PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2770 "Python/bytecodes.c"
+ #line 2772 "Python/bytecodes.c"
assert(kwnames == NULL);
assert(oparg == 0 || oparg == 1);
int is_meth = method != NULL;
@@ -3962,7 +3962,7 @@
PyObject **args = (stack_pointer - oparg);
PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
- #line 2802 "Python/bytecodes.c"
+ #line 2804 "Python/bytecodes.c"
assert(kwnames == NULL);
int is_meth = method != NULL;
int total_args = oparg;
@@ -4005,7 +4005,7 @@
PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))];
PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))];
PyObject *result;
- #line 2833 "Python/bytecodes.c"
+ #line 2835 "Python/bytecodes.c"
if (oparg & 1) {
// DICT_MERGE is called before this opcode if there are kwargs.
// It converts all dict subtypes in kwargs into regular dicts.
@@ -4028,7 +4028,7 @@
Py_DECREF(func);
Py_DECREF(callargs);
Py_XDECREF(kwargs);
- #line 2852 "Python/bytecodes.c"
+ #line 2854 "Python/bytecodes.c"
assert(PEEK(3 + (oparg & 1)) == NULL);
if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; }
@@ -4047,7 +4047,7 @@
PyObject *kwdefaults = (oparg & 0x02) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0))] : NULL;
PyObject *defaults = (oparg & 0x01) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x01) ? 1 : 0))] : NULL;
PyObject *func;
- #line 2863 "Python/bytecodes.c"
+ #line 2865 "Python/bytecodes.c"
PyFunctionObject *func_obj = (PyFunctionObject *)
PyFunction_New(codeobj, GLOBALS());
@@ -4083,7 +4083,7 @@
}
TARGET(RETURN_GENERATOR) {
- #line 2894 "Python/bytecodes.c"
+ #line 2896 "Python/bytecodes.c"
assert(PyFunction_Check(frame->f_funcobj));
PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj;
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
@@ -4112,13 +4112,13 @@
PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))];
PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))];
PyObject *slice;
- #line 2917 "Python/bytecodes.c"
+ #line 2919 "Python/bytecodes.c"
slice = PySlice_New(start, stop, step);
#line 4118 "Python/generated_cases.c.h"
Py_DECREF(start);
Py_DECREF(stop);
Py_XDECREF(step);
- #line 2919 "Python/bytecodes.c"
+ #line 2921 "Python/bytecodes.c"
if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; }
#line 4124 "Python/generated_cases.c.h"
STACK_SHRINK(((oparg == 3) ? 1 : 0));
@@ -4131,7 +4131,7 @@
PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? stack_pointer[-((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))] : NULL;
PyObject *value = stack_pointer[-(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))];
PyObject *result;
- #line 2923 "Python/bytecodes.c"
+ #line 2925 "Python/bytecodes.c"
/* Handles f-string value formatting. */
PyObject *(*conv_fn)(PyObject *);
int which_conversion = oparg & FVC_MASK;
@@ -4175,7 +4175,7 @@
TARGET(COPY) {
PyObject *bottom = stack_pointer[-(1 + (oparg-1))];
PyObject *top;
- #line 2960 "Python/bytecodes.c"
+ #line 2962 "Python/bytecodes.c"
assert(oparg > 0);
top = Py_NewRef(bottom);
#line 4182 "Python/generated_cases.c.h"
@@ -4190,7 +4190,7 @@
PyObject *rhs = stack_pointer[-1];
PyObject *lhs = stack_pointer[-2];
PyObject *res;
- #line 2965 "Python/bytecodes.c"
+ #line 2967 "Python/bytecodes.c"
#if ENABLE_SPECIALIZATION
_PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -4209,7 +4209,7 @@
#line 4210 "Python/generated_cases.c.h"
Py_DECREF(lhs);
Py_DECREF(rhs);
- #line 2981 "Python/bytecodes.c"
+ #line 2983 "Python/bytecodes.c"
if (res == NULL) goto pop_2_error;
#line 4215 "Python/generated_cases.c.h"
STACK_SHRINK(1);
@@ -4221,7 +4221,7 @@
TARGET(SWAP) {
PyObject *top = stack_pointer[-1];
PyObject *bottom = stack_pointer[-(2 + (oparg-2))];
- #line 2986 "Python/bytecodes.c"
+ #line 2988 "Python/bytecodes.c"
assert(oparg >= 2);
#line 4227 "Python/generated_cases.c.h"
stack_pointer[-1] = bottom;
@@ -4230,7 +4230,7 @@
}
TARGET(EXTENDED_ARG) {
- #line 2990 "Python/bytecodes.c"
+ #line 2992 "Python/bytecodes.c"
assert(oparg);
assert(cframe.use_tracing == 0);
opcode = next_instr->op.code;
@@ -4241,7 +4241,7 @@
}
TARGET(CACHE) {
- #line 2999 "Python/bytecodes.c"
+ #line 3001 "Python/bytecodes.c"
Py_UNREACHABLE();
#line 4247 "Python/generated_cases.c.h"
}
diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h
index 347a84dad463..08032519f383 100644
--- a/Python/opcode_metadata.h
+++ b/Python/opcode_metadata.h
@@ -731,13 +731,13 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[256] = {
[BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IX },
[BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC },
[BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC },
- [BINARY_SUBSCR] = { true, INSTR_FMT_IXC000 },
+ [BINARY_SUBSCR] = { true, INSTR_FMT_IXC },
[BINARY_SLICE] = { true, INSTR_FMT_IX },
[STORE_SLICE] = { true, INSTR_FMT_IX },
- [BINARY_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC000 },
- [BINARY_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC000 },
- [BINARY_SUBSCR_DICT] = { true, INSTR_FMT_IXC000 },
- [BINARY_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC000 },
+ [BINARY_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC },
+ [BINARY_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC },
+ [BINARY_SUBSCR_DICT] = { true, INSTR_FMT_IXC },
+ [BINARY_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC },
[LIST_APPEND] = { true, INSTR_FMT_IB },
[SET_ADD] = { true, INSTR_FMT_IB },
[STORE_SUBSCR] = { true, INSTR_FMT_IXC },
diff --git a/Python/specialize.c b/Python/specialize.c
index dd5b22dd2346..9187438d519b 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -1330,16 +1330,16 @@ _Py_Specialize_BinarySubscr(
SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
goto fail;
}
- assert(cls->tp_version_tag != 0);
- write_u32(cache->type_version, cls->tp_version_tag);
- int version = _PyFunction_GetVersionForCurrentState(func);
- if (version == 0 || version != (uint16_t)version) {
- SPECIALIZATION_FAIL(BINARY_SUBSCR, version == 0 ?
- SPEC_FAIL_OUT_OF_VERSIONS : SPEC_FAIL_OUT_OF_RANGE);
+ uint32_t version = _PyFunction_GetVersionForCurrentState(func);
+ if (version == 0) {
+ SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_VERSIONS);
goto fail;
}
- cache->func_version = version;
- ((PyHeapTypeObject *)container_type)->_spec_cache.getitem = descriptor;
+ PyHeapTypeObject *ht = (PyHeapTypeObject *)container_type;
+ // This pointer is invalidated by PyType_Modified (see the comment on
+ // struct _specialization_cache):
+ ht->_spec_cache.getitem = descriptor;
+ ht->_spec_cache.getitem_version = version;
instr->op.code = BINARY_SUBSCR_GETITEM;
goto success;
}
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
[3.10] gh-103112: Add http.client.HTTPResponse.read docstring and fix pydoc output (GH-103113) (#103120)
by terryjreedy 29 Mar '23
by terryjreedy 29 Mar '23
29 Mar '23
https://github.com/python/cpython/commit/3a27be79527368804c3a1c19c5bbe07a8e…
commit: 3a27be79527368804c3a1c19c5bbe07a8e8ce41e
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: terryjreedy <tjreedy(a)udel.edu>
date: 2023-03-29T18:30:27-04:00
summary:
[3.10] gh-103112: Add http.client.HTTPResponse.read docstring and fix pydoc output (GH-103113) (#103120)
(cherry picked from commit d052a383f1a0c599c176a12c73a761ca00436d8b)
Co-authored-by: Bernhard Wagner <github.comNotification20120125(a)xmlizer.net>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot](a)users.noreply.github.com>
Co-authored-by: Terry Jan Reedy <tjreedy(a)udel.edu>
Co-authored-by: Éric <merwok(a)netwok.org>
files:
A Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst
M Lib/http/client.py
diff --git a/Lib/http/client.py b/Lib/http/client.py
index 28527fa8786e..d1b7b1048c91 100644
--- a/Lib/http/client.py
+++ b/Lib/http/client.py
@@ -448,6 +448,7 @@ def isclosed(self):
return self.fp is None
def read(self, amt=None):
+ """Read and return the response body, or up to the next amt bytes."""
if self.fp is None:
return b""
diff --git a/Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst b/Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst
new file mode 100644
index 000000000000..babc81509661
--- /dev/null
+++ b/Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst
@@ -0,0 +1 @@
+Add docstring to :meth:`http.client.HTTPResponse.read` to fix ``pydoc`` output.
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
[3.11] gh-103112: Add http.client.HTTPResponse.read docstring and fix pydoc output (GH-103113) (#103119)
by terryjreedy 29 Mar '23
by terryjreedy 29 Mar '23
29 Mar '23
https://github.com/python/cpython/commit/ae42c1d168a3672964ffbb248e41941781…
commit: ae42c1d168a3672964ffbb248e419417812ad9c0
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: terryjreedy <tjreedy(a)udel.edu>
date: 2023-03-29T18:30:03-04:00
summary:
[3.11] gh-103112: Add http.client.HTTPResponse.read docstring and fix pydoc output (GH-103113) (#103119)
(cherry picked from commit d052a383f1a0c599c176a12c73a761ca00436d8b)
Co-authored-by: Bernhard Wagner <github.comNotification20120125(a)xmlizer.net>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot](a)users.noreply.github.com>
Co-authored-by: Terry Jan Reedy <tjreedy(a)udel.edu>
Co-authored-by: Éric <merwok(a)netwok.org>
files:
A Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst
M Lib/http/client.py
diff --git a/Lib/http/client.py b/Lib/http/client.py
index 4622a8f4297d..eabb0ca26940 100644
--- a/Lib/http/client.py
+++ b/Lib/http/client.py
@@ -448,6 +448,7 @@ def isclosed(self):
return self.fp is None
def read(self, amt=None):
+ """Read and return the response body, or up to the next amt bytes."""
if self.fp is None:
return b""
diff --git a/Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst b/Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst
new file mode 100644
index 000000000000..babc81509661
--- /dev/null
+++ b/Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst
@@ -0,0 +1 @@
+Add docstring to :meth:`http.client.HTTPResponse.read` to fix ``pydoc`` output.
1
0
https://github.com/python/cpython/commit/e647dbaded898e5399d01d06771c1b42b5…
commit: e647dbaded898e5399d01d06771c1b42b5631be8
branch: main
author: Eric Snow <ericsnowcurrently(a)gmail.com>
committer: ericsnowcurrently <ericsnowcurrently(a)gmail.com>
date: 2023-03-29T16:08:40-06:00
summary:
gh-90110: Bring the whitelists up to date. (gh-103114)
https://github.com/python/cpython/issues/90110
files:
M Tools/c-analyzer/cpython/globals-to-fix.tsv
M Tools/c-analyzer/cpython/ignored.tsv
diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv
index 57b8542fb464..e0e45265209f 100644
--- a/Tools/c-analyzer/cpython/globals-to-fix.tsv
+++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv
@@ -457,7 +457,6 @@ Modules/_decimal/_decimal.c - extended_context_template -
Modules/_decimal/_decimal.c - round_map -
Modules/_decimal/_decimal.c - Rational -
Modules/_decimal/_decimal.c - SignalTuple -
-Modules/arraymodule.c array_array___reduce_ex___impl array_reconstructor -
## state
Modules/_asynciomodule.c - fi_freelist -
@@ -539,7 +538,6 @@ Modules/_tkinter.c - command_mutex -
Modules/_tkinter.c - HeadFHCD -
Modules/_tkinter.c - stdin_ready -
Modules/_tkinter.c - event_tstate -
-Modules/_xxinterpchannelsmodule.c - _globals -
Modules/readline.c - completer_word_break_characters -
Modules/readline.c - _history_length -
Modules/readline.c - should_auto_add_history -
diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv
index 9203c1888149..a8ba88efc732 100644
--- a/Tools/c-analyzer/cpython/ignored.tsv
+++ b/Tools/c-analyzer/cpython/ignored.tsv
@@ -156,6 +156,9 @@ Modules/faulthandler.c faulthandler_dump_traceback reentrant -
Python/pylifecycle.c _Py_FatalErrorFormat reentrant -
Python/pylifecycle.c fatal_error reentrant -
+# explicitly protected, internal-only
+Modules/_xxinterpchannelsmodule.c - _globals -
+
##################################
## not significant
1
0
https://github.com/python/cpython/commit/0b1d9c44f1f091a499856d81542eeafda2…
commit: 0b1d9c44f1f091a499856d81542eeafda25011e1
branch: main
author: Brett Cannon <brett(a)python.org>
committer: brettcannon <brett(a)python.org>
date: 2023-03-29T13:28:08-07:00
summary:
GH-102973: add a dev container (GH-102975)
On content update, builds `python` and the docs. Also adds a Dockerfile that should include everything but autoconf 2.69 that's necessary to build CPython and the entire stdlib on Fedora.
Co-authored-by: Ronald Oussoren <ronaldoussoren(a)mac.com>
Co-authored-by: Dusty Phillips <dusty(a)phillips.codes>
files:
A .devcontainer/Dockerfile
A .devcontainer/devcontainer.json
A Misc/NEWS.d/next/Build/2023-03-23-20-58-56.gh-issue-102973.EaJUrw.rst
M Tools/wasm/Setup.local.example
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 000000000000..ce8967337b02
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,24 @@
+FROM docker.io/library/fedora:37
+
+ENV CC=clang
+
+ENV WASI_SDK_VERSION=19
+ENV WASI_SDK_PATH=/opt/wasi-sdk
+
+ENV WASMTIME_HOME=/opt/wasmtime
+ENV WASMTIME_VERSION=7.0.0
+ENV WASMTIME_CPU_ARCH=x86_64
+
+RUN dnf -y --nodocs install git clang xz python3-blurb dnf-plugins-core && \
+ dnf -y --nodocs builddep python3 && \
+ dnf -y clean all
+
+RUN mkdir ${WASI_SDK_PATH} && \
+ curl --location https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_S… | \
+ tar --strip-components 1 --directory ${WASI_SDK_PATH} --extract --gunzip
+
+RUN mkdir --parents ${WASMTIME_HOME} && \
+ curl --location "https://github.com/bytecodealliance/wasmtime/releases/download/v${WASMTIME_…" | \
+ xz --decompress | \
+ tar --strip-components 1 --directory ${WASMTIME_HOME} -x && \
+ ln -s ${WASMTIME_HOME}/wasmtime /usr/local/bin
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 000000000000..e3fb4c6c88f4
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,75 @@
+{
+ "build": {
+ "dockerfile": "Dockerfile"
+ },
+ "onCreateCommand": [
+ // Install common tooling.
+ "dnf",
+ "install",
+ "-y",
+ "which",
+ "zsh",
+ "fish"
+ ],
+ "updateContentCommand": {
+ // Using the shell for `nproc` usage.
+ "python": "./configure --config-cache --with-pydebug && make -s -j `nproc`",
+ "docs": [
+ "make",
+ "--directory",
+ "Doc",
+ "venv",
+ "html"
+ ]
+ },
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ // Highlighting for Parser/Python.asdl.
+ "brettcannon.zephyr-asdl",
+ // Highlighting for configure.ac.
+ "maelvalais.autoconf",
+ // C auto-complete.
+ "ms-vscode.cpptools",
+ // To view built docs.
+ "ms-vscode.live-server"
+ // https://github.com/microsoft/vscode-python/issues/18073
+ // "ms-python.python"
+ ],
+ "settings": {
+ "C_Cpp.default.cStandard": "c11",
+ "C_Cpp.default.defines": [
+ "Py_BUILD_CORE"
+ ],
+ // https://github.com/microsoft/vscode-cpptools/issues/10732
+ "C_Cpp.errorSquiggles": "disabled",
+ "editor.insertSpaces": true,
+ "editor.rulers": [
+ 80
+ ],
+ "editor.tabSize": 4,
+ "editor.trimAutoWhitespace": true,
+ "files.associations": {
+ "*.h": "c"
+ },
+ "files.encoding": "utf8",
+ "files.eol": "\n",
+ "files.insertFinalNewline": true,
+ "files.trimTrailingWhitespace": true,
+ "python.analysis.diagnosticSeverityOverrides": {
+ // Complains about shadowing the stdlib w/ the stdlib.
+ "reportShadowedImports": "none",
+ // Doesn't like _frozen_importlib.
+ "reportMissingImports": "none"
+ },
+ "python.analysis.extraPaths": [
+ "Lib"
+ ],
+ "python.defaultInterpreterPath": "./python",
+ "[restructuredtext]": {
+ "editor.tabSize": 3
+ }
+ }
+ }
+ }
+}
diff --git a/Misc/NEWS.d/next/Build/2023-03-23-20-58-56.gh-issue-102973.EaJUrw.rst b/Misc/NEWS.d/next/Build/2023-03-23-20-58-56.gh-issue-102973.EaJUrw.rst
new file mode 100644
index 000000000000..38b02391266f
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2023-03-23-20-58-56.gh-issue-102973.EaJUrw.rst
@@ -0,0 +1,2 @@
+Add a dev container (along with accompanying Dockerfile) for development
+purposes.
diff --git a/Tools/wasm/Setup.local.example b/Tools/wasm/Setup.local.example
index ad58c31a2efe..cfb9f7fc8755 100644
--- a/Tools/wasm/Setup.local.example
+++ b/Tools/wasm/Setup.local.example
@@ -5,6 +5,7 @@ audioop
_bz2
_crypt
_decimal
+nis
_pickle
pyexpat _elementtree
_sha3 _blake2
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
gh-103112: Add http.client.HTTPResponse.read docstring and fix pydoc output (#103113)
by terryjreedy 29 Mar '23
by terryjreedy 29 Mar '23
29 Mar '23
https://github.com/python/cpython/commit/d052a383f1a0c599c176a12c73a761ca00…
commit: d052a383f1a0c599c176a12c73a761ca00436d8b
branch: main
author: Bernhard Wagner <github.comNotification20120125(a)xmlizer.net>
committer: terryjreedy <tjreedy(a)udel.edu>
date: 2023-03-29T15:21:56-04:00
summary:
gh-103112: Add http.client.HTTPResponse.read docstring and fix pydoc output (#103113)
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot](a)users.noreply.github.com>
Co-authored-by: Terry Jan Reedy <tjreedy(a)udel.edu>
Co-authored-by: Éric <merwok(a)netwok.org>
files:
A Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst
M Lib/http/client.py
diff --git a/Lib/http/client.py b/Lib/http/client.py
index 15c5cf634cf5..bd55e7d239af 100644
--- a/Lib/http/client.py
+++ b/Lib/http/client.py
@@ -448,6 +448,7 @@ def isclosed(self):
return self.fp is None
def read(self, amt=None):
+ """Read and return the response body, or up to the next amt bytes."""
if self.fp is None:
return b""
diff --git a/Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst b/Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst
new file mode 100644
index 000000000000..babc81509661
--- /dev/null
+++ b/Misc/NEWS.d/next/Documentation/2023-03-29-14-51-39.gh-issue-103112.XgGSEO.rst
@@ -0,0 +1 @@
+Add docstring to :meth:`http.client.HTTPResponse.read` to fix ``pydoc`` output.
1
0