From: Joachim Dahl on
thanks - the patch fixed my problem.

Joachim

On Dec 1, 5:51 am, casevh <cas...(a)gmail.com> wrote:
> On Nov 30, 2:18 pm, Joachim Dahl <dahl.joac...(a)gmail.com> wrote:
>
>
>
>
>
> > I think that "C" encoding is what I need, however I run into an odd
> > problem.
> > If I use the following C code
>
> > static PyObject* foo(PyObject *self, PyObject *args, PyObject *kwrds)
> > {
> >   char a, b;
> >   char *kwlist[] = {"a", "b", NULL};
> >   if (!PyArg_ParseTupleAndKeywords(args, kwrds, "|CC", kwlist, &a,
> > &b))
> >     return NULL;
> >   ...
>
> > then the following works:
>
> > >>> foo('a')
> > >>> foo('a','b')
> > >>> foo(a='a',b='b')
>
> > but the following fails:>>> foo(b='b')
>
> > RuntimeError: impossible<bad format char>: 'CC'
>
> > Is this error-message expected?
>
> Nope. It appears to be a bug in Python. The format code 'C' is missing
> in the switch statement in skipitem() in getargs.c. I added "case
> 'C': /* int */" after "case 'c': /* char */" and then example worked
> for me.
>
> I'll open a bug report.
>
> casevh
>
>
>
>
>
> > On Nov 30, 10:19 pm, casevh <cas...(a)gmail.com> wrote:
>
> > > On Nov 30, 1:04 pm, Joachim Dahl <dahl.joac...(a)gmail.com> wrote:
>
> > > > Obviously the name of the C function and the char variable cannot both
> > > > be foo,
> > > > so the C code should be:
>
> > > > static PyObject* foo(PyObject *self, PyObject *args, PyObject *kwrds)
> > > > {
> > > >   char foochar;
> > > >   char *kwlist[] = {"foochar", NULL};
> > > >   if (!PyArg_ParseTupleAndKeywords(args, kwrds, "c", kwlist,
> > > > &foochar))
> > > >     return NULL;
> > > >   ...
>
> > > > The question remains the same: why can't I pass a single character
> > > > argument to this function under Python3.1?
>
> > > > Thanks.
> > > > Joachim
>
> > > > On Nov 30, 9:52 pm, Joachim Dahl <dahl.joac...(a)gmail.com> wrote:
>
> > > > > I am updating an extension module from Python2.6 to Python3.
>
> > > > > I used to pass character codes to the extension module, for example, I
> > > > > would write:
>
> > > > > >>> foo('X')
>
> > > > > with the corresponding C extension routine defined as follows:
> > > > > static PyObject* foo(PyObject *self, PyObject *args, PyObject *kwrds)
> > > > > {
> > > > >   char foo;
> > > > >   char *kwlist[] = {"foo", NULL};
> > > > >   if (!PyArg_ParseTupleAndKeywords(args, kwrds, "c", kwlist, &foo))
> > > > >     return NULL;
> > > > >   ...
>
> > > > > In Python3.0 this also works, but in Python3.1 I get the following
> > > > > error:
> > > > > TypeError: argument 1 must be a byte string of length 1, not str
>
> > > > > and I seem to be supposed to write>>> foo(b'X')
>
> > > > > instead. From the Python C API, I have not been able to explain this
> > > > > new behavior.
> > > > > What is the correct way to pass a single character argument to
> > > > > Python3.1
> > > > > extension modules?- Hide quoted text -
>
> > > > - Show quoted text -
>
> > > Python 3.1 uses "c" (lowercase c) to parse a single character from a
> > > byte-string and uses "C" (uppercase c) to parse a single character
> > > from a Unicode string. I don't think there is an easy way to accept a
> > > character from both.
>
> > > HTH,
>
> > > casevh

From: Joachim Dahl on
In the Ubuntu 9.10 version of Python 3.1 (using your patch), there's a
related bug:

>>> foo(b='b')

will set the value of a in the extension module to zero, thus clearing
whatever
default value it may have had. In other words, the optional character
arguments
that are skipped seem to be nulled by PyArg_ParseTupleAndKeywords().
From: casevh on
On Dec 17, 11:14 am, Joachim Dahl <dahl.joac...(a)gmail.com> wrote:
> In the Ubuntu 9.10 version of Python 3.1 (using your patch), there's a
> related bug:
>
> >>> foo(b='b')
>
> will set the value of a in the extension module to zero, thus clearing
> whatever
> default value it may have had.  In other words, the optional character
> arguments
> that are skipped seem to be nulled by PyArg_ParseTupleAndKeywords().

The following code seems to work fine for me:

static PyObject* foo(PyObject *self, PyObject *args, PyObject *kwrds)
{
int a=65, b=66;
char *kwlist[] = {"a", "b", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwrds, "|CC", kwlist, &a,
&b))
return NULL;
return Py_BuildValue("(CC)", a, b);
}

The default values seem to remain as 'A' and 'B'.

>>> foo()
('A', 'B')
>>> foo(b='b')
('A', 'b')
>>> foo()
('A', 'B')
>>> foo('a')
('a', 'B')
>>> foo('a', b='b')
('a', 'b')
>>> foo()
('A', 'B')
>>>

casevh
From: Case Vanhorsen on
On Fri, Dec 18, 2009 at 2:26 AM, Emeka <emekamicro(a)gmail.com> wrote:
>    char *kwlist[] = {"a", "b", NULL};
>    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "|CC", kwlist, &a,
> &b))
> I am yet to understand what pointer kwlist[] does and why it is needed?
> Regards,
> Emeka

foo is designed to accept two arguments that can be specified by
either position or name. kwlist contains the legal keyword names. In
this example, the legal keywords are 'a' and 'b'. That they match the
names of the C variables is just a lucky coincidence. If you want to
change the keyword names to 'foo' and 'bar', you would just use char
*kwlist[]={"foo", "bar", NULL}.

casevh
>
> On Fri, Dec 18, 2009 at 8:17 AM, casevh <casevh(a)gmail.com> wrote:
>>
>> On Dec 17, 11:14 am, Joachim Dahl <dahl.joac...(a)gmail.com> wrote:
>> > In the Ubuntu 9.10 version of Python 3.1 (using your patch), there's a
>> > related bug:
>> >
>> > >>> foo(b='b')
>> >
>> > will set the value of a in the extension module to zero, thus clearing
>> > whatever
>> > default value it may have had.  In other words, the optional character
>> > arguments
>> > that are skipped seem to be nulled by PyArg_ParseTupleAndKeywords().
>>
>> The following code seems to work fine for me:
>>
>> static PyObject* foo(PyObject *self, PyObject *args, PyObject *kwrds)
>> {
>>    int a=65, b=66;
>>    char *kwlist[] = {"a", "b", NULL};
>>    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "|CC", kwlist, &a,
>> &b))
>>        return NULL;
>>    return Py_BuildValue("(CC)", a, b);
>> }
>>
>> The default values seem to remain as 'A' and 'B'.
>>
>> >>> foo()
>> ('A', 'B')
>> >>> foo(b='b')
>> ('A', 'b')
>> >>> foo()
>> ('A', 'B')
>> >>> foo('a')
>> ('a', 'B')
>> >>> foo('a', b='b')
>> ('a', 'b')
>> >>> foo()
>> ('A', 'B')
>> >>>
>>
>> casevh
>> --
>> http://mail.python.org/mailman/listinfo/python-list
>
>
From: Case Vanhorsen on
On Fri, Dec 18, 2009 at 7:57 AM, Emeka <emekamicro(a)gmail.com> wrote:
> Case,
> Thanks so much! However, I am still confused. This is what I understood;
> foo (a = "a", b = "b") so function , foo,  has default values which are "a"
> and "b". pointer kwlist[] is a way of specifying default values .
> Regards,
> Emeka
kwlist just specifies the names. The default values are specified by
"int a=65, b=66;". 65 is equivalent to 'A' and 66 is equivalent to
'B'.

casevh
>
> On Fri, Dec 18, 2009 at 3:02 PM, Case Vanhorsen <casevh(a)gmail.com> wrote:
>>
>> On Fri, Dec 18, 2009 at 2:26 AM, Emeka <emekamicro(a)gmail.com> wrote:
>> >    char *kwlist[] = {"a", "b", NULL};
>> >    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "|CC", kwlist, &a,
>> > &b))
>> > I am yet to understand what pointer kwlist[] does and why it is needed?
>> > Regards,
>> > Emeka
>>
>> foo is designed to accept two arguments that can be specified by
>> either position or name. kwlist contains the legal keyword names. In
>> this example, the legal keywords are 'a' and 'b'. That they match the
>> names of the C variables is just a lucky coincidence. If you want to
>> change the keyword names to 'foo' and 'bar', you would just use char
>> *kwlist[]={"foo", "bar", NULL}.
>>
>> casevh
>> >
>> > On Fri, Dec 18, 2009 at 8:17 AM, casevh <casevh(a)gmail.com> wrote:
>> >>
>> >> On Dec 17, 11:14 am, Joachim Dahl <dahl.joac...(a)gmail.com> wrote:
>> >> > In the Ubuntu 9.10 version of Python 3.1 (using your patch), there's
>> >> > a
>> >> > related bug:
>> >> >
>> >> > >>> foo(b='b')
>> >> >
>> >> > will set the value of a in the extension module to zero, thus
>> >> > clearing
>> >> > whatever
>> >> > default value it may have had.  In other words, the optional
>> >> > character
>> >> > arguments
>> >> > that are skipped seem to be nulled by PyArg_ParseTupleAndKeywords()..
>> >>
>> >> The following code seems to work fine for me:
>> >>
>> >> static PyObject* foo(PyObject *self, PyObject *args, PyObject *kwrds)
>> >> {
>> >>    int a=65, b=66;
>> >>    char *kwlist[] = {"a", "b", NULL};
>> >>    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "|CC", kwlist, &a,
>> >> &b))
>> >>        return NULL;
>> >>    return Py_BuildValue("(CC)", a, b);
>> >> }
>> >>
>> >> The default values seem to remain as 'A' and 'B'.
>> >>
>> >> >>> foo()
>> >> ('A', 'B')
>> >> >>> foo(b='b')
>> >> ('A', 'b')
>> >> >>> foo()
>> >> ('A', 'B')
>> >> >>> foo('a')
>> >> ('a', 'B')
>> >> >>> foo('a', b='b')
>> >> ('a', 'b')
>> >> >>> foo()
>> >> ('A', 'B')
>> >> >>>
>> >>
>> >> casevh
>> >> --
>> >> http://mail.python.org/mailman/listinfo/python-list
>> >
>> >
>
>