From be9c7cb4b50f8007b61018538c10d0a92c44cf17 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 1 May 2026 16:51:06 -0700 Subject: [PATCH 1/5] GH-149252: Update WASI SDK version from 32 to 33 (#149253) Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- .../next/Build/2026-05-01-20-01-32.gh-issue-149252.4W_0-w.rst | 1 + Platforms/WASI/config.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Build/2026-05-01-20-01-32.gh-issue-149252.4W_0-w.rst diff --git a/Misc/NEWS.d/next/Build/2026-05-01-20-01-32.gh-issue-149252.4W_0-w.rst b/Misc/NEWS.d/next/Build/2026-05-01-20-01-32.gh-issue-149252.4W_0-w.rst new file mode 100644 index 00000000000000..646a8e33732016 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-05-01-20-01-32.gh-issue-149252.4W_0-w.rst @@ -0,0 +1 @@ +Update to WASI SDK 33. diff --git a/Platforms/WASI/config.toml b/Platforms/WASI/config.toml index 31ec2b8023dab1..6a6d5713ee9673 100644 --- a/Platforms/WASI/config.toml +++ b/Platforms/WASI/config.toml @@ -2,5 +2,5 @@ # This allows for blanket copying of the WASI build code between supported # Python versions. [targets] -wasi-sdk = 32 +wasi-sdk = 33 host-triple = "wasm32-wasip1" From ff35fe4633cc6d3a30f6af8281dfa641783c1d07 Mon Sep 17 00:00:00 2001 From: "W. H. Wang" Date: Sat, 2 May 2026 10:27:23 +0800 Subject: [PATCH 2/5] gh-149117: Set `ImportError.name` on errors from `runpy.run_module`/`run_path` (gh-149159) Set ImportError.name on errors from runpy.run_module/run_path `runpy.run_module()` and `runpy.run_path()` now set the `name` attribute of the `ImportError` they raise to the requested module name, matching the behaviour of a regular import statement (previously `name` was always `None`, which broke introspection). The `name=` kwarg is gated on `issubclass(error, ImportError)` because `_get_module_details()` is also used by `_run_module_as_main()` with a private `_Error` sentinel class. `_Error` does not subclass ImportError, and `BaseException.__init__` rejects unknown kwargs at the C level, so passing `name=` unconditionally would break the `python -m foo` codepath. --- Lib/runpy.py | 25 ++++++++++------ Lib/test/test_runpy.py | 30 +++++++++++++++++++ ...-04-29-16-11-27.gh-issue-149117.yEeTYd.rst | 3 ++ 3 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-04-29-16-11-27.gh-issue-149117.yEeTYd.rst diff --git a/Lib/runpy.py b/Lib/runpy.py index 9f62d20e9a2322..a535b4f651a5ae 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -102,8 +102,10 @@ def _run_module_code(code, init_globals=None, # Helper to get the full name, spec and code for a module def _get_module_details(mod_name, error=ImportError): + # name= is only accepted by ImportError and its subclasses. + kwargs = {"name": mod_name} if issubclass(error, ImportError) else {} if mod_name.startswith("."): - raise error("Relative module names not supported") + raise error("Relative module names not supported", **kwargs) pkg_name, _, _ = mod_name.rpartition(".") if pkg_name: # Try importing the parent to avoid catching initialization errors @@ -136,12 +138,13 @@ def _get_module_details(mod_name, error=ImportError): if mod_name.endswith(".py"): msg += (f". Try using '{mod_name[:-3]}' instead of " f"'{mod_name}' as the module name.") - raise error(msg.format(mod_name, type(ex).__name__, ex)) from ex + raise error(msg.format(mod_name, type(ex).__name__, ex), + **kwargs) from ex if spec is None: - raise error("No module named %s" % mod_name) + raise error("No module named %s" % mod_name, **kwargs) if spec.submodule_search_locations is not None: if mod_name == "__main__" or mod_name.endswith(".__main__"): - raise error("Cannot use package as __main__ module") + raise error("Cannot use package as __main__ module", **kwargs) try: pkg_main_name = mod_name + ".__main__" return _get_module_details(pkg_main_name, error) @@ -149,17 +152,19 @@ def _get_module_details(mod_name, error=ImportError): if mod_name not in sys.modules: raise # No module loaded; being a package is irrelevant raise error(("%s; %r is a package and cannot " + - "be directly executed") %(e, mod_name)) + "be directly executed") %(e, mod_name), + **kwargs) loader = spec.loader if loader is None: raise error("%r is a namespace package and cannot be executed" - % mod_name) + % mod_name, + **kwargs) try: code = loader.get_code(mod_name) except ImportError as e: - raise error(format(e)) from e + raise error(format(e), **kwargs) from e if code is None: - raise error("No code object available for %s" % mod_name) + raise error("No code object available for %s" % mod_name, **kwargs) return mod_name, spec, code class _Error(Exception): @@ -232,6 +237,7 @@ def _get_main_module_details(error=ImportError): # Also moves the standard __main__ out of the way so that the # preexisting __loader__ entry doesn't cause issues main_name = "__main__" + kwargs = {"name": main_name} if issubclass(error, ImportError) else {} saved_main = sys.modules[main_name] del sys.modules[main_name] try: @@ -239,7 +245,8 @@ def _get_main_module_details(error=ImportError): except ImportError as exc: if main_name in str(exc): raise error("can't find %r module in %r" % - (main_name, sys.path[0])) from exc + (main_name, sys.path[0]), + **kwargs) from exc raise finally: sys.modules[main_name] = saved_main diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 9f3bc8973eb8ac..55b9673ef6c91c 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -217,6 +217,25 @@ def test_invalid_names(self): # Package without __main__.py self.expect_import_error("multiprocessing") + def test_invalid_names_set_name_attribute(self): + cases = [ + # (mod_name, expected_name) -- comment indicates raise site + ("nonexistent_runpy_test_module", + "nonexistent_runpy_test_module"), # spec is None + ("sys.imp.eric", "sys.imp.eric"), # find_spec error + (".relative_name", ".relative_name"), # relative name rejected + ("sys", "sys"), # builtin: no code object + ("multiprocessing", "multiprocessing"), # package without __main__ + ] + for mod_name, expected_name in cases: + with self.subTest(mod_name=mod_name): + try: + run_module(mod_name) + except ImportError as exc: + self.assertEqual(exc.name, expected_name) + else: + self.fail("Expected ImportError for %r" % mod_name) + def test_library_module(self): self.assertEqual(run_module("runpy")["__name__"], "runpy") @@ -714,6 +733,17 @@ def test_directory_error(self): msg = "can't find '__main__' module in %r" % script_dir self._check_import_error(script_dir, msg) + def test_directory_error_sets_name_attribute(self): + with temp_dir() as script_dir: + self._make_test_script(script_dir, 'not_main') + try: + run_path(script_dir) + except ImportError as exc: + self.assertEqual(exc.name, '__main__') + else: + self.fail("Expected ImportError for directory without " + "__main__.py") + def test_zipfile(self): with temp_dir() as script_dir: mod_name = '__main__' diff --git a/Misc/NEWS.d/next/Library/2026-04-29-16-11-27.gh-issue-149117.yEeTYd.rst b/Misc/NEWS.d/next/Library/2026-04-29-16-11-27.gh-issue-149117.yEeTYd.rst new file mode 100644 index 00000000000000..41223e90ed0b0e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-04-29-16-11-27.gh-issue-149117.yEeTYd.rst @@ -0,0 +1,3 @@ +Fix :func:`runpy.run_module` and :func:`runpy.run_path` to set the +:attr:`~ImportError.name` attribute on the :exc:`ImportError` they +raise. From 0e2c055892629c36e77e20d396376676890da7f6 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Fri, 1 May 2026 23:52:43 -0400 Subject: [PATCH 3/5] gh-149254: Update macOS installer to use OpenSSL 3.5.6. (#149262) --- Mac/BuildScript/build-installer.py | 6 +++--- .../macOS/2026-05-01-20-12-33.gh-issue-149254.kXdWpS.rst | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/macOS/2026-05-01-20-12-33.gh-issue-149254.kXdWpS.rst diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index cd5f4c71b005ed..c5f92a99a1e076 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -246,9 +246,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 3.5.5", - url="https://github.com/openssl/openssl/releases/download/openssl-3.5.5/openssl-3.5.5.tar.gz", - checksum="b28c91532a8b65a1f983b4c28b7488174e4a01008e29ce8e69bd789f28bc2a89", + name="OpenSSL 3.5.6", + url="https://github.com/openssl/openssl/releases/download/openssl-3.5.6/openssl-3.5.6.tar.gz", + checksum="deae7c80cba99c4b4f940ecadb3c3338b13cb77418409238e57d7f31f2a3b736", buildrecipe=build_universal_openssl, configure=None, install=None, diff --git a/Misc/NEWS.d/next/macOS/2026-05-01-20-12-33.gh-issue-149254.kXdWpS.rst b/Misc/NEWS.d/next/macOS/2026-05-01-20-12-33.gh-issue-149254.kXdWpS.rst new file mode 100644 index 00000000000000..278327c91f1baa --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2026-05-01-20-12-33.gh-issue-149254.kXdWpS.rst @@ -0,0 +1 @@ +Update macOS installer to use OpenSSL 3.5.6. From 0f5cd57f80a704e67b8566f8cf5686d300db28c3 Mon Sep 17 00:00:00 2001 From: htjworld <116538001+htjworld@users.noreply.github.com> Date: Sat, 2 May 2026 12:54:24 +0900 Subject: [PATCH 4/5] statistics: Fix geometric_mean() error message for negative inputs (#149246) --- Lib/statistics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/statistics.py b/Lib/statistics.py index 32fcf2313a815a..01ca6c51dafcaf 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -248,7 +248,7 @@ def count_positive(iterable): elif x == 0.0: found_zero = True else: - raise StatisticsError('No negative inputs allowed', x) + raise StatisticsError(f'No negative inputs allowed: {x!r}') total = fsum(map(log, count_positive(data))) From bb5e41efdbe227c7ad9b32a259f79404bab42d5c Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 1 May 2026 22:58:23 -0500 Subject: [PATCH 5/5] gh-149244 Document statistics functions that require sequence inputs. (gh-149264) --- Doc/library/statistics.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index cbb131855dc664..dba0e26787d951 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -713,7 +713,7 @@ However, for reading convenience, most of the examples show sorted sequences. .. function:: covariance(x, y, /) - Return the sample covariance of two inputs *x* and *y*. Covariance + Return the sample covariance of two sequence inputs *x* and *y*. Covariance is a measure of the joint variability of two inputs. Both inputs must be of the same length (no less than two), otherwise @@ -739,7 +739,7 @@ However, for reading convenience, most of the examples show sorted sequences. Return the `Pearson's correlation coefficient `_ - for two inputs. Pearson's correlation coefficient *r* takes values + for two sequence inputs. Pearson's correlation coefficient *r* takes values between -1 and +1. It measures the strength and direction of a linear relationship. @@ -802,7 +802,7 @@ However, for reading convenience, most of the examples show sorted sequences. (it is equal to the difference between predicted and actual values of the dependent variable). - Both inputs must be of the same length (no less than two), and + Both inputs must be sequences of the same length (no less than two), and the independent variable *x* cannot be constant; otherwise a :exc:`StatisticsError` is raised.