[Pyrex] Total newbie needs code review
Greg Ewing
greg.ewing at canterbury.ac.nz
Mon Sep 12 07:22:32 CEST 2005
Grant McDonald wrote:
> What pyrex means by "Obtaining char * from temporary Python value" is
> that you haven't created a char pointer variable to hold the string
> value.
Er, not exactly. By "temporary Python value" it means
one of its internally generated local variables holding
an object reference. It's meant to catch things like
cdef char *p
p = s1 + s2
where s1 and s2 are Python strings. This generates
something like
char *p;
PyObject *__pyx_1;
__pyx_1 = PyObject_Add(s1, s2);
p = PyString_AsString(__pyx_1);
Py_DECREF(__pyx_1);
The "temporary Python value" here is __pyx_1. This
piece of code can't possibly work correctly, because
the result of PyObject_Add in this case is a brand
new string object with no other references to it,
so it's going to go away as soon as the Py_DECREF
is executed, leaving p dangling.
It seemed to me it would be rather easy to fall
into this trap unawares, so I built in a heuristic
which essentially makes it an error to write something
which causes PyString_AsString to be applied to one
of these internal temporary variables. Being a
heuristic, sometimes it gets it wrong, rejecting
something that's actually okay, or accepting
something that's not okay.
In your case, it sounds like it's a false alarm,
although I'd have to see the exact piece of code
producing it to be sure.
> The
> way to remove this warning from your code is to be explicit in your
> conversions:
That's not quite correct. The way to remove it is to
make sure that the Python string reference you're starting
with (NOT the char *) is held in an explicitly-named
variable (local, global or parameter).
> doStuff(pyStuff) # implicit
>
> cStuff = pyStuff
> doStuff(cStuff) # explicit
Both of those actually compile okay. An example of
something that *does* (currently) produce the error
is
doStuff(foo.stuff)
and it can be removed by rewriting it as
pyStuff = foo.stuff
doStuff(pyStuff)
What grant wrote about mallocing a copy of the string
if you need to modify it is correct. I'd just add that
you should also malloc a copy if there is any chance
that the original Python string could get garbage
collected before you're finished with the C string.
--
Greg Ewing, Computer Science Dept, +--------------------------------------+
University of Canterbury, | A citizen of NewZealandCorp, a |
Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. |
greg.ewing at canterbury.ac.nz +--------------------------------------+
More information about the Pyrex
mailing list