C API PyObject_Call segfaults with string

Jen Kris jenkris at tutanota.com
Thu Feb 10 17:13:21 EST 2022


Thank you for that suggestion.  It allowed me to replace six lines of code with one.  :)


Feb 10, 2022, 12:43 by python at mrabarnett.plus.com:

> On 2022-02-10 20:00, Jen Kris via Python-list wrote:
>
>> With the help of PyErr_Print() I have it solved.  Here is the final code (the part relevant to sents):
>>
>>     Py_ssize_t listIndex = 0;
>>     pListItem = PyList_GetItem(pFileIds, listIndex);
>>     pListStrE = PyUnicode_AsEncodedString(pListItem, "UTF-8", "strict");
>>     pListStr = PyBytes_AS_STRING(pListStrE); // Borrowed pointer
>>
>>     // Then:  sentences = gutenberg.sents(fileid) - this is a sequence item
>>     PyObject *c_args = Py_BuildValue("s", pListStr);
>>     PyObject *args_tuple = PyTuple_New(1);
>>     PyTuple_SetItem(args_tuple, 0, c_args);
>>
>>     pSents = PyObject_CallObject(pSentMod, args_tuple);
>>
>>     if ( pSents == 0x0){
>>         PyErr_Print();
>>         return return_value; }
>>
>> As you mentioned yesterday, CallObject needs a tuple, so that was the problem.  Now it works.
>>
>> You also asked why I don't just use pListStrE.  I tried that and got a long error message from PyErr_Print.  I'm not far enough along in my C_API work to understand why, but it doesn't work.
>>
>> Thanks very much for your help on this.
>>
> You're encoding a Unicode string to a UTF-8 bytestring:
>
>  pListStrE = PyUnicode_AsEncodedString(pListItem, "UTF-8", "strict");
>
> then pointing to the bytes of that UTF-8 bytestring:
>
>  pListStr = PyBytes_AS_STRING(pListStrE); // Borrowed pointer
>
> then making a Unicode string from those UTF-8 bytes:
>
>  PyObject *c_args = Py_BuildValue("s", pListStr);
>
> You might was well just use the original Unicode string!
>
> Try this instead:
>
>  Py_ssize_t listIndex = 0;
>  pListItem = PyList_GetItem(pFileIds, listIndex);
>  //> pListItem?
>
>  pSents = PyObject_CallFunctionObjArgs(pSentMod, pListItem, 0);
>  //> pSents+?
>
>  if (pSents == 0x0){
>  PyErr_Print();
>  return return_value;
>  }
>
>>
>>
>> Feb 9, 2022, 17:40 by songofacandy at gmail.com:
>>
>>> On Thu, Feb 10, 2022 at 10:37 AM Jen Kris <jenkris at tutanota.com> wrote:
>>>
>>>>
>>>> I'm using Python 3.8 so I tried your second choice:
>>>>
>>>> pSents = PyObject_CallFunctionObjArgs(pSentMod, pListItem);
>>>>
>>>> but pSents is 0x0.  pSentMod and pListItem are valid pointers.
>>>>
>>>
>>> It means exception happened.
>>> If you are writing Python/C function, return NULL (e.g. `if (pSents ==
>>> NULL) return NULL`)
>>> Then Python show the exception and traceback for you.
>>>
> -- 
> https://mail.python.org/mailman/listinfo/python-list
>



More information about the Python-list mailing list