From e02a35c36535330bb86b4067104f537aa6da00e4 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Sat, 13 Dec 2025 22:38:10 +0800 Subject: [PATCH 1/3] gh-134584: Cleanups for GH-135860 (GH-142604) --- Include/internal/pycore_opcode_metadata.h | 4 ++-- Include/internal/pycore_uop_ids.h | 2 +- Include/internal/pycore_uop_metadata.h | 8 ++++---- Lib/test/test_capi/test_opt.py | 3 +-- Python/bytecodes.c | 9 ++++++--- Python/executor_cases.c.h | 17 ++++++----------- Python/generated_cases.c.h | 23 ++++++++++++++--------- Python/optimizer_bytecodes.c | 3 ++- Python/optimizer_cases.c.h | 7 +++++-- 9 files changed, 41 insertions(+), 35 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 13e58721ebee9e..82c7cf486b1a00 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1130,7 +1130,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [CALL_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CALL_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, [CHECK_EG_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [CHECK_EXC_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, @@ -1376,7 +1376,7 @@ _PyOpcode_macro_expansion[256] = { [CALL_PY_EXACT_ARGS] = { .nuops = 8, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _CHECK_STACK_SPACE, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _INIT_CALL_PY_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, [CALL_PY_GENERAL] = { .nuops = 6, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_GENERAL, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, [CALL_STR_1] = { .nuops = 4, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_STR_1, OPARG_SIMPLE, 3 }, { _CALL_STR_1, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, - [CALL_TUPLE_1] = { .nuops = 4, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_TUPLE_1, OPARG_SIMPLE, 3 }, { _CALL_TUPLE_1, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, + [CALL_TUPLE_1] = { .nuops = 5, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_TUPLE_1, OPARG_SIMPLE, 3 }, { _CALL_TUPLE_1, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, [CALL_TYPE_1] = { .nuops = 3, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_TYPE_1, OPARG_SIMPLE, 3 }, { _CALL_TYPE_1, OPARG_SIMPLE, 3 } } }, [CHECK_EG_MATCH] = { .nuops = 1, .uops = { { _CHECK_EG_MATCH, OPARG_SIMPLE, 0 } } }, [CHECK_EXC_MATCH] = { .nuops = 1, .uops = { { _CHECK_EXC_MATCH, OPARG_SIMPLE, 0 } } }, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 56928b06685270..ce1ad5a4c8a5f6 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -439,7 +439,7 @@ extern "C" { #define _CALL_METHOD_DESCRIPTOR_O_r01 632 #define _CALL_NON_PY_GENERAL_r01 633 #define _CALL_STR_1_r31 634 -#define _CALL_TUPLE_1_r31 635 +#define _CALL_TUPLE_1_r32 635 #define _CALL_TYPE_1_r31 636 #define _CHECK_AND_ALLOCATE_OBJECT_r00 637 #define _CHECK_ATTR_CLASS_r01 638 diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 2ae84bdee0df12..0a37ce98c7eb48 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -276,7 +276,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_GUARD_CALLABLE_STR_1] = HAS_DEOPT_FLAG, [_CALL_STR_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_GUARD_CALLABLE_TUPLE_1] = HAS_DEOPT_FLAG, - [_CALL_TUPLE_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_CALL_TUPLE_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_CHECK_AND_ALLOCATE_OBJECT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_CREATE_INIT_FRAME] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG, [_EXIT_INIT_CHECK] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, @@ -2543,7 +2543,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, - { 1, 0, _CALL_TUPLE_1_r31 }, + { 2, 0, _CALL_TUPLE_1_r32 }, }, }, [_CHECK_AND_ALLOCATE_OBJECT] = { @@ -3739,7 +3739,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_GUARD_CALLABLE_TUPLE_1_r13] = _GUARD_CALLABLE_TUPLE_1, [_GUARD_CALLABLE_TUPLE_1_r23] = _GUARD_CALLABLE_TUPLE_1, [_GUARD_CALLABLE_TUPLE_1_r33] = _GUARD_CALLABLE_TUPLE_1, - [_CALL_TUPLE_1_r31] = _CALL_TUPLE_1, + [_CALL_TUPLE_1_r32] = _CALL_TUPLE_1, [_CHECK_AND_ALLOCATE_OBJECT_r00] = _CHECK_AND_ALLOCATE_OBJECT, [_CREATE_INIT_FRAME_r01] = _CREATE_INIT_FRAME, [_EXIT_INIT_CHECK_r10] = _EXIT_INIT_CHECK, @@ -4058,7 +4058,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_CALL_STR_1] = "_CALL_STR_1", [_CALL_STR_1_r31] = "_CALL_STR_1_r31", [_CALL_TUPLE_1] = "_CALL_TUPLE_1", - [_CALL_TUPLE_1_r31] = "_CALL_TUPLE_1_r31", + [_CALL_TUPLE_1_r32] = "_CALL_TUPLE_1_r32", [_CALL_TYPE_1] = "_CALL_TYPE_1", [_CALL_TYPE_1_r31] = "_CALL_TYPE_1_r31", [_CHECK_AND_ALLOCATE_OBJECT] = "_CHECK_AND_ALLOCATE_OBJECT", diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index e512c08752a02a..0e7fd62c28a065 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1938,8 +1938,7 @@ def testfunc(n): self.assertIsNotNone(ex) uops = get_opnames(ex) self.assertIn("_CALL_TUPLE_1", uops) - # Re-enable later gh-134584 - # self.assertIn("_POP_TOP_NOP", uops) + self.assertIn("_POP_TOP_NOP", uops) def test_call_str_1(self): def testfunc(n): diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 3e7b7d5594f8f7..d96a1944cd516a 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4068,15 +4068,17 @@ dummy_func( DEOPT_IF(callable_o != (PyObject *)&PyTuple_Type); } - op(_CALL_TUPLE_1, (callable, null, arg -- res)) { + op(_CALL_TUPLE_1, (callable, null, arg -- res, a)) { PyObject *arg_o = PyStackRef_AsPyObjectBorrow(arg); assert(oparg == 1); STAT_INC(CALL, hit); PyObject *res_o = PySequence_Tuple(arg_o); - PyStackRef_CLOSE(arg); + if (res_o == NULL) { + ERROR_NO_POP(); + } + a = arg; INPUTS_DEAD(); - ERROR_IF(res_o == NULL); res = PyStackRef_FromPyObjectSteal(res_o); } @@ -4086,6 +4088,7 @@ dummy_func( _GUARD_NOS_NULL + _GUARD_CALLABLE_TUPLE_1 + _CALL_TUPLE_1 + + POP_TOP + _CHECK_PERIODIC_AT_END; op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 9c2bffb35abbfb..fab23f358682eb 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -12888,11 +12888,12 @@ break; } - case _CALL_TUPLE_1_r31: { + case _CALL_TUPLE_1_r32: { CHECK_CURRENT_CACHED_VALUES(3); assert(WITHIN_STACK_BOUNDS_WITH_CACHE()); _PyStackRef arg; _PyStackRef res; + _PyStackRef a; _PyStackRef _stack_item_0 = _tos_cache0; _PyStackRef _stack_item_1 = _tos_cache1; _PyStackRef _stack_item_2 = _tos_cache2; @@ -12909,23 +12910,17 @@ _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = PySequence_Tuple(arg_o); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(arg); - stack_pointer = _PyFrame_GetStackPointer(frame); if (res_o == NULL) { - stack_pointer += -2; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); SET_CURRENT_CACHED_VALUES(0); JUMP_TO_ERROR(); } + a = arg; res = PyStackRef_FromPyObjectSteal(res_o); + _tos_cache1 = a; _tos_cache0 = res; - _tos_cache1 = PyStackRef_ZERO_BITS; _tos_cache2 = PyStackRef_ZERO_BITS; - SET_CURRENT_CACHED_VALUES(1); - stack_pointer += -2; + SET_CURRENT_CACHED_VALUES(2); + stack_pointer += -3; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); assert(WITHIN_STACK_BOUNDS_WITH_CACHE()); break; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index e72c621f10d340..413593386583a8 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -4040,6 +4040,8 @@ _PyStackRef callable; _PyStackRef arg; _PyStackRef res; + _PyStackRef a; + _PyStackRef value; /* Skip 1 cache entry */ /* Skip 2 cache entries */ // _GUARD_NOS_NULL @@ -4070,21 +4072,24 @@ _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = PySequence_Tuple(arg_o); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(arg); - stack_pointer = _PyFrame_GetStackPointer(frame); if (res_o == NULL) { - JUMP_TO_LABEL(pop_2_error); + JUMP_TO_LABEL(error); } + a = arg; res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC_AT_END + // _POP_TOP { - stack_pointer[-2] = res; - stack_pointer += -1; + value = a; + stack_pointer[-3] = res; + stack_pointer += -2; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + // _CHECK_PERIODIC_AT_END + { _PyFrame_SetStackPointer(frame, stack_pointer); int err = check_periodics(tstate); stack_pointer = _PyFrame_GetStackPointer(frame); diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 61f2dd1e454148..9e767464500d45 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1097,7 +1097,7 @@ dummy_func(void) { } } - op(_CALL_TUPLE_1, (callable, null, arg -- res)) { + op(_CALL_TUPLE_1, (callable, null, arg -- res, a)) { if (sym_matches_type(arg, &PyTuple_Type)) { // e.g. tuple((1, 2)) or tuple(foo) where foo is known to be a tuple // Note: we must strip the reference information because it goes @@ -1107,6 +1107,7 @@ dummy_func(void) { else { res = sym_new_type(ctx, &PyTuple_Type); } + a = arg; } op(_GUARD_TOS_LIST, (tos -- tos)) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 7d95bce7679815..c3f122215ed7bd 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2882,6 +2882,7 @@ case _CALL_TUPLE_1: { JitOptRef arg; JitOptRef res; + JitOptRef a; arg = stack_pointer[-1]; if (sym_matches_type(arg, &PyTuple_Type)) { res = PyJitRef_StripReferenceInfo(arg); @@ -2889,9 +2890,11 @@ else { res = sym_new_type(ctx, &PyTuple_Type); } - CHECK_STACK_BOUNDS(-2); + a = arg; + CHECK_STACK_BOUNDS(-1); stack_pointer[-3] = res; - stack_pointer += -2; + stack_pointer[-2] = a; + stack_pointer += -1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); break; } From 170dac291edc385cf5b46e09c6481be409e0633a Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 13 Dec 2025 17:32:13 +0200 Subject: [PATCH 2/3] gh-76007: Deprecate `__version__` attribute in `http.server` (#142658) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/deprecations/pending-removal-in-3.20.rst | 1 + Doc/whatsnew/3.15.rst | 1 + Lib/http/server.py | 15 +++++++++++---- Lib/test/test_httpservers.py | 10 ++++++++++ Misc/NEWS.d/3.15.0a2.rst | 2 +- .../2025-12-13-00-09-09.gh-issue-76007.Xg1xCO.rst | 2 ++ 6 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-12-13-00-09-09.gh-issue-76007.Xg1xCO.rst diff --git a/Doc/deprecations/pending-removal-in-3.20.rst b/Doc/deprecations/pending-removal-in-3.20.rst index c0feda1968258d..1e517531c953e9 100644 --- a/Doc/deprecations/pending-removal-in-3.20.rst +++ b/Doc/deprecations/pending-removal-in-3.20.rst @@ -9,6 +9,7 @@ Pending removal in Python 3.20 - :mod:`csv` - :mod:`!ctypes.macholib` - :mod:`decimal` (use :data:`decimal.SPEC_VERSION` instead) + - :mod:`http.server` - :mod:`imaplib` - :mod:`ipaddress` - :mod:`json` diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index afefcc15ab2d55..a94486dd4805bd 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1026,6 +1026,7 @@ New deprecations - :mod:`csv` - :mod:`!ctypes.macholib` - :mod:`decimal` (use :data:`decimal.SPEC_VERSION` instead) + - :mod:`http.server` - :mod:`imaplib` - :mod:`ipaddress` - :mod:`json` diff --git a/Lib/http/server.py b/Lib/http/server.py index 160d3eefc7cbdf..9c9cfbce421343 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -61,8 +61,6 @@ # (Actually, the latter is only true if you know the server configuration # at the time the request was made!) -__version__ = "0.6" - __all__ = [ "HTTPServer", "ThreadingHTTPServer", "HTTPSServer", "ThreadingHTTPSServer", @@ -280,7 +278,7 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler): # The server software version. You may want to override this. # The format is multiple whitespace-separated strings, # where each string is of the form name[/version]. - server_version = "BaseHTTP/" + __version__ + server_version = "BaseHTTP" error_message_format = DEFAULT_ERROR_MESSAGE error_content_type = DEFAULT_ERROR_CONTENT_TYPE @@ -690,7 +688,7 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): """ - server_version = "SimpleHTTP/" + __version__ + server_version = "SimpleHTTP" index_pages = ("index.html", "index.htm") extensions_map = _encodings_map_default = { '.gz': 'application/gzip', @@ -1080,5 +1078,14 @@ class HTTPSDualStackServer(DualStackServerMixin, ThreadingHTTPSServer): ) +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 20)) + return "0.6" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + if __name__ == '__main__': _main() diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 7da5e3a1957588..0dc5c9dbaed5d8 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -1560,6 +1560,16 @@ def test_https_client(self): self.assertEqual(res, self.served_data) +class TestModule(unittest.TestCase): + def test_deprecated__version__(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.20", + ) as cm: + getattr(http.server, "__version__") + self.assertEqual(cm.filename, __file__) + + def setUpModule(): unittest.addModuleCleanup(os.chdir, os.getcwd()) diff --git a/Misc/NEWS.d/3.15.0a2.rst b/Misc/NEWS.d/3.15.0a2.rst index 4e3a62b0f4a7d2..4329d8c6bc2265 100644 --- a/Misc/NEWS.d/3.15.0a2.rst +++ b/Misc/NEWS.d/3.15.0a2.rst @@ -583,7 +583,7 @@ would raise an error. .. nonce: peEgcr .. section: Library -Deprecate ``__version__`` from a :mod:`imaplib`. Patch by Hugo van Kemenade. +Deprecate ``__version__`` from :mod:`imaplib`. Patch by Hugo van Kemenade. .. diff --git a/Misc/NEWS.d/next/Library/2025-12-13-00-09-09.gh-issue-76007.Xg1xCO.rst b/Misc/NEWS.d/next/Library/2025-12-13-00-09-09.gh-issue-76007.Xg1xCO.rst new file mode 100644 index 00000000000000..48e9d30497716e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-13-00-09-09.gh-issue-76007.Xg1xCO.rst @@ -0,0 +1,2 @@ +Deprecate ``__version__`` from :mod:`http.server`. Patch by Hugo van +Kemenade. From c865ab3781e92ccc56b1729b2b751ac2769f50a0 Mon Sep 17 00:00:00 2001 From: Joshua Ward Date: Sat, 13 Dec 2025 11:07:53 -0500 Subject: [PATCH 3/3] gh-142568: Fix eval() docs to use 'source' parameter name (#142644) --- Doc/library/functions.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 601745a75780fc..9cfbb5a482e974 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -606,16 +606,16 @@ are always available. They are listed here in alphabetical order. This function executes arbitrary code. Calling it with user-supplied input may lead to security vulnerabilities. - The *expression* argument is parsed and evaluated as a Python expression + The *source* argument is parsed and evaluated as a Python expression (technically speaking, a condition list) using the *globals* and *locals* mappings as global and local namespace. If the *globals* dictionary is present and does not contain a value for the key ``__builtins__``, a reference to the dictionary of the built-in module :mod:`builtins` is - inserted under that key before *expression* is parsed. That way you can + inserted under that key before *source* is parsed. That way you can control what builtins are available to the executed code by inserting your own ``__builtins__`` dictionary into *globals* before passing it to :func:`eval`. If the *locals* mapping is omitted it defaults to the - *globals* dictionary. If both mappings are omitted, the expression is + *globals* dictionary. If both mappings are omitted, the source is executed with the *globals* and *locals* in the environment where :func:`eval` is called. Note, *eval()* will only have access to the :term:`nested scopes ` (non-locals) in the enclosing