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]

Reply via email to