Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 819399b

Browse files
Issue #26671: Enhanced path_converter.
Exceptions raised during converting argument of correct type are no longer overridded with TypeError. Some error messages are now more detailed.
1 parent ec39756 commit 819399b

1 file changed

Lines changed: 50 additions & 56 deletions

File tree

Modules/posixmodule.c

Lines changed: 50 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -669,21 +669,20 @@ _Py_Dev_Converter(PyObject *obj, void *p)
669669
#endif
670670

671671
static int
672-
_fd_converter(PyObject *o, int *p, const char *allowed)
672+
_fd_converter(PyObject *o, int *p)
673673
{
674674
int overflow;
675675
long long_value;
676676

677677
PyObject *index = PyNumber_Index(o);
678678
if (index == NULL) {
679-
PyErr_Format(PyExc_TypeError,
680-
"argument should be %s, not %.200s",
681-
allowed, Py_TYPE(o)->tp_name);
682679
return 0;
683680
}
684681

682+
assert(PyLong_Check(index));
685683
long_value = PyLong_AsLongAndOverflow(index, &overflow);
686684
Py_DECREF(index);
685+
assert(!PyErr_Occurred());
687686
if (overflow > 0 || long_value > INT_MAX) {
688687
PyErr_SetString(PyExc_OverflowError,
689688
"fd is greater than maximum");
@@ -706,7 +705,15 @@ dir_fd_converter(PyObject *o, void *p)
706705
*(int *)p = DEFAULT_DIR_FD;
707706
return 1;
708707
}
709-
return _fd_converter(o, (int *)p, "integer");
708+
else if (PyIndex_Check(o)) {
709+
return _fd_converter(o, (int *)p);
710+
}
711+
else {
712+
PyErr_Format(PyExc_TypeError,
713+
"argument should be integer or None, not %.200s",
714+
Py_TYPE(o)->tp_name);
715+
return 0;
716+
}
710717
}
711718

712719

@@ -816,9 +823,10 @@ path_cleanup(path_t *path) {
816823
}
817824

818825
static int
819-
path_converter(PyObject *o, void *p) {
826+
path_converter(PyObject *o, void *p)
827+
{
820828
path_t *path = (path_t *)p;
821-
PyObject *unicode, *bytes;
829+
PyObject *bytes;
822830
Py_ssize_t length;
823831
char *narrow;
824832

@@ -837,12 +845,7 @@ path_converter(PyObject *o, void *p) {
837845
/* ensure it's always safe to call path_cleanup() */
838846
path->cleanup = NULL;
839847

840-
if (o == Py_None) {
841-
if (!path->nullable) {
842-
FORMAT_EXCEPTION(PyExc_TypeError,
843-
"can't specify None for %s argument");
844-
return 0;
845-
}
848+
if ((o == Py_None) && path->nullable) {
846849
path->wide = NULL;
847850
path->narrow = NULL;
848851
path->length = 0;
@@ -851,24 +854,20 @@ path_converter(PyObject *o, void *p) {
851854
return 1;
852855
}
853856

854-
unicode = PyUnicode_FromObject(o);
855-
if (unicode) {
857+
if (PyUnicode_Check(o)) {
856858
#ifdef MS_WINDOWS
857859
wchar_t *wide;
858860

859-
wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
861+
wide = PyUnicode_AsUnicodeAndSize(o, &length);
860862
if (!wide) {
861-
Py_DECREF(unicode);
862863
return 0;
863864
}
864865
if (length > 32767) {
865866
FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
866-
Py_DECREF(unicode);
867867
return 0;
868868
}
869869
if (wcslen(wide) != length) {
870-
FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character");
871-
Py_DECREF(unicode);
870+
FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
872871
return 0;
873872
}
874873

@@ -877,51 +876,46 @@ path_converter(PyObject *o, void *p) {
877876
path->length = length;
878877
path->object = o;
879878
path->fd = -1;
880-
path->cleanup = unicode;
881-
return Py_CLEANUP_SUPPORTED;
879+
return 1;
882880
#else
883-
int converted = PyUnicode_FSConverter(unicode, &bytes);
884-
Py_DECREF(unicode);
885-
if (!converted)
886-
bytes = NULL;
881+
if (!PyUnicode_FSConverter(o, &bytes)) {
882+
return 0;
883+
}
887884
#endif
888885
}
889-
else {
890-
PyErr_Clear();
891-
if (PyObject_CheckBuffer(o))
892-
bytes = PyBytes_FromObject(o);
893-
else
894-
bytes = NULL;
886+
else if (PyObject_CheckBuffer(o)) {
887+
# ifdef MS_WINDOWS
888+
if (win32_warn_bytes_api()) {
889+
return 0;
890+
}
891+
# endif
892+
bytes = PyBytes_FromObject(o);
895893
if (!bytes) {
896-
PyErr_Clear();
897-
if (path->allow_fd) {
898-
int fd;
899-
int result = _fd_converter(o, &fd,
900-
"string, bytes or integer");
901-
if (result) {
902-
path->wide = NULL;
903-
path->narrow = NULL;
904-
path->length = 0;
905-
path->object = o;
906-
path->fd = fd;
907-
return result;
908-
}
909-
}
894+
return 0;
910895
}
911896
}
912-
913-
if (!bytes) {
914-
if (!PyErr_Occurred())
915-
FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
916-
return 0;
897+
else if (path->allow_fd && PyIndex_Check(o)) {
898+
if (!_fd_converter(o, &path->fd)) {
899+
return 0;
900+
}
901+
path->wide = NULL;
902+
path->narrow = NULL;
903+
path->length = 0;
904+
path->object = o;
905+
return 1;
917906
}
918-
919-
#ifdef MS_WINDOWS
920-
if (win32_warn_bytes_api()) {
921-
Py_DECREF(bytes);
907+
else {
908+
PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
909+
path->function_name ? path->function_name : "",
910+
path->function_name ? ": " : "",
911+
path->argument_name ? path->argument_name : "path",
912+
path->allow_fd && path->nullable ? "string, bytes, integer or None" :
913+
path->allow_fd ? "string, bytes or integer" :
914+
path->nullable ? "string, bytes or None" :
915+
"string or bytes",
916+
Py_TYPE(o)->tp_name);
922917
return 0;
923918
}
924-
#endif
925919

926920
length = PyBytes_GET_SIZE(bytes);
927921
#ifdef MS_WINDOWS

0 commit comments

Comments
 (0)