@@ -669,21 +669,20 @@ _Py_Dev_Converter(PyObject *obj, void *p)
669669#endif
670670
671671static 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
818825static 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