@@ -715,21 +715,126 @@ Internal Argument Parsing:
715715
716716These markers are used by the PyArg_ParseTuple() APIs:
717717
718- 'U' : Check for Unicode object and return a pointer to it
718+ "U" : Check for Unicode object and return a pointer to it
719719
720- 's' : For Unicode objects: auto convert them to the <default encoding>
720+ "s" : For Unicode objects: auto convert them to the <default encoding>
721721 and return a pointer to the object's <defencstr> buffer.
722722
723- 's#' : Access to the Unicode object via the bf_getreadbuf buffer interface
723+ "s#" : Access to the Unicode object via the bf_getreadbuf buffer interface
724724 (see Buffer Interface); note that the length relates to the buffer
725725 length, not the Unicode string length (this may be different
726726 depending on the Internal Format).
727727
728- 't#' : Access to the Unicode object via the bf_getcharbuf buffer interface
728+ "t#" : Access to the Unicode object via the bf_getcharbuf buffer interface
729729 (see Buffer Interface); note that the length relates to the buffer
730730 length, not necessarily to the Unicode string length (this may
731731 be different depending on the <default encoding>).
732732
733+ "es":
734+ Takes two parameters: encoding (const char *) and
735+ buffer (char **).
736+
737+ The input object is first coerced to Unicode in the usual way
738+ and then encoded into a string using the given encoding.
739+
740+ On output, a buffer of the needed size is allocated and
741+ returned through *buffer as NULL-terminated string.
742+ The encoded may not contain embedded NULL characters.
743+ The caller is responsible for free()ing the allocated *buffer
744+ after usage.
745+
746+ "es#":
747+ Takes three parameters: encoding (const char *),
748+ buffer (char **) and buffer_len (int *).
749+
750+ The input object is first coerced to Unicode in the usual way
751+ and then encoded into a string using the given encoding.
752+
753+ If *buffer is non-NULL, *buffer_len must be set to sizeof(buffer)
754+ on input. Output is then copied to *buffer.
755+
756+ If *buffer is NULL, a buffer of the needed size is
757+ allocated and output copied into it. *buffer is then
758+ updated to point to the allocated memory area. The caller
759+ is responsible for free()ing *buffer after usage.
760+
761+ In both cases *buffer_len is updated to the number of
762+ characters written (excluding the trailing NULL-byte).
763+ The output buffer is assured to be NULL-terminated.
764+
765+ Examples:
766+
767+ Using "es#" with auto-allocation:
768+
769+ static PyObject *
770+ test_parser(PyObject *self,
771+ PyObject *args)
772+ {
773+ PyObject *str;
774+ const char *encoding = "latin-1";
775+ char *buffer = NULL;
776+ int buffer_len = 0;
777+
778+ if (!PyArg_ParseTuple(args, "es#:test_parser",
779+ encoding, &buffer, &buffer_len))
780+ return NULL;
781+ if (!buffer) {
782+ PyErr_SetString(PyExc_SystemError,
783+ "buffer is NULL");
784+ return NULL;
785+ }
786+ str = PyString_FromStringAndSize(buffer, buffer_len);
787+ free(buffer);
788+ return str;
789+ }
790+
791+ Using "es" with auto-allocation returning a NULL-terminated string:
792+
793+ static PyObject *
794+ test_parser(PyObject *self,
795+ PyObject *args)
796+ {
797+ PyObject *str;
798+ const char *encoding = "latin-1";
799+ char *buffer = NULL;
800+
801+ if (!PyArg_ParseTuple(args, "es:test_parser",
802+ encoding, &buffer))
803+ return NULL;
804+ if (!buffer) {
805+ PyErr_SetString(PyExc_SystemError,
806+ "buffer is NULL");
807+ return NULL;
808+ }
809+ str = PyString_FromString(buffer);
810+ free(buffer);
811+ return str;
812+ }
813+
814+ Using "es#" with a pre-allocated buffer:
815+
816+ static PyObject *
817+ test_parser(PyObject *self,
818+ PyObject *args)
819+ {
820+ PyObject *str;
821+ const char *encoding = "latin-1";
822+ char _buffer[10];
823+ char *buffer = _buffer;
824+ int buffer_len = sizeof(_buffer);
825+
826+ if (!PyArg_ParseTuple(args, "es#:test_parser",
827+ encoding, &buffer, &buffer_len))
828+ return NULL;
829+ if (!buffer) {
830+ PyErr_SetString(PyExc_SystemError,
831+ "buffer is NULL");
832+ return NULL;
833+ }
834+ str = PyString_FromStringAndSize(buffer, buffer_len);
835+ return str;
836+ }
837+
733838
734839File/Stream Output:
735840-------------------
@@ -837,6 +942,7 @@ Encodings:
837942
838943History of this Proposal:
839944-------------------------
945+ 1.3: Added new "es" and "es#" parser markers
8409461.2: Removed POD about codecs.open()
8419471.1: Added note about comparisons and hash values. Added note about
842948 case mapping algorithms. Changed stream codecs .read() and
0 commit comments