CPython Class variable exposed to Python is altered.
Peter Otten
__peter__ at web.de
Wed Apr 12 05:47:40 EDT 2017
Vincent Vande Vyvre wrote:
> Le 12/04/17 à 10:51, Peter Otten a écrit :
>> Vincent Vande Vyvre wrote:
>>
>>> Le 12/04/17 à 08:57, Vincent Vande Vyvre a écrit :
>>>> Hi,
>>>>
>>>> Learning CPython, I've made this simple exercice, a module test which
>>>> contains an object Test.
>>>>
>>>> The object Test has an attribute name, fixed at instanciation.
>>>>
>>>> So, I try my code with a script:
>>>>
>>>> -------------------------------------------
>>>> from test import Test
>>>>
>>>> for n in ("The name", "Foo", "Spam"):
>>>> t = Test(n)
>>>> print("%s --> %s" %(n, t.name))
>>>> -------------------------------------------
>>>>
>>>> And the return:
>>>>
>>>> Uhe name --> Uhe name
>>>> Goo --> Goo
>>>> Tpam --> Tpam
>>>>
>>>> As we can see, the first letter is changed with the next letter in
>>>> alphabetical order, but not only for the attribute name, also for the
>>>> reference n.
>>> if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist, &name))
>>> return -1;
>>>
>>> if (name) {
>>> tmp = self->name;
>>> Py_INCREF(name);
>> While I don't know how to do this properly you seem to be applying
>> Py_INCREF() to a C string rather than a Python string object. C being C
>> you can cast anything to anything else...
>>
>> Aren't there any warnings at compile time?
>>
>
> No, no warning.
>
>
> For the truth, this code is copy-pasted from the doc.
>
> https://docs.python.org/3.5//extending/newtypes.html#adding-data-and-methods-to-the-basic-example
But the example expects objects (the big O), not strings. Following the
example you need
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|", kwlist, &name))
return -1;
and also
static PyMemberDef Test_members[] = {
{"name", T_OBJECT_EX, offsetof(Test, name), 0,
"The object name"},
{NULL} /* Sentinel */
};
If you want a string instead of an object you must not apply Py_INCREF(),
you probably have to manage its lifetime yourself.
More information about the Python-list
mailing list