https://github.com/python/cpython/commit/abf7a184bd94da4d1a6b54503a27ede1957b48b7 commit: abf7a184bd94da4d1a6b54503a27ede1957b48b7 branch: main author: Serhiy Storchaka <[email protected]> committer: serhiy-storchaka <[email protected]> date: 2026-08-29T22:41:39+03:00 summary:
gh-69370: Fix "python -m inspect --details" for unencodable paths (GH-155246) It failed with UnicodeEncodeError if the path of the module contains characters unencodable in the encoding of sys.stdout, e.g. undecodable bytes of a file name. Such characters are now escaped with backslashes, unless stdout uses an error handler which can handle them. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> files: A Misc/NEWS.d/next/Library/2026-08-05-17-30-00.gh-issue-69370.inspCLI.rst M Lib/inspect.py M Lib/test/test_inspect/test_inspect.py diff --git a/Lib/inspect.py b/Lib/inspect.py index 3f8991c79652d3f..c52469e63861a22 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -3464,6 +3464,10 @@ def _main(): import argparse import importlib + # The printed text can contain characters unencodable in the encoding + # of stdout, e.g. undecodable bytes of a file name. + sys.stdout.reconfigure(errors='backslashreplace') + parser = argparse.ArgumentParser() parser.add_argument( 'object', diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index c68c643cb97fb45..8930f6343ac299d 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -40,7 +40,7 @@ from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ from test.support import run_no_yield_async_fn, EqualToForwardRef from test.support.import_helper import DirsOnSysPath, ready_to_import -from test.support.os_helper import TESTFN, temp_cwd +from test.support.os_helper import TESTFN, TESTFN_UNDECODABLE, temp_cwd from test.support.script_helper import assert_python_ok, assert_python_failure, kill_python from test.support import has_subprocess_support from test import support @@ -6619,6 +6619,25 @@ def test_error_data(self): lines = err.decode().splitlines() self.assertEqual(lines, [self.NO_SOURCE_TARGET_ERROR]) + @unittest.skipUnless(TESTFN_UNDECODABLE, + 'requires undecodable file names') + def test_details_undecodable_path(self): + # gh-69370: the path of the module is not encodable in the encoding + # of stdout. + with temp_cwd() as test_dir: + subdir = os.path.join(os.fsencode(test_dir), TESTFN_UNDECODABLE) + try: + os.mkdir(subdir) + except OSError: + self.skipTest('undecodable paths are not supported') + with open(os.path.join(subdir, b'undecodable_mod.py'), 'w') as f: + f.write('"""Module docstring."""\n') + rc, out, err = assert_python_ok('-X', 'utf8=0', '-m', 'inspect', + '--details', 'undecodable_mod', + PYTHONPATH=os.fsdecode(subdir)) + self.assertIn(b'Target: undecodable_mod', out) + self.assertEqual(err, b'') + def test_details_option_with_package(self): module_name = 'unittest' module = importlib.import_module(module_name) diff --git a/Misc/NEWS.d/next/Library/2026-08-05-17-30-00.gh-issue-69370.inspCLI.rst b/Misc/NEWS.d/next/Library/2026-08-05-17-30-00.gh-issue-69370.inspCLI.rst new file mode 100644 index 000000000000000..27c97f9bdf07b48 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-08-05-17-30-00.gh-issue-69370.inspCLI.rst @@ -0,0 +1,4 @@ +:program:`python -m inspect --details` no longer fails with +:exc:`UnicodeEncodeError` if the path of the module contains characters +unencodable in the encoding of :data:`sys.stdout`. Such characters are now +escaped with backslashes. _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
