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. -- https://mail.python.org/mailman/listinfo/python-list