Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
gh-69370: Fix "python -m inspect --details" for unencodable paths
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) <noreply@anthropic.com>
  • Loading branch information
serhiy-storchaka and claude committed Aug 5, 2026
commit 0588ae67d4313709d1b1699db2fcdaae6014a23f
5 changes: 5 additions & 0 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -3461,6 +3461,11 @@ 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.
if getattr(sys.stdout, 'errors', None) == 'strict':
sys.stdout.reconfigure(errors='backslashreplace')

parser = argparse.ArgumentParser()
parser.add_argument(
'object',
Expand Down
18 changes: 17 additions & 1 deletion Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -6584,6 +6584,22 @@ 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)
os.mkdir(subdir)
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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
``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.
Loading