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

Skip to content

Commit 0afff38

Browse files
committed
Special case the "s#" PyArg_Parse() token for Unicode objects:
"s#" will now return a pointer to the default encoded string data of the Unicode object instead of a pointer to the raw UTF-16 data. The latter is still available via PyObject_AsReadBuffer(). The patch also adds an optimization for string objects which is based on the fact that string objects return the raw character data for getreadbuffer access and are always single-segment.
1 parent 3578b77 commit 0afff38

1 file changed

Lines changed: 53 additions & 26 deletions

File tree

Python/getargs.c

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -556,22 +556,36 @@ convertsimple1(PyObject *arg, char **p_format, va_list *p_va)
556556

557557
case 's': /* string */
558558
{
559-
if (*format == '#') { /* any buffer-like object */
559+
if (*format == '#') {
560560
void **p = (void **)va_arg(*p_va, char **);
561-
PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
562561
int *q = va_arg(*p_va, int *);
563-
int count;
564562

565-
if ( pb == NULL ||
566-
pb->bf_getreadbuffer == NULL ||
567-
pb->bf_getsegcount == NULL )
568-
return "read-only buffer";
569-
if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
570-
return "single-segment read-only buffer";
571-
if ( (count =
572-
(*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
573-
return "(unspecified)";
574-
*q = count;
563+
if (PyString_Check(arg)) {
564+
*p = PyString_AS_STRING(arg);
565+
*q = PyString_GET_SIZE(arg);
566+
}
567+
else if (PyUnicode_Check(arg)) {
568+
arg = _PyUnicode_AsDefaultEncodedString(
569+
arg, NULL);
570+
if (arg == NULL)
571+
return "unicode conversion error";
572+
*p = PyString_AS_STRING(arg);
573+
*q = PyString_GET_SIZE(arg);
574+
}
575+
else { /* any buffer-like object */
576+
PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
577+
int count;
578+
if ( pb == NULL ||
579+
pb->bf_getreadbuffer == NULL ||
580+
pb->bf_getsegcount == NULL )
581+
return "read-only buffer";
582+
if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
583+
return "single-segment read-only buffer";
584+
if ( (count =
585+
(*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
586+
return "(unspecified)";
587+
*q = count;
588+
}
575589
format++;
576590
} else {
577591
char **p = va_arg(*p_va, char **);
@@ -597,24 +611,37 @@ convertsimple1(PyObject *arg, char **p_format, va_list *p_va)
597611
{
598612
if (*format == '#') { /* any buffer-like object */
599613
void **p = (void **)va_arg(*p_va, char **);
600-
PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
601614
int *q = va_arg(*p_va, int *);
602-
int count;
603615

604616
if (arg == Py_None) {
605617
*p = 0;
606618
*q = 0;
607-
} else {
608-
if ( pb == NULL ||
609-
pb->bf_getreadbuffer == NULL ||
610-
pb->bf_getsegcount == NULL )
611-
return "read-only buffer";
612-
if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
613-
return "single-segment read-only buffer";
614-
if ( (count = (*pb->bf_getreadbuffer)
615-
(arg, 0, p)) < 0 )
616-
return "(unspecified)";
617-
*q = count;
619+
}
620+
else if (PyString_Check(arg)) {
621+
*p = PyString_AS_STRING(arg);
622+
*q = PyString_GET_SIZE(arg);
623+
}
624+
else if (PyUnicode_Check(arg)) {
625+
arg = _PyUnicode_AsDefaultEncodedString(
626+
arg, NULL);
627+
if (arg == NULL)
628+
return "unicode conversion error";
629+
*p = PyString_AS_STRING(arg);
630+
*q = PyString_GET_SIZE(arg);
631+
}
632+
else { /* any buffer-like object */
633+
PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
634+
int count;
635+
if ( pb == NULL ||
636+
pb->bf_getreadbuffer == NULL ||
637+
pb->bf_getsegcount == NULL )
638+
return "read-only buffer";
639+
if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
640+
return "single-segment read-only buffer";
641+
if ( (count =
642+
(*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
643+
return "(unspecified)";
644+
*q = count;
618645
}
619646
format++;
620647
} else {

0 commit comments

Comments
 (0)