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

Skip to content

Commit 6f15e57

Browse files
committed
Added new parser markers 'et' and 'et#' which do not recode string
objects but instead assume that they use the requested encoding. This is needed on Windows to enable opening files by passing in Unicode file names.
1 parent b1f35bf commit 6f15e57

2 files changed

Lines changed: 32 additions & 4 deletions

File tree

Doc/ext/ext.tex

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,12 @@ \section{Extracting Parameters in Extension Functions
736736
storage. The caller is responsible for calling
737737
\cfunction{PyMem_Free()} to free the allocated buffer after usage.
738738

739+
\item[\samp{et} (string, Unicode object or character buffer compatible
740+
object) {[const char *encoding, char **buffer]}]
741+
Same as \samp{es} except that string objects are passed through without
742+
recoding them. Instead, the implementation assumes that the string
743+
object uses the encoding passed in as parameter.
744+
739745
\item[\samp{es\#} (string, Unicode object or character buffer compatible
740746
object) {[const char *encoding, char **buffer, int *buffer_length]}]
741747
This variant on \samp{s\#} is used for encoding Unicode and objects
@@ -767,6 +773,12 @@ \section{Extracting Parameters in Extension Functions
767773
In both cases, \var{*buffer_length} is set to the length of the
768774
encoded data without the trailing 0-byte.
769775

776+
\item[\samp{et\#} (string, Unicode object or character buffer compatible
777+
object) {[const char *encoding, char **buffer]}]
778+
Same as \samp{es\#} except that string objects are passed through without
779+
recoding them. Instead, the implementation assumes that the string
780+
object uses the encoding passed in as parameter.
781+
770782
\item[\samp{b} (integer) {[char]}]
771783
Convert a Python integer to a tiny int, stored in a C \ctype{char}.
772784

Python/getargs.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -687,25 +687,39 @@ convertsimple1(PyObject *arg, char **p_format, va_list *p_va)
687687
char **buffer;
688688
const char *encoding;
689689
PyObject *u, *s;
690-
int size;
690+
int size, recode_strings;
691691

692692
/* Get 'e' parameter: the encoding name */
693693
encoding = (const char *)va_arg(*p_va, const char *);
694694
if (encoding == NULL)
695695
encoding = PyUnicode_GetDefaultEncoding();
696696

697-
/* Get 's' parameter: the output buffer to use */
697+
/* Get output buffer parameter:
698+
's' (recode all objects via Unicode) or
699+
't' (only recode non-string objects)
700+
*/
698701
if (*format != 's')
702+
recode_strings = 1;
703+
else if (*format == 't')
704+
recode_strings = 0;
705+
else
699706
return "(unknown parser marker combination)";
700707
buffer = (char **)va_arg(*p_va, char **);
701708
format++;
702709
if (buffer == NULL)
703710
return "(buffer is NULL)";
704711

712+
/* Encode object */
713+
if (!recode_strings && PyString_Check(arg)) {
714+
s = arg;
715+
Py_INCREF(s);
716+
}
717+
else {
705718
/* Convert object to Unicode */
706719
u = PyUnicode_FromObject(arg);
707720
if (u == NULL)
708-
return "string or unicode or text buffer";
721+
return \
722+
"string or unicode or text buffer";
709723

710724
/* Encode object; use default error handling */
711725
s = PyUnicode_AsEncodedString(u,
@@ -716,7 +730,9 @@ convertsimple1(PyObject *arg, char **p_format, va_list *p_va)
716730
return "(encoding failed)";
717731
if (!PyString_Check(s)) {
718732
Py_DECREF(s);
719-
return "(encoder failed to return a string)";
733+
return \
734+
"(encoder failed to return a string)";
735+
}
720736
}
721737
size = PyString_GET_SIZE(s);
722738

0 commit comments

Comments
 (0)