This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: bug skipping optional keyword arguments of type "w#"
Type: Stage:
Components: Interpreter Core Versions:
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: georg.brandl, mdehoon, mdr0
Priority: normal Keywords: patch

Created on 2004-07-06 04:37 by mdr0, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
Python-2.3.4-getargs-buffer-fix.diff mdr0, 2004-07-06 04:37 Python/getargs.c patch
Messages (4)
msg46317 - (view) Author: Mark D. Roth (mdr0) Date: 2004-07-06 04:37
When using PyArg_ParseTupleAndKeywords(), if you use
"w#" as an optional keyword argument, you cannot skip
it and still specify an optional argument that follows
it.  For example, take the following function:

static PyObject *
dummy_func(PyObject *self, PyObject *args, PyObject *kwds)
{
        char *string;
        char *buf = NULL;
        int bufsize = 0;
        unsigned short ushort = 5;
        static char *kwlist[] = { "string", "buffer",
"ushort", NULL };

        if (! PyArg_ParseTupleAndKeywords(args, kwds,
"s|w#H", kwlist,
                                          &string,
                                          &buf,
                                          &bufsize,
                                          &ushort))
                return NULL;

        printf("buf=%p, bufsize=%d, ushort=%hu\n", buf,
bufsize, ushort);
        snprintf(buf, bufsize, "you said \"%s\"\n",
hostname);

        return Py_BuildValue("s", hostname);
}

You can call this function successfully as follows:

# don't specify buffer or ushort
dummy_func("text")

Or like this:

# specify buffer
buf = array.array('c', [' ' for x in range(0, 1023)])
dummy_func("text", buffer=buf)

Or like this:

# specify buffer and ushort
buf = array.array('c', [' ' for x in range(0, 1023)])
dummy_func("text", buffer=buf, ushort=10)

However, the following does NOT work:

# specify ushort without first specifying buffer
dummy_func("text", ushort=10)

It fails with the following error:

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: argument 2 impossible<bad format char>

This is because the skipitem() function in
Python/getargs.c does not know how to skip arguments
for the "w#" format unit.
I've attached a patch that fixes this.

Note that skipitem() is also missing code for many
other legal format units, in addition to "w" and "w#".
 In particular:

  u, u#     (see patch #853890)
  es, es#
  et, et#
  I (capital i)
  k
  K
  D
  S
  U
  t#
  (tuple)

It might be a good idea to refactor the code so that
if/when new format units are added, the same code will
handle them for both skipitem() and convertsimple().
msg46318 - (view) Author: Mark D. Roth (mdr0) Date: 2004-07-06 04:42
Logged In: YES 
user_id=994239

Whoops!  You'll need to change "hostname" to "string" in
that example function.  I missed a few occurances of that
variable when I renamed it to make the example more clear...
*sheepish grin*
msg46319 - (view) Author: Michiel de Hoon (mdehoon) * Date: 2005-02-27 14:41
Logged In: YES 
user_id=488897

I applied your patch and ran the Python test suite, finding
no problems with this patch. I'll send a patch review to
python-dev.
msg46320 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2005-06-01 18:24
Logged In: YES 
user_id=1188172

Closing; subsumed by #1212928.
History
Date User Action Args
2022-04-11 14:56:05adminsetgithub: 40513
2004-07-06 04:37:06mdr0create