@@ -842,7 +842,8 @@ _match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_
842842 Py_ssize_t idx = start ;
843843 int is_float = 0 ;
844844 PyObject * rval ;
845- PyObject * numstr ;
845+ PyObject * numstr = NULL ;
846+ PyObject * custom_func ;
846847
847848 /* read a sign if it's there, make sure it's not the end of the string */
848849 if (str [idx ] == '-' ) {
@@ -895,22 +896,37 @@ _match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_
895896 }
896897 }
897898
898- /* copy the section we determined to be a number */
899- numstr = PyUnicode_FromUnicode (& str [start ], idx - start );
900- if (numstr == NULL )
901- return NULL ;
902- if (is_float ) {
903- /* parse as a float using a fast path if available, otherwise call user defined method */
904- if (s -> parse_float != (PyObject * )& PyFloat_Type ) {
905- rval = PyObject_CallFunctionObjArgs (s -> parse_float , numstr , NULL );
906- }
907- else {
908- rval = PyFloat_FromString (numstr );
909- }
899+ if (is_float && s -> parse_float != (PyObject * )& PyFloat_Type )
900+ custom_func = s -> parse_float ;
901+ else if (!is_float && s -> parse_int != (PyObject * ) & PyLong_Type )
902+ custom_func = s -> parse_int ;
903+ else
904+ custom_func = NULL ;
905+
906+ if (custom_func ) {
907+ /* copy the section we determined to be a number */
908+ numstr = PyUnicode_FromUnicode (& str [start ], idx - start );
909+ if (numstr == NULL )
910+ return NULL ;
911+ rval = PyObject_CallFunctionObjArgs (custom_func , numstr , NULL );
910912 }
911913 else {
912- /* no fast path for unicode -> int, just call */
913- rval = PyObject_CallFunctionObjArgs (s -> parse_int , numstr , NULL );
914+ Py_ssize_t i , n ;
915+ char * buf ;
916+ /* Straight conversion to ASCII, to avoid costly conversion of
917+ decimal unicode digits (which cannot appear here) */
918+ n = idx - start ;
919+ numstr = PyBytes_FromStringAndSize (NULL , n );
920+ if (numstr == NULL )
921+ return NULL ;
922+ buf = PyBytes_AS_STRING (numstr );
923+ for (i = 0 ; i < n ; i ++ ) {
924+ buf [i ] = (char ) str [i + start ];
925+ }
926+ if (is_float )
927+ rval = PyFloat_FromString (numstr );
928+ else
929+ rval = PyLong_FromString (buf , NULL , 10 );
914930 }
915931 Py_DECREF (numstr );
916932 * next_idx_ptr = idx ;
0 commit comments