Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbe8ae08

Browse files
committed
Merge branch 'main' ofhttps://github.com/python/cpython
2 parentsd70e5c1 +7303f06 commitbe8ae08

File tree

12 files changed

+175
-68
lines changed

12 files changed

+175
-68
lines changed

‎Include/internal/pycore_pyerrors.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ PyAPI_FUNC(void) _PyErr_SetString(
130130
PyObject*exception,
131131
constchar*string);
132132

133+
/*
134+
* Set an exception with the error message decoded from the current locale
135+
* encoding (LC_CTYPE).
136+
*
137+
* Exceptions occurring in decoding take priority over the desired exception.
138+
*
139+
* Exported for '_ctypes' shared extensions.
140+
*/
141+
PyAPI_FUNC(void)_PyErr_SetLocaleString(
142+
PyObject*exception,
143+
constchar*string);
144+
133145
PyAPI_FUNC(PyObject*)_PyErr_Format(
134146
PyThreadState*tstate,
135147
PyObject*exception,

‎Lib/test/test_ctypes/test_dlerror.py

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
import_ctypes
12
importos
3+
importplatform
24
importsys
5+
importtest.support
36
importunittest
4-
importplatform
7+
fromctypesimportCDLL,c_int
8+
fromctypes.utilimportfind_library
9+
510

611
FOO_C=r"""
712
#include <unistd.h>
@@ -26,7 +31,7 @@
2631

2732

2833
@unittest.skipUnless(sys.platform.startswith('linux'),
29-
'Test only valid for Linux')
34+
'test requires GNU IFUNC support')
3035
classTestNullDlsym(unittest.TestCase):
3136
"""GH-126554: Ensure that we catch NULL dlsym return values
3237
@@ -53,14 +58,6 @@ def test_null_dlsym(self):
5358
importsubprocess
5459
importtempfile
5560

56-
# To avoid ImportErrors on Windows, where _ctypes does not have
57-
# dlopen and dlsym,
58-
# import here, i.e., inside the test function.
59-
# The skipUnless('linux') decorator ensures that we're on linux
60-
# if we're executing these statements.
61-
fromctypesimportCDLL,c_int
62-
from_ctypesimportdlopen,dlsym
63-
6461
retcode=subprocess.call(["gcc","--version"],
6562
stdout=subprocess.DEVNULL,
6663
stderr=subprocess.DEVNULL)
@@ -111,6 +108,8 @@ def test_null_dlsym(self):
111108
self.assertEqual(os.read(pipe_r,2),b'OK')
112109

113110
# Case #3: Test 'py_dl_sym' from Modules/_ctypes/callproc.c
111+
dlopen=test.support.get_attribute(_ctypes,'dlopen')
112+
dlsym=test.support.get_attribute(_ctypes,'dlsym')
114113
L=dlopen(dstname)
115114
withself.assertRaisesRegex(OSError,"symbol 'foo' not found"):
116115
dlsym(L,"foo")
@@ -119,5 +118,66 @@ def test_null_dlsym(self):
119118
self.assertEqual(os.read(pipe_r,2),b'OK')
120119

121120

121+
@unittest.skipUnless(os.name!='nt','test requires dlerror() calls')
122+
classTestLocalization(unittest.TestCase):
123+
124+
@staticmethod
125+
defconfigure_locales(func):
126+
returntest.support.run_with_locale(
127+
'LC_ALL',
128+
'fr_FR.iso88591','ja_JP.sjis','zh_CN.gbk',
129+
'fr_FR.utf8','en_US.utf8',
130+
'',
131+
)(func)
132+
133+
@classmethod
134+
defsetUpClass(cls):
135+
cls.libc_filename=find_library("c")
136+
137+
@configure_locales
138+
deftest_localized_error_from_dll(self):
139+
dll=CDLL(self.libc_filename)
140+
withself.assertRaises(AttributeError)ascm:
141+
dll.this_name_does_not_exist
142+
ifsys.platform.startswith('linux'):
143+
# On macOS, the filename is not reported by dlerror().
144+
self.assertIn(self.libc_filename,str(cm.exception))
145+
146+
@configure_locales
147+
deftest_localized_error_in_dll(self):
148+
dll=CDLL(self.libc_filename)
149+
withself.assertRaises(ValueError)ascm:
150+
c_int.in_dll(dll,'this_name_does_not_exist')
151+
ifsys.platform.startswith('linux'):
152+
# On macOS, the filename is not reported by dlerror().
153+
self.assertIn(self.libc_filename,str(cm.exception))
154+
155+
@unittest.skipUnless(hasattr(_ctypes,'dlopen'),
156+
'test requires _ctypes.dlopen()')
157+
@configure_locales
158+
deftest_localized_error_dlopen(self):
159+
missing_filename=b'missing\xff.so'
160+
# Depending whether the locale, we may encode '\xff' differently
161+
# but we are only interested in avoiding a UnicodeDecodeError
162+
# when reporting the dlerror() error message which contains
163+
# the localized filename.
164+
filename_pattern=r'missing.*?\.so'
165+
withself.assertRaisesRegex(OSError,filename_pattern):
166+
_ctypes.dlopen(missing_filename,2)
167+
168+
@unittest.skipUnless(hasattr(_ctypes,'dlopen'),
169+
'test requires _ctypes.dlopen()')
170+
@unittest.skipUnless(hasattr(_ctypes,'dlsym'),
171+
'test requires _ctypes.dlsym()')
172+
@configure_locales
173+
deftest_localized_error_dlsym(self):
174+
dll=_ctypes.dlopen(self.libc_filename)
175+
withself.assertRaises(OSError)ascm:
176+
_ctypes.dlsym(dll,'this_name_does_not_exist')
177+
ifsys.platform.startswith('linux'):
178+
# On macOS, the filename is not reported by dlerror().
179+
self.assertIn(self.libc_filename,str(cm.exception))
180+
181+
122182
if__name__=="__main__":
123183
unittest.main()

‎Lib/test/test_dbm_gnu.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
fromtestimportsupport
2-
fromtest.supportimportimport_helper,cpython_only
3-
gdbm=import_helper.import_module("dbm.gnu")#skip if not supported
4-
importunittest
51
importos
6-
fromtest.support.os_helperimportTESTFN,TESTFN_NONASCII,unlink,FakePath
2+
importunittest
3+
fromtestimportsupport
4+
fromtest.supportimportcpython_only,import_helper
5+
fromtest.support.os_helperimport (TESTFN,TESTFN_NONASCII,FakePath,
6+
create_empty_file,temp_dir,unlink)
77

8+
gdbm=import_helper.import_module("dbm.gnu")# skip if not supported
89

910
filename=TESTFN
1011

@@ -205,6 +206,16 @@ def test_clear(self):
205206
self.assertNotIn(k,db)
206207
self.assertEqual(len(db),0)
207208

209+
@support.run_with_locale(
210+
'LC_ALL',
211+
'fr_FR.iso88591','ja_JP.sjis','zh_CN.gbk',
212+
'fr_FR.utf8','en_US.utf8',
213+
'',
214+
)
215+
deftest_localized_error(self):
216+
withtemp_dir()asd:
217+
create_empty_file(os.path.join(d,'test'))
218+
self.assertRaises(gdbm.error,gdbm.open,filename,'r')
208219

209220

210221
if__name__=='__main__':

‎Modules/_ctypes/_ctypes.c

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -984,15 +984,8 @@ CDataType_in_dll_impl(PyObject *type, PyTypeObject *cls, PyObject *dll,
984984
#ifdefUSE_DLERROR
985985
constchar*dlerr=dlerror();
986986
if (dlerr) {
987-
PyObject*message=PyUnicode_DecodeLocale(dlerr,"surrogateescape");
988-
if (message) {
989-
PyErr_SetObject(PyExc_ValueError,message);
990-
Py_DECREF(message);
991-
returnNULL;
992-
}
993-
// Ignore errors from PyUnicode_DecodeLocale,
994-
// fall back to the generic error below.
995-
PyErr_Clear();
987+
_PyErr_SetLocaleString(PyExc_ValueError,dlerr);
988+
returnNULL;
996989
}
997990
#endif
998991
#undef USE_DLERROR
@@ -3825,21 +3818,14 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
38253818
address= (PPROC)dlsym(handle,name);
38263819

38273820
if (!address) {
3828-
#ifdefUSE_DLERROR
3821+
#ifdefUSE_DLERROR
38293822
constchar*dlerr=dlerror();
38303823
if (dlerr) {
3831-
PyObject*message=PyUnicode_DecodeLocale(dlerr,"surrogateescape");
3832-
if (message) {
3833-
PyErr_SetObject(PyExc_AttributeError,message);
3834-
Py_DECREF(ftuple);
3835-
Py_DECREF(message);
3836-
returnNULL;
3837-
}
3838-
// Ignore errors from PyUnicode_DecodeLocale,
3839-
// fall back to the generic error below.
3840-
PyErr_Clear();
3824+
_PyErr_SetLocaleString(PyExc_AttributeError,dlerr);
3825+
Py_DECREF(ftuple);
3826+
returnNULL;
38413827
}
3842-
#endif
3828+
#endif
38433829
PyErr_Format(PyExc_AttributeError,"function '%s' not found",name);
38443830
Py_DECREF(ftuple);
38453831
returnNULL;

‎Modules/_ctypes/callproc.c

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,10 +1588,11 @@ static PyObject *py_dl_open(PyObject *self, PyObject *args)
15881588
Py_XDECREF(name2);
15891589
if (!handle) {
15901590
constchar*errmsg=dlerror();
1591-
if (!errmsg)
1592-
errmsg="dlopen() error";
1593-
PyErr_SetString(PyExc_OSError,
1594-
errmsg);
1591+
if (errmsg) {
1592+
_PyErr_SetLocaleString(PyExc_OSError,errmsg);
1593+
returnNULL;
1594+
}
1595+
PyErr_SetString(PyExc_OSError,"dlopen() error");
15951596
returnNULL;
15961597
}
15971598
returnPyLong_FromVoidPtr(handle);
@@ -1604,8 +1605,12 @@ static PyObject *py_dl_close(PyObject *self, PyObject *args)
16041605
if (!PyArg_ParseTuple(args,"O&:dlclose",&_parse_voidp,&handle))
16051606
returnNULL;
16061607
if (dlclose(handle)) {
1607-
PyErr_SetString(PyExc_OSError,
1608-
dlerror());
1608+
constchar*errmsg=dlerror();
1609+
if (errmsg) {
1610+
_PyErr_SetLocaleString(PyExc_OSError,errmsg);
1611+
returnNULL;
1612+
}
1613+
PyErr_SetString(PyExc_OSError,"dlclose() error");
16091614
returnNULL;
16101615
}
16111616
Py_RETURN_NONE;
@@ -1639,21 +1644,14 @@ static PyObject *py_dl_sym(PyObject *self, PyObject *args)
16391644
if (ptr) {
16401645
returnPyLong_FromVoidPtr(ptr);
16411646
}
1642-
#ifdefUSE_DLERROR
1643-
constchar*dlerr=dlerror();
1644-
if (dlerr) {
1645-
PyObject*message=PyUnicode_DecodeLocale(dlerr,"surrogateescape");
1646-
if (message) {
1647-
PyErr_SetObject(PyExc_OSError,message);
1648-
Py_DECREF(message);
1649-
returnNULL;
1650-
}
1651-
// Ignore errors from PyUnicode_DecodeLocale,
1652-
// fall back to the generic error below.
1653-
PyErr_Clear();
1647+
#ifdefUSE_DLERROR
1648+
constchar*errmsg=dlerror();
1649+
if (errmsg) {
1650+
_PyErr_SetLocaleString(PyExc_OSError,errmsg);
1651+
returnNULL;
16541652
}
1655-
#endif
1656-
#undef USE_DLERROR
1653+
#endif
1654+
#undef USE_DLERROR
16571655
PyErr_Format(PyExc_OSError,"symbol '%s' not found",name);
16581656
returnNULL;
16591657
}

‎Modules/_gdbmmodule.c

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
#endif
99

1010
#include"Python.h"
11+
#include"pycore_pyerrors.h"// _PyErr_SetLocaleString()
1112
#include"gdbm.h"
1213

1314
#include<fcntl.h>
14-
#include<stdlib.h>// free()
15+
#include<stdlib.h>// free()
1516
#include<sys/stat.h>
1617
#include<sys/types.h>
1718

@@ -33,6 +34,24 @@ get_gdbm_state(PyObject *module)
3334
return (_gdbm_state*)state;
3435
}
3536

37+
/*
38+
* Set the gdbm error obtained by gdbm_strerror(gdbm_errno).
39+
*
40+
* If no error message exists, a generic (UTF-8) error message
41+
* is used instead.
42+
*/
43+
staticvoid
44+
set_gdbm_error(_gdbm_state*state,constchar*generic_error)
45+
{
46+
constchar*gdbm_errmsg=gdbm_strerror(gdbm_errno);
47+
if (gdbm_errmsg) {
48+
_PyErr_SetLocaleString(state->gdbm_error,gdbm_errmsg);
49+
}
50+
else {
51+
PyErr_SetString(state->gdbm_error,generic_error);
52+
}
53+
}
54+
3655
/*[clinic input]
3756
module _gdbm
3857
class _gdbm.gdbm "gdbmobject *" "&Gdbmtype"
@@ -91,7 +110,7 @@ newgdbmobject(_gdbm_state *state, const char *file, int flags, int mode)
91110
PyErr_SetFromErrnoWithFilename(state->gdbm_error,file);
92111
}
93112
else {
94-
PyErr_SetString(state->gdbm_error,gdbm_strerror(gdbm_errno));
113+
set_gdbm_error(state,"gdbm_open() error");
95114
}
96115
Py_DECREF(dp);
97116
returnNULL;
@@ -136,7 +155,7 @@ gdbm_length(gdbmobject *dp)
136155
PyErr_SetFromErrno(state->gdbm_error);
137156
}
138157
else {
139-
PyErr_SetString(state->gdbm_error,gdbm_strerror(gdbm_errno));
158+
set_gdbm_error(state,"gdbm_count() error");
140159
}
141160
return-1;
142161
}
@@ -286,7 +305,7 @@ gdbm_ass_sub(gdbmobject *dp, PyObject *v, PyObject *w)
286305
PyErr_SetObject(PyExc_KeyError,v);
287306
}
288307
else {
289-
PyErr_SetString(state->gdbm_error,gdbm_strerror(gdbm_errno));
308+
set_gdbm_error(state,"gdbm_delete() error");
290309
}
291310
return-1;
292311
}
@@ -297,11 +316,12 @@ gdbm_ass_sub(gdbmobject *dp, PyObject *v, PyObject *w)
297316
}
298317
errno=0;
299318
if (gdbm_store(dp->di_dbm,krec,drec,GDBM_REPLACE)<0) {
300-
if (errno!=0)
319+
if (errno!=0) {
301320
PyErr_SetFromErrno(state->gdbm_error);
302-
else
303-
PyErr_SetString(state->gdbm_error,
304-
gdbm_strerror(gdbm_errno));
321+
}
322+
else {
323+
set_gdbm_error(state,"gdbm_store() error");
324+
}
305325
return-1;
306326
}
307327
}
@@ -534,10 +554,12 @@ _gdbm_gdbm_reorganize_impl(gdbmobject *self, PyTypeObject *cls)
534554
check_gdbmobject_open(self,state->gdbm_error);
535555
errno=0;
536556
if (gdbm_reorganize(self->di_dbm)<0) {
537-
if (errno!=0)
557+
if (errno!=0) {
538558
PyErr_SetFromErrno(state->gdbm_error);
539-
else
540-
PyErr_SetString(state->gdbm_error,gdbm_strerror(gdbm_errno));
559+
}
560+
else {
561+
set_gdbm_error(state,"gdbm_reorganize() error");
562+
}
541563
returnNULL;
542564
}
543565
Py_RETURN_NONE;

‎Modules/_hashopenssl.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ _setException(PyObject *exc, const char* altmsg, ...)
319319
va_end(vargs);
320320
ERR_clear_error();
321321

322+
/* ERR_ERROR_STRING(3) ensures that the messages below are ASCII */
322323
lib=ERR_lib_error_string(errcode);
323324
func=ERR_func_error_string(errcode);
324325
reason=ERR_reason_error_string(errcode);

‎Modules/_sqlite/util.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ _pysqlite_seterror(pysqlite_state *state, sqlite3 *db)
134134

135135
/* Create and set the exception. */
136136
intextended_errcode=sqlite3_extended_errcode(db);
137+
// sqlite3_errmsg() always returns an UTF-8 encoded message
137138
constchar*errmsg=sqlite3_errmsg(db);
138139
raise_exception(exc_class,extended_errcode,errmsg);
139140
returnextended_errcode;

‎Modules/_testcapi/exceptions.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include"parts.h"
55
#include"util.h"
6+
67
#include"clinic/exceptions.c.h"
78

89

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp