From bd0913a8403db0238161a2eca09f9d52b36808c4 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Thu, 24 Sep 2026 15:06:56 +0900 Subject: [PATCH 1/7] gh-157407: Fix a compilation error on Windows. (#158048) `&PyUnicode_Type` cannot be determined at compile time on Windows. Caused by #157393. --- Parser/asdl_c.py | 2 +- Python/Python-ast.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 93baea2130c889c..2b83e97353bbf1f 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -799,7 +799,7 @@ def visitModule(self, mod): FIELD_SEQUENCE = 2, FIELD_BUILTIN = 4, }; - static PyTypeObject *const builtin_types[] = { + PyTypeObject *const builtin_types[] = { ''')) for c_type in builtins: self.emit(f"&{c_type},", 2) diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 2038b14811d3c0a..0d89f7e87f1fa2d 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -832,7 +832,7 @@ add_ast_annotations(struct ast_state *state) FIELD_SEQUENCE = 2, FIELD_BUILTIN = 4, }; - static PyTypeObject *const builtin_types[] = { + PyTypeObject *const builtin_types[] = { &PyUnicode_Type, &PyLong_Type, &PyBaseObject_Type, From daacd2d9a2b47ee277f398ed024afe6ced6f039f Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Thu, 24 Sep 2026 14:54:43 +0800 Subject: [PATCH 2/7] gh-158051: Update testbed to support Xcode 27 (#158052) Modify testbed to target iOS 15 as a minimum, and use a UIScene lifecycle. These changes are required by Xcode 27, but are backwards compatible to at least Xcode 16. --- ...-09-24-10-40-28.gh-issue-158051.B1ZBTA.rst | 1 + .../iOSTestbed.xcodeproj/project.pbxproj | 18 ++++++++++------ .../Apple/testbed/iOSTestbed/AppDelegate.m | 9 ++++++-- .../Apple/testbed/iOSTestbed/SceneDelegate.h | 12 +++++++++++ .../Apple/testbed/iOSTestbed/SceneDelegate.m | 21 +++++++++++++++++++ .../testbed/iOSTestbed/iOSTestbed-Info.plist | 12 ++++++++++- 6 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2026-09-24-10-40-28.gh-issue-158051.B1ZBTA.rst create mode 100644 Platforms/Apple/testbed/iOSTestbed/SceneDelegate.h create mode 100644 Platforms/Apple/testbed/iOSTestbed/SceneDelegate.m diff --git a/Misc/NEWS.d/next/Tests/2026-09-24-10-40-28.gh-issue-158051.B1ZBTA.rst b/Misc/NEWS.d/next/Tests/2026-09-24-10-40-28.gh-issue-158051.B1ZBTA.rst new file mode 100644 index 000000000000000..202fb12086210c7 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2026-09-24-10-40-28.gh-issue-158051.B1ZBTA.rst @@ -0,0 +1 @@ +The iOS testbed has been updated for compatibilty with Xcode 27. diff --git a/Platforms/Apple/testbed/iOSTestbed.xcodeproj/project.pbxproj b/Platforms/Apple/testbed/iOSTestbed.xcodeproj/project.pbxproj index f8835a3bc587df5..1f9e3f23a02dcaf 100644 --- a/Platforms/Apple/testbed/iOSTestbed.xcodeproj/project.pbxproj +++ b/Platforms/Apple/testbed/iOSTestbed.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 607A66172B0EFA380010BFC8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 607A66162B0EFA380010BFC8 /* AppDelegate.m */; }; + 71CB095279CCE565BAFB69C3 /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D995ADFDE8B3EF5DDEB37874 /* SceneDelegate.m */; }; 607A66222B0EFA390010BFC8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607A66212B0EFA390010BFC8 /* Assets.xcassets */; }; 607A66252B0EFA390010BFC8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607A66232B0EFA390010BFC8 /* LaunchScreen.storyboard */; }; 607A66282B0EFA390010BFC8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 607A66272B0EFA390010BFC8 /* main.m */; }; @@ -59,6 +60,8 @@ 607A66122B0EFA380010BFC8 /* iOSTestbed.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOSTestbed.app; sourceTree = BUILT_PRODUCTS_DIR; }; 607A66152B0EFA380010BFC8 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 607A66162B0EFA380010BFC8 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 83DC5E71F9D64737365A3BE4 /* SceneDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SceneDelegate.h; sourceTree = ""; }; + D995ADFDE8B3EF5DDEB37874 /* SceneDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SceneDelegate.m; sourceTree = ""; }; 607A66212B0EFA390010BFC8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 607A66242B0EFA390010BFC8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 607A66272B0EFA390010BFC8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; @@ -120,6 +123,8 @@ 607A66592B0F08600010BFC8 /* iOSTestbed-Info.plist */, 607A66152B0EFA380010BFC8 /* AppDelegate.h */, 607A66162B0EFA380010BFC8 /* AppDelegate.m */, + 83DC5E71F9D64737365A3BE4 /* SceneDelegate.h */, + D995ADFDE8B3EF5DDEB37874 /* SceneDelegate.m */, 607A66212B0EFA390010BFC8 /* Assets.xcassets */, 607A66232B0EFA390010BFC8 /* LaunchScreen.storyboard */, 607A66272B0EFA390010BFC8 /* main.m */, @@ -270,6 +275,7 @@ buildActionMask = 2147483647; files = ( 607A66172B0EFA380010BFC8 /* AppDelegate.m in Sources */, + 71CB095279CCE565BAFB69C3 /* SceneDelegate.m in Sources */, 607A66282B0EFA390010BFC8 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -356,7 +362,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -411,7 +417,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; @@ -437,7 +443,7 @@ INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -468,7 +474,7 @@ INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -491,7 +497,7 @@ DEVELOPMENT_TEAM = 3HEZE76D99; GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/Python.framework/Headers\""; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = org.python.iOSTestbedTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -511,7 +517,7 @@ DEVELOPMENT_TEAM = 3HEZE76D99; GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/Python.framework/Headers\""; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = org.python.iOSTestbedTests; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/Platforms/Apple/testbed/iOSTestbed/AppDelegate.m b/Platforms/Apple/testbed/iOSTestbed/AppDelegate.m index e5085399d0ca5fb..fbe71bae23b7183 100644 --- a/Platforms/Apple/testbed/iOSTestbed/AppDelegate.m +++ b/Platforms/Apple/testbed/iOSTestbed/AppDelegate.m @@ -4,6 +4,7 @@ // #import "AppDelegate.h" +#import "SceneDelegate.h" @interface AppDelegate () @@ -11,9 +12,13 @@ @interface AppDelegate () @implementation AppDelegate +- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { + UISceneConfiguration *configuration = [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role]; + configuration.delegateClass = [SceneDelegate class]; + return configuration; +} -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - return YES; +- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { } @end diff --git a/Platforms/Apple/testbed/iOSTestbed/SceneDelegate.h b/Platforms/Apple/testbed/iOSTestbed/SceneDelegate.h new file mode 100644 index 000000000000000..264aacadca16e5d --- /dev/null +++ b/Platforms/Apple/testbed/iOSTestbed/SceneDelegate.h @@ -0,0 +1,12 @@ +// +// SceneDelegate.h +// iOSTestbed +// + +#import + +@interface SceneDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/Platforms/Apple/testbed/iOSTestbed/SceneDelegate.m b/Platforms/Apple/testbed/iOSTestbed/SceneDelegate.m new file mode 100644 index 000000000000000..e82e447985d2e90 --- /dev/null +++ b/Platforms/Apple/testbed/iOSTestbed/SceneDelegate.m @@ -0,0 +1,21 @@ +// +// SceneDelegate.m +// iOSTestbed +// + +#import "SceneDelegate.h" + +@interface SceneDelegate () + +@end + +@implementation SceneDelegate + +- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { + UIWindowScene *windowScene = (UIWindowScene *)scene; + self.window = [[UIWindow alloc] initWithWindowScene:windowScene]; + self.window.rootViewController = [[UIViewController alloc] init]; + [self.window makeKeyAndVisible]; +} + +@end diff --git a/Platforms/Apple/testbed/iOSTestbed/iOSTestbed-Info.plist b/Platforms/Apple/testbed/iOSTestbed/iOSTestbed-Info.plist index fea45e1fad6f6f6..3a560656972aeca 100644 --- a/Platforms/Apple/testbed/iOSTestbed/iOSTestbed-Info.plist +++ b/Platforms/Apple/testbed/iOSTestbed/iOSTestbed-Info.plist @@ -46,7 +46,17 @@ UIApplicationSupportsMultipleScenes UISceneConfigurations - + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + SceneDelegate + + + From a942c8c8334b72803ff4ee43ffcf9c02914d4116 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 24 Sep 2026 10:05:27 +0300 Subject: [PATCH 3/7] Delete CLAUDE.md (GH-157799) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude Code 2.1.277 now supports AGENTS.md: > Added AGENTS.md support: in a project with no CLAUDE.md, Claude Code reads AGENTS.md instead; change it under “Project instructions” in `/config` (not yet on Bedrock, Vertex or Foundry) https://code.claude.com/docs/en/changelog#2-1-277 --- .claude/CLAUDE.md | 1 - 1 file changed, 1 deletion(-) delete mode 120000 .claude/CLAUDE.md diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md deleted file mode 120000 index be77ac83a1895cf..000000000000000 --- a/.claude/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -../AGENTS.md \ No newline at end of file From 5ec9283f0c69d7820b663d42437be0bdd8a8b5ae Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 24 Sep 2026 11:26:16 +0300 Subject: [PATCH 4/7] gh-156865: Don't raise exceptions for ctypes.c_float_complex overflows (#156919) Co-authored-by: Victor Stinner --- Lib/test/test_ctypes/test_numbers.py | 20 +++++++++++++++++++ ...-09-04-11-45-08.gh-issue-156865.mrdfKJ.rst | 2 ++ Modules/_ctypes/cfield.c | 8 ++++---- 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-09-04-11-45-08.gh-issue-156865.mrdfKJ.rst diff --git a/Lib/test/test_ctypes/test_numbers.py b/Lib/test/test_ctypes/test_numbers.py index b7df08f6079cd31..f67cdf5f7d4e945 100644 --- a/Lib/test/test_ctypes/test_numbers.py +++ b/Lib/test/test_ctypes/test_numbers.py @@ -240,6 +240,26 @@ def test_float_overflow(self): if (hasattr(t, "__ctype_le__")): self.assertRaises(OverflowError, t.__ctype_le__, big_int) + # gh-156865: be silent in overflows of C types + self.assertEqual(ctypes.c_float(3e300).value, float('inf')) + self.assertEqual(ctypes.c_float.__ctype_le__(3e300).value, float('inf')) + self.assertEqual(ctypes.c_float.__ctype_be__(3e300).value, float('inf')) + + @unittest.skipUnless(hasattr(ctypes, "c_float_complex"), + "requires C11 complex type") + def test_complex_overflow(self): + # gh-156865: be silent in overflows of C types + self.assertEqual(ctypes.c_float_complex(3e300).value, complex('inf')) + self.assertEqual(ctypes.c_float_complex.__ctype_le__(3e300).value, + complex('inf')) + self.assertEqual(ctypes.c_float_complex.__ctype_be__(3e300).value, + complex('inf')) + self.assertEqual(ctypes.c_float_complex(3e300j).value, complex('infj')) + self.assertEqual(ctypes.c_float_complex.__ctype_le__(3e300j).value, + complex('infj')) + self.assertEqual(ctypes.c_float_complex.__ctype_be__(3e300j).value, + complex('infj')) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2026-09-04-11-45-08.gh-issue-156865.mrdfKJ.rst b/Misc/NEWS.d/next/Library/2026-09-04-11-45-08.gh-issue-156865.mrdfKJ.rst new file mode 100644 index 000000000000000..e27cd622562a96c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-09-04-11-45-08.gh-issue-156865.mrdfKJ.rst @@ -0,0 +1,2 @@ +Don't raise exceptions on overflows in :class:`ctypes.c_float_complex`. +Patch by Sergey B Kirpichev. diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 00b075bccff6647..193c60a1afee85c 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -865,14 +865,14 @@ Zf_set_sw(void *ptr, PyObject *value, Py_ssize_t size) return NULL; } #ifdef WORDS_BIGENDIAN - if (PyFloat_Pack4(c.real, ptr, 1) - || PyFloat_Pack4(c.imag, ptr + sizeof(float), 1)) + if (PyFloat_Pack4((float)c.real, ptr, 1) + || PyFloat_Pack4((float)c.imag, ptr + sizeof(float), 1)) { return NULL; } #else - if (PyFloat_Pack4(c.real, ptr, 0) - || PyFloat_Pack4(c.imag, ptr + sizeof(float), 0)) + if (PyFloat_Pack4((float)c.real, ptr, 0) + || PyFloat_Pack4((float)c.imag, ptr + sizeof(float), 0)) { return NULL; } From 0b447baeaac43723be7d4903d90f22780cc7e374 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 24 Sep 2026 11:33:51 +0300 Subject: [PATCH 5/7] gh-156865: struct.pack() check for overflows for Zf type (#156868) Co-authored-by: Victor Stinner --- Lib/test/test_struct.py | 14 ++++++++++ ...-09-03-04-32-06.gh-issue-156867.hq3efC.rst | 3 ++ Modules/_struct.c | 28 ++++++++++++++----- 3 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-09-03-04-32-06.gh-issue-156867.hq3efC.rst diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 3809f2d26438955..d0773490ac807b4 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -424,6 +424,20 @@ def test_705836(self): self.assertRaises(OverflowError, struct.pack, "Zf", "StructError, "required argument is not a complex"); return -1; } - memcpy(p, &x, sizeof(x)); + if (PyFloat_Pack4(c.real, tmp, PY_LITTLE_ENDIAN) + || PyFloat_Pack4(c.imag, tmp + 4, PY_LITTLE_ENDIAN)) + { + return -1; + } + memcpy(p, tmp, 8); return 0; } @@ -1132,15 +1137,20 @@ static int bp_float_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { Py_complex x = PyComplex_AsCComplex(v); + char tmp[8]; + if (x.real == -1 && PyErr_Occurred()) { PyErr_SetString(state->StructError, "required argument is not a complex"); return -1; } - if (PyFloat_Pack4(x.real, p, 0)) { + if (PyFloat_Pack4(x.real, tmp, 0) + || PyFloat_Pack4(x.imag, tmp + 4, 0)) + { return -1; } - return PyFloat_Pack4(x.imag, p + 4, 0); + memcpy(p, tmp, 8); + return 0; } static int @@ -1458,16 +1468,20 @@ static int lp_float_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { Py_complex x = PyComplex_AsCComplex(v); + char tmp[8]; + if (x.real == -1 && PyErr_Occurred()) { PyErr_SetString(state->StructError, "required argument is not a complex"); return -1; } - if (PyFloat_Pack4(x.real, p, 1)) { + if (PyFloat_Pack4(x.real, tmp, 1) + || PyFloat_Pack4(x.imag, tmp + 4, 1)) + { return -1; } - return PyFloat_Pack4(x.imag, p + 4, 1); - + memcpy(p, tmp, 8); + return 0; } static int From 82936545cc82c6ae98c5a012a19726a71aeb82fd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 24 Sep 2026 10:47:59 +0200 Subject: [PATCH 6/7] gh-154757: Remove deprecated PyEval_InitThreads() function (#158037) Remove it from the C API, but keep it in the stable ABI. --- Doc/c-api/interp-lifecycle.rst | 4 +-- Doc/c-api/threads.rst | 27 ------------------- Doc/data/stable_abi.dat | 1 - Doc/tools/removed-ids.txt | 1 + Doc/whatsnew/3.16.rst | 4 +++ Include/ceval.h | 2 -- ...-09-23-23-52-55.gh-issue-154757.EUVFeZ.rst | 2 ++ Misc/stable_abi.toml | 1 + Python/ceval_gil.c | 3 ++- 9 files changed, 11 insertions(+), 34 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2026-09-23-23-52-55.gh-issue-154757.EUVFeZ.rst diff --git a/Doc/c-api/interp-lifecycle.rst b/Doc/c-api/interp-lifecycle.rst index 46f5b1dd33963c0..a38d8cec8277466 100644 --- a/Doc/c-api/interp-lifecycle.rst +++ b/Doc/c-api/interp-lifecycle.rst @@ -74,8 +74,7 @@ The following functions can be safely called before Python is initialized: Despite their apparent similarity to some of the functions listed above, the following functions **should not be called** before the interpreter has - been initialized: :c:func:`Py_EncodeLocale`, :c:func:`PyEval_InitThreads`, and - :c:func:`Py_RunMain`. + been initialized: :c:func:`Py_EncodeLocale`, and :c:func:`Py_RunMain`. .. _global-conf-vars: @@ -355,7 +354,6 @@ Initializing and finalizing the interpreter .. c:function:: void Py_Initialize() .. index:: - single: PyEval_InitThreads() single: modules (in module sys) single: path (in module sys) pair: module; builtins diff --git a/Doc/c-api/threads.rst b/Doc/c-api/threads.rst index f48af654e7422bc..70192207ecd1bbe 100644 --- a/Doc/c-api/threads.rst +++ b/Doc/c-api/threads.rst @@ -577,33 +577,6 @@ C extensions. This thread's interpreter state. -.. c:function:: void PyEval_InitThreads() - - .. index:: - single: PyEval_AcquireThread() - single: PyEval_ReleaseThread() - single: PyEval_SaveThread() - single: PyEval_RestoreThread() - - Deprecated function which does nothing. - - In Python 3.6 and older, this function created the GIL if it didn't exist. - - .. versionchanged:: 3.9 - The function now does nothing. - - .. versionchanged:: 3.7 - This function is now called by :c:func:`Py_Initialize()`, so you don't - have to call it yourself anymore. - - .. versionchanged:: 3.2 - This function cannot be called before :c:func:`Py_Initialize()` anymore. - - .. deprecated:: 3.9 - - .. index:: pair: module; _thread - - .. c:function:: PyThreadState* PyEval_SaveThread() Detach the :term:`attached thread state` and return it. diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 3fbff9a0d65362b..65f0e5f52bd936b 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -239,7 +239,6 @@ func,PyEval_GetFuncDesc,3.2,, func,PyEval_GetFuncName,3.2,, func,PyEval_GetGlobals,3.2,, func,PyEval_GetLocals,3.2,, -func,PyEval_InitThreads,3.2,, func,PyEval_ReleaseThread,3.2,, func,PyEval_RestoreThread,3.2,, func,PyEval_SaveThread,3.2,, diff --git a/Doc/tools/removed-ids.txt b/Doc/tools/removed-ids.txt index be3c2f38f194ec2..a6fb127a1e92ae3 100644 --- a/Doc/tools/removed-ids.txt +++ b/Doc/tools/removed-ids.txt @@ -3,6 +3,7 @@ # Remove from here in 3.16 c-api/allocation.html: deprecated-aliases c-api/file.html: deprecated-api +c-api/threads.html: c.PyEval_InitThreads # Removed sections library/asyncio-task.html: terminating-a-task-group diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index 6c38beb04e8d27e..8010379323e7217 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -1141,6 +1141,10 @@ Deprecated C APIs Removed C APIs -------------- +* Remove :c:func:`!PyEval_InitThreads` function which did nothing since Python + 3.7 and was deprecated since Python 3.9. + (Contributed by Victor Stinner in :gh:`154757`.) + * The :c:var:`!PyUnstable_ExecutableKinds` array, as well as the macros :c:macro:`!PyUnstable_EXECUTABLE_KIND_SKIP`, :c:macro:`!PyUnstable_EXECUTABLE_KIND_PY_FUNCTION`, diff --git a/Include/ceval.h b/Include/ceval.h index e9df8684996e23f..93cf38ce6e2264a 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -111,8 +111,6 @@ PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(PyFrameObject *f, int exc); PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void); PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); -Py_DEPRECATED(3.9) PyAPI_FUNC(void) PyEval_InitThreads(void); - PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); diff --git a/Misc/NEWS.d/next/C_API/2026-09-23-23-52-55.gh-issue-154757.EUVFeZ.rst b/Misc/NEWS.d/next/C_API/2026-09-23-23-52-55.gh-issue-154757.EUVFeZ.rst new file mode 100644 index 000000000000000..127d179e9a5286a --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-09-23-23-52-55.gh-issue-154757.EUVFeZ.rst @@ -0,0 +1,2 @@ +Remove :c:func:`!PyEval_InitThreads` function which did nothing since Python +3.7 and was deprecated since Python 3.9. Patch by Victor Stinner. diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index 8ae17142dcc67a0..b7a1e49c8bf4803 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -715,6 +715,7 @@ added = '3.2' [function.PyEval_InitThreads] added = '3.2' + abi_only = true [function.PyEval_ReleaseLock] added = '3.2' abi_only = true diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c index 2425bc1b39f0dcc..49b2ede4ed3e60f 100644 --- a/Python/ceval_gil.c +++ b/Python/ceval_gil.c @@ -550,7 +550,8 @@ _PyEval_FiniGIL(PyInterpreterState *interp) interp->ceval.gil = NULL; } -void +// Function removed in Python 3.16 limited C API, but kept in the stable ABI +PyAPI_FUNC(void) PyEval_InitThreads(void) { /* Do nothing: kept for backward compatibility */ From a5a4659548ed112692c7617a295577f0e6eee6df Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 24 Sep 2026 12:52:54 +0200 Subject: [PATCH 7/7] gh-158001: Remove Py_SetProgramName() function (#158024) Remove Py_SetProgramName(), Py_SetPythonHome(), PySys_SetArgv() and PySys_SetArgvEx() functions, deprecated since Python 3.11. Mark the 4 functions as abi_only in stable_abi.toml. --- Doc/c-api/interp-lifecycle.rst | 126 ------------------ Doc/data/refcounts.dat | 12 -- Doc/data/stable_abi.dat | 4 - Doc/tools/removed-ids.txt | 4 + Doc/whatsnew/3.16.rst | 11 ++ Include/pylifecycle.h | 4 - Include/sysmodule.h | 3 - ...-09-23-21-45-43.gh-issue-158001.R_wX4E.rst | 3 + Misc/stable_abi.toml | 4 + Programs/_testembed.c | 4 + Python/pathconfig.c | 6 +- Python/sysmodule.c | 9 +- 12 files changed, 34 insertions(+), 156 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2026-09-23-21-45-43.gh-issue-158001.R_wX4E.rst diff --git a/Doc/c-api/interp-lifecycle.rst b/Doc/c-api/interp-lifecycle.rst index a38d8cec8277466..6f832b7a34b10b9 100644 --- a/Doc/c-api/interp-lifecycle.rst +++ b/Doc/c-api/interp-lifecycle.rst @@ -37,8 +37,6 @@ The following functions can be safely called before Python is initialized: * :c:func:`PyMem_SetAllocator` * :c:func:`PyMem_SetupDebugHooks` * :c:func:`PyObject_SetArenaAllocator` - * :c:func:`Py_SetProgramName` - * :c:func:`Py_SetPythonHome` * the configuration functions covered in :ref:`init-config` * Informative functions: @@ -778,33 +776,6 @@ deleted. This can be done using interpreter views. Process-wide parameters ----------------------- -.. c:function:: void Py_SetProgramName(const wchar_t *name) - - .. index:: - single: Py_Initialize() - single: main() - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.program_name` should be used instead, see :ref:`Python - Initialization Configuration `. - - This function should be called before :c:func:`Py_Initialize` is called for - the first time, if it is called at all. It tells the interpreter the value - of the ``argv[0]`` argument to the :c:func:`main` function of the program - (converted to wide characters). - This is used by some other functions below to find - the Python run-time libraries relative to the interpreter executable. The - default value is ``'python'``. The argument should point to a - zero-terminated wide character string in static storage whose contents will not - change for the duration of the program's execution. No code in the Python - interpreter will change the contents of this storage. - - Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a - :c:expr:`wchar_t*` string. - - .. deprecated-removed:: 3.11 3.16 - - .. c:function:: const char* Py_GetVersion() Return the version of this Python interpreter. This is a string that looks @@ -873,100 +844,3 @@ Process-wide parameters The returned string points into static storage; the caller should not modify its value. The value is available to Python code as part of the variable ``sys.version``. - - -.. c:function:: void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) - - .. index:: - single: main() - single: Py_FatalError() - single: argv (in module sys) - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.argv`, :c:member:`PyConfig.parse_argv` and - :c:member:`PyConfig.safe_path` should be used instead, see :ref:`Python - Initialization Configuration `. - - Set :data:`sys.argv` based on *argc* and *argv*. These parameters are - similar to those passed to the program's :c:func:`main` function with the - difference that the first entry should refer to the script file to be - executed rather than the executable hosting the Python interpreter. If there - isn't a script that will be run, the first entry in *argv* can be an empty - string. If this function fails to initialize :data:`sys.argv`, a fatal - condition is signalled using :c:func:`Py_FatalError`. - - If *updatepath* is zero, this is all the function does. If *updatepath* - is non-zero, the function also modifies :data:`sys.path` according to the - following algorithm: - - - If the name of an existing script is passed in ``argv[0]``, the absolute - path of the directory where the script is located is prepended to - :data:`sys.path`. - - Otherwise (that is, if *argc* is ``0`` or ``argv[0]`` doesn't point - to an existing file name), an empty string is prepended to - :data:`sys.path`, which is the same as prepending the current working - directory (``"."``). - - Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a - :c:expr:`wchar_t*` string. - - See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv` - members of the :ref:`Python Initialization Configuration `. - - .. note:: - It is recommended that applications embedding the Python interpreter - for purposes other than executing a single script pass ``0`` as *updatepath*, - and update :data:`sys.path` themselves if desired. - See :cve:`2008-5983`. - - On versions before 3.1.3, you can achieve the same effect by manually - popping the first :data:`sys.path` element after having called - :c:func:`PySys_SetArgv`, for example using:: - - PyRun_SimpleString("import sys; sys.path.pop(0)\n"); - - .. versionadded:: 3.1.3 - - .. deprecated-removed:: 3.11 3.16 - - -.. c:function:: void PySys_SetArgv(int argc, wchar_t **argv) - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.argv` and :c:member:`PyConfig.parse_argv` should be used - instead, see :ref:`Python Initialization Configuration `. - - This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set - to ``1`` unless the :program:`python` interpreter was started with the - :option:`-I`. - - Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a - :c:expr:`wchar_t*` string. - - See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv` - members of the :ref:`Python Initialization Configuration `. - - .. versionchanged:: 3.4 The *updatepath* value depends on :option:`-I`. - - .. deprecated-removed:: 3.11 3.16 - - -.. c:function:: void Py_SetPythonHome(const wchar_t *home) - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.home` should be used instead, see :ref:`Python - Initialization Configuration `. - - Set the default "home" directory, that is, the location of the standard - Python libraries. See :envvar:`PYTHONHOME` for the meaning of the - argument string. - - The argument should point to a zero-terminated character string in static - storage whose contents will not change for the duration of the program's - execution. No code in the Python interpreter will change the contents of - this storage. - - Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a - :c:expr:`wchar_t*` string. - - .. deprecated-removed:: 3.11 3.16 diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 60c02aabeb89c51..c19a8a3083a4302 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -2265,15 +2265,6 @@ PySys_GetObject:const char*:name:: PySys_GetXOptions:PyObject*::0: -PySys_SetArgv:void::: -PySys_SetArgv:int:argc:: -PySys_SetArgv:wchar_t**:argv:: - -PySys_SetArgvEx:void::: -PySys_SetArgvEx:int:argc:: -PySys_SetArgvEx:wchar_t**:argv:: -PySys_SetArgvEx:int:updatepath:: - PySys_SetObject:int::: PySys_SetObject:const char*:name:: PySys_SetObject:PyObject*:v:+1: @@ -3085,9 +3076,6 @@ Py_ReprEnter:PyObject*:object:+1: Py_ReprLeave:void::: Py_ReprLeave:PyObject*:object:-1: -Py_SetProgramName:void::: -Py_SetProgramName:const wchar_t*:name:: - Py_XDECREF:void::: Py_XDECREF:PyObject*:o:-1:if o is not NULL diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 65f0e5f52bd936b..662158323c5d305 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -717,8 +717,6 @@ func,PySys_GetObject,3.2,, func,PySys_GetOptionalAttr,3.15,, func,PySys_GetOptionalAttrString,3.15,, func,PySys_GetXOptions,3.7,, -func,PySys_SetArgv,3.2,, -func,PySys_SetArgvEx,3.2,, func,PySys_SetObject,3.2,, func,PySys_WriteStderr,3.2,, func,PySys_WriteStdout,3.2,, @@ -993,8 +991,6 @@ func,Py_ReprEnter,3.2,, func,Py_ReprLeave,3.2,, func,Py_SET_SIZE,3.15,, func,Py_SIZE,3.15,, -func,Py_SetProgramName,3.2,, -func,Py_SetPythonHome,3.2,, func,Py_SetRecursionLimit,3.2,, macro,Py_TPFLAGS_BASETYPE,3.2,, macro,Py_TPFLAGS_DEFAULT,3.2,, diff --git a/Doc/tools/removed-ids.txt b/Doc/tools/removed-ids.txt index a6fb127a1e92ae3..3f7906ee84ec148 100644 --- a/Doc/tools/removed-ids.txt +++ b/Doc/tools/removed-ids.txt @@ -3,6 +3,10 @@ # Remove from here in 3.16 c-api/allocation.html: deprecated-aliases c-api/file.html: deprecated-api +c-api/interp-lifecycle.html: c.PySys_SetArgv +c-api/interp-lifecycle.html: c.PySys_SetArgvEx +c-api/interp-lifecycle.html: c.Py_SetProgramName +c-api/interp-lifecycle.html: c.Py_SetPythonHome c-api/threads.html: c.PyEval_InitThreads # Removed sections diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index 8010379323e7217..c76681261f6746d 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -1145,6 +1145,17 @@ Removed C APIs 3.7 and was deprecated since Python 3.9. (Contributed by Victor Stinner in :gh:`154757`.) +* Remove :c:func:`!Py_SetProgramName` and :c:func:`!Py_SetPythonHome` + functions, deprecated since Python 3.11. Instead, use :ref:`PyInitConfig C + API ` to set respectively ``"program_name"`` and + ``"home"``. + (Contributed by Victor Stinner in :gh:`158001`.) + +* Remove :c:func:`!PySys_SetArgv` and :c:func:`!PySys_SetArgvEx` functions, + deprecated since Python 3.11. Instead, set directly :data:`sys.argv`, and + maybe also :data:`sys.path`. + (Contributed by Victor Stinner in :gh:`158001`.) + * The :c:var:`!PyUnstable_ExecutableKinds` array, as well as the macros :c:macro:`!PyUnstable_EXECUTABLE_KIND_SKIP`, :c:macro:`!PyUnstable_EXECUTABLE_KIND_PY_FUNCTION`, diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h index 4b3474035cec192..f11ac4d2a9f10e9 100644 --- a/Include/pylifecycle.h +++ b/Include/pylifecycle.h @@ -33,10 +33,6 @@ PyAPI_FUNC(void) _Py_NO_RETURN Py_Exit(int); PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv); -/* In pathconfig.c */ -Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *); -Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *); - #ifdef MS_WINDOWS int _Py_CheckPython3(void); #endif diff --git a/Include/sysmodule.h b/Include/sysmodule.h index b7d800c5e5db0b9..fc6da6f4c797b36 100644 --- a/Include/sysmodule.h +++ b/Include/sysmodule.h @@ -13,9 +13,6 @@ PyAPI_FUNC(int) PySys_GetOptionalAttrString(const char *, PyObject **); PyAPI_FUNC(PyObject *) PySys_GetObject(const char *); PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *); -Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **); -Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int); - PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) Py_GCC_ATTRIBUTE((format(printf, 1, 2))); PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) diff --git a/Misc/NEWS.d/next/C_API/2026-09-23-21-45-43.gh-issue-158001.R_wX4E.rst b/Misc/NEWS.d/next/C_API/2026-09-23-21-45-43.gh-issue-158001.R_wX4E.rst new file mode 100644 index 000000000000000..2da45967b24597a --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-09-23-21-45-43.gh-issue-158001.R_wX4E.rst @@ -0,0 +1,3 @@ +Remove :c:func:`!Py_SetProgramName`, :c:func:`!Py_SetPythonHome`, +:c:func:`!PySys_SetArgv` and :c:func:`!PySys_SetArgvEx` functions, deprecated +since Python 3.11. Patch by Victor Stinner. diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index b7a1e49c8bf4803..08fd7009dbc4b86 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -1350,8 +1350,10 @@ abi_only = true [function.PySys_SetArgv] added = '3.2' + abi_only = true [function.PySys_SetArgvEx] added = '3.2' + abi_only = true [function.PySys_SetObject] added = '3.2' [function.PySys_SetPath] @@ -1695,8 +1697,10 @@ added = '3.2' [function.Py_SetProgramName] added = '3.2' + abi_only = true [function.Py_SetPythonHome] added = '3.2' + abi_only = true [function.Py_SetRecursionLimit] added = '3.2' [function.Py_VaBuildValue] diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 17b93ba47caac4f..7e82a6365d9808b 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -23,6 +23,10 @@ extern void PySys_AddWarnOption(const wchar_t *s); extern void PySys_AddXOption(const wchar_t *s); extern void Py_SetPath(const wchar_t *path); +// Functions removed from Python 3.16 API but still exported for the stable +// ABI. +extern void Py_SetPythonHome(const wchar_t *); + // These functions were removed from Python 3.15 API but are still exported // for the stable ABI. We want to test them in this program. extern void PySys_ResetWarnOptions(void); diff --git a/Python/pathconfig.c b/Python/pathconfig.c index d034562c43f23c3..b4ba1c52066879b 100644 --- a/Python/pathconfig.c +++ b/Python/pathconfig.c @@ -236,7 +236,8 @@ Py_SetPath(const wchar_t *path) } -void +// Function removed from Python 3.16 limited C API, but kept in the stable ABI +PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *home) { int has_value = home && home[0]; @@ -254,7 +255,8 @@ Py_SetPythonHome(const wchar_t *home) } -void +// Function removed from Python 3.16 limited C API, but kept in the stable ABI +PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *program_name) { int has_value = program_name && program_name[0]; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index b3ec8461485de12..718ae51944faf22 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -4490,7 +4490,8 @@ make_sys_argv(int argc, wchar_t * const * argv) return list; } -void +// Function removed from Python 3.16 limited C API, but kept in the stable ABI +PyAPI_FUNC(void) PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) { wchar_t* empty_argv[1] = {L""}; @@ -4537,7 +4538,8 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) } } -void +// Function removed from Python 3.16 limited C API, but kept in the stable ABI +PyAPI_FUNC(void) PySys_SetArgv(int argc, wchar_t **argv) { int isolated = 0; @@ -4547,10 +4549,7 @@ PySys_SetArgv(int argc, wchar_t **argv) isolated = config->isolated; } -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS PySys_SetArgvEx(argc, argv, isolated == 0); -_Py_COMP_DIAG_POP } /* Reimplementation of PyFile_WriteString() no calling indirectly