8000 gh-126742: allow to use non-UTF8 exception messages by picnixz · Pull Request #126746 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-126742: allow to use non-UTF8 exception messages #126746

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 47 commits into from
Dec 17, 2024
Merged
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
24eb521
allow to use translated exception messages
picnixz Nov 12, 2024
4c0f85b
Use 'surrogateescape' handler instead of 'strict' handler.
picnixz Nov 12, 2024
f432dc9
fix typos
picnixz Nov 20, 2024
434cf5b
Merge branch 'main' into feat/capi/set-locale-exception-126742
picnixz Nov 20, 2024
48238fc
Allow to set localized error string.
picnixz Nov 20, 2024
a38105b
Use `PyErr_SetLocaleString` when possible
picnixz Nov 20, 2024
714dcb7
Indicate which external functions may return non-UTF8 error strings.
picnixz Nov 20, 2024
ee1f3c6
Merge branch 'main' into feat/capi/set-locale-exception-126742
picnixz Nov 29, 2024
3d71f6b
fix build
picnixz Nov 29, 2024
1a23bf5
update dll
picnixz Nov 29, 2024
16a98a2
add docs & news
picnixz Nov 29, 2024
5a150d2
update comment
picnixz Nov 29, 2024
074bd4c
update TODO
picnixz Nov 29, 2024
7f3a909
update comment
picnixz Nov 29, 2024
1a321f9
Revert "add docs & news"
picnixz Dec 2, 2024
f5813a9
keep one internal helper instead of a public/private API pair
picnixz Dec 2, 2024
84afad2
rename references to `PyErr_SetLocaleString`
picnixz Dec 2, 2024
166a736
Simplify logic
picnixz Dec 2, 2024
7c9a793
Merge branch 'main' into fix/locale-set-object-exception-126742
picnixz Dec 2, 2024
314c9f1
Remove entry from refcounts.dat.
picnixz Dec 2, 2024
571de05
update comment
picnixz Dec 2, 2024
2633d18
Update Include/internal/pycore_pyerrors.h
picnixz Dec 2, 2024
45442c3
fix grammar
picnixz Dec 2, 2024
6bedc4b
Merge branch 'main' into fix/locale-set-object-exception-126742
picnixz Dec 3, 2024
6f9ee0b
Unconditionally re-raise decoding errors
picnixz Dec 8, 2024
b02a715
add tests for `_PyErr_SetLocaleString`
picnixz Dec 9, 2024
47d50b8
add tests for `dlerror` and `gdbm_*` functions
picnixz Dec 9, 2024
574184c
fix tests
picnixz Dec 12, 2024
4fecd76
remove C API internal tests
picnixz Dec 12, 2024
26f074c
cosmetic changes on imports
picnixz Dec 12, 2024
cb4d5e4
fix tests
picnixz Dec 13, 2024
6798f21
fix `dbm` tests
picnixz Dec 14, 2024
ce8ae02
improve test coverage
picnixz Dec 14, 2024
8d442a3
fix macOS tests
picnixz Dec 14, 2024
f06d6a5
update names
picnixz Dec 14, 2024
1c05250
fix tests
picnixz Dec 14, 2024
3d69de1
fix tests (again???)
picnixz Dec 14, 2024
a079511
fix tests (macOS)
picnixz Dec 14, 2024
8618de8
fix tests (windows)
picnixz Dec 14, 2024
9bc4012
fix macOS tests
picnixz Dec 14, 2024
1ea0f73
fix windows tests
picnixz Dec 14, 2024
09d60f4
revert a missing line
picnixz Dec 15, 2024
a5722b1
revert changes
picnixz Dec 15, 2024
5fc2e17
use libc.so instead
picnixz Dec 16, 2024
62db957
address Victor's review
picnixz Dec 16, 2024
c665a2d
Fix tests (hopefully it will still work)
picnixz Dec 16, 2024
765e16c
Reverting last commit to use `run_with_locale` only
picnixz Dec 16, 2024
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
Prev Previous commit
Next Next commit
improve test coverage
  • Loading branch information
picnixz committed Dec 14, 2024
commit ce8ae02f588051d1d8043dc463f6839867a4fec4
121 changes: 80 additions & 41 deletions Lib/test/test_ctypes/test_dlerror.py
10000
Original file line number< 8000 /th> Diff line number Diff line change
@@ -1,9 +1,12 @@
import _ctypes

import os
import platform
import re
import sys
import subprocess
import tempfile
import test.support
import unittest
from ctypes import CDLL, c_int


FOO_C = r"""
Expand All @@ -28,8 +31,16 @@
"""


@unittest.skipUnless(sys.platform.startswith('linux'),
'Test only valid for Linux')
def has_gcc():
return subprocess.call(["gcc", "--version"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL) == 0


@unittest.skipUnless(hasattr(_ctypes, 'dlopen'),
'test requires _ctypes.dlopen()')
@unittest.skipUnless(hasattr(_ctypes, 'dlsym'),
'test requires _ctypes.dlsym()')
class TestNullDlsym(unittest.TestCase):
"""GH-126554: Ensure that we catch NULL dlsym return values

Expand All @@ -53,21 +64,7 @@ class TestNullDlsym(unittest.TestCase):
"""

def test_null_dlsym(self):
import subprocess
import tempfile

# To avoid ImportErrors on Windows, where _ctypes does not have
# dlopen and dlsym,
# import here, i.e., inside the test function.
# The skipUnless('linux') decorator ensures that we're on linux
# if we're executing these statements.
from ctypes import CDLL, c_int
from _ctypes import dlopen, dlsym

retcode = subprocess.call(["gcc", "--version"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
if retcode != 0:
if not has_gcc():
self.skipTest("gcc is missing")

pipe_r, pipe_w = os.pipe()
Expand Down Expand Up @@ -114,35 +111,77 @@ def test_null_dlsym(self):
self.assertEqual(os.read(pipe_r, 2), b'OK')

# Case #3: Test 'py_dl_sym' from Modules/_ctypes/callproc.c
L = dlopen(dstname)
L = _ctypes.dlopen(dstname)
with self.assertRaisesRegex(OSError, "symbol 'foo' not found"):
dlsym(L, "foo")

# Assert that the IFUNC was called
self.assertEqual(os.read(pipe_r, 2), b'OK')
_ctypes.dlsym(L, "foo")


@unittest.skipUnless(sys.platform.startswith('linux'),
'test requires _ctypes.dlopen()')
class TestLinuxLocalization(unittest.TestCase):

@test.support.run_with_locale(
'LC_ALL',
'fr_FR.iso88591', 'ja_JP.sjis', 'zh_CN.gbk',
'',
)
def test_localized_error(self):
# An ImportError would be propagated and would be unexpected on Linux.
from _ctypes import dlopen

@staticmethod
def configure_locales(func):
return test.support.run_with_locale(
'LC_ALL',
'fr_FR.iso88591', 'ja_JP.sjis', 'zh_CN.gbk',
'fr_FR.utf8', 'en_US.utf8',
'',
)(func)

@classmethod
def setUpClass(cls):
if not has_gcc():
raise unittest.SkipTest("gcc is missing")

def make_libfoo(self, outdir, source, so_libname):
srcname = os.path.join(outdir, 'source.c')
dstname = os.path.join(outdir, so_libname)
with open(srcname, 'w') as f:
f.write(source)
args = ['gcc', '-fPIC', '-shared', '-o', dstname, srcname]
p = subprocess.run(args, capture_output=True)
p.check_returncode()
return dstname

@configure_locales
def test_localized_error_from_dll(self):
with tempfile.TemporaryDirectory() as outdir:
dstname = self.make_libfoo(outdir, 'int x = 0;', 'test_in_dll.so')
dll = CDLL(dstname)
with self.assertRaisesRegex(AttributeError, r'test_in_dll\.so:.+'):
dll.foo

@configure_locales
def test_localized_error_in_dll(self):
with tempfile.TemporaryDirectory() as outdir:
dstname = self.make_libfoo(outdir, 'int x = 0;', 'test_in_dll.so')
dll = CDLL(dstname)
with self.assertRaisesRegex(ValueError, r'test_in_dll\.so:.+'):
c_int.in_dll(dll, 'foo')

@unittest.skipUnless(hasattr(_ctypes, 'dlopen'),
'test requires _ctypes.dlopen()')
@configure_locales
def test_localized_error_dlopen(self):
missing_filename = b'missing\xff.so'
# Depending whether the locale is ISO-88591 or not, we may either
# encode '\xff' as '\udcff' or 'ÿ', but we are only interested in
# avoiding a UnicodeDecodeError when reporting the dlerror() error
# message which contains the localized filename.
filename_pattern = r'missing[ÿ|\udcff].so:.+'
# Depending whether the locale, we may encode '\xff' differently
# but we are only interested in avoiding a UnicodeDecodeError
# when reporting the dlerror() error message which contains
# the localized filename.
filename_pattern = r'missing.*?\.so:.+'
with self.assertRaisesRegex(OSError, filename_pattern):
dlopen(missing_filename, 2)
_ctypes.dlopen(missing_filename, 2)

@unittest.skipUnless(hasattr(_ctypes, 'dlopen'),
'test requires _ctypes.dlopen()')
@unittest.skipUnless(hasattr(_ctypes, 'dlsym'),
'test requires _ctypes.dlsym()')
@configure_locales
def test_localized_error_dlsym(self):
with tempfile.TemporaryDirectory() as outdir:
dstname = self.make_libfoo(outdir, 'int x = 0;', 'test_dlsym.so')
dll = _ctypes.dlopen(dstname)
with self.assertRaisesRegex(OSError, r'test_dlsym\.so:.+'):
_ctypes.dlsym(dll, 'foo')


if __name__ == "__main__":
Expand Down
Loading
0