Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Doc/library/statistics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -739,7 +739,7 @@ However, for reading convenience, most of the examples show sorted sequences.

Return the `Pearson's correlation coefficient
<https://en.wikipedia.org/wiki/Pearson_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.

Expand Down Expand Up @@ -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.

Expand Down
25 changes: 16 additions & 9 deletions Lib/runpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -136,30 +138,33 @@ 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)
except error as e:
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):
Expand Down Expand Up @@ -232,14 +237,16 @@ 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:
return _get_module_details(main_name)
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
Expand Down
2 changes: 1 addition & 1 deletion Lib/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)))

Expand Down
30 changes: 30 additions & 0 deletions Lib/test/test_runpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down Expand Up @@ -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__'
Expand Down
6 changes: 3 additions & 3 deletions Mac/BuildScript/build-installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update to WASI SDK 33.
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update macOS installer to use OpenSSL 3.5.6.
2 changes: 1 addition & 1 deletion Platforms/WASI/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Loading