CPython Class variable exposed to Python is altered.

Vincent Vande Vyvre vincent.vande.vyvre at telenet.be
Wed Apr 12 03:23:17 EDT 2017


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.
>
> Same into a console:
>
> (py352_venv) vincent at djoliba:~/CPython/py352_venv/pydcraw$ python
> Python 3.5.2 (default, Dec 19 2016, 11:46:33)
> [GCC 4.8.4] on linux
> Type "help", "copyright", "credits" or "license" for more information.
> >>> from test import Test
> >>> for n in ("The name", "Foo", "Spam"):
> ...     t = Test(n)
> ...     print("%s --> %s" %(n, t.name))
> ...
> Uhe name --> Uhe name
> Goo --> Goo
> Tpam --> Tpam
>
>
> I'm working in a venv.
>
> The testmodule.c is attached.
>
>
> The setup.py
> ------------------------------------------------
> from distutils.core import setup, Extension
> setup(name="test", version="1.0",
>       ext_modules=[
>          Extension("test", ["testmodule.c"],
>                    libraries=[])
>          ])
> ------------------------------------------------
>
>
> Best,
>
>
> Vincent
>
I see the attachement is rejected.


This is the testmodule.c

-----------------------------------------------------------

#include <Python.h>
#include "structmember.h"


typedef struct {
     PyObject_HEAD
     PyObject *name;
} Test;

static void
Test_dealloc(Test* self)
{
     Py_XDECREF(self->name);
}

static PyObject *
Test_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
     Test *self;

     self = (Test *)type->tp_alloc(type, 0);
     if (self != NULL){
         self->name = PyUnicode_FromString("");
         if (self->name == NULL){
             Py_DECREF(self);
             return NULL;
         }
     }

     return (PyObject *)self;
}

static int
Test_init(Test *self, PyObject *args, PyObject *kwds)
{
     PyObject *name, *tmp;
     static char *kwlist[] = {"name", NULL};

     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist, &name))
         return -1;

     if (name) {
         tmp = self->name;
         Py_INCREF(name);
         self->name = name;
         Py_XDECREF(tmp);
     }

     return 0;
}

static PyMemberDef Test_members[] = {
     {"name", T_STRING, offsetof(Test, name), 0,
      "The object name"},
     {NULL}  /* Sentinel */
};

static PyMethodDef Test_methods[] = {
     {NULL} /* sentinel */
};

static PyTypeObject TestType = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "test.Test",                  /* tp_name */
     sizeof(Test),                 /* tp_basicsize */
     0,                            /* tp_itemsize */
     (destructor)Test_dealloc,     /* tp_dealloc */
     0,                            /* tp_print */
     0,                            /* tp_getattr */
     0,                            /* tp_setattr */
     0,                            /* tp_reserved */
     0,                            /* tp_repr */
     0,                            /* tp_as_number */
     0,                            /* tp_as_sequence */
     0,                            /* tp_as_mapping */
     0,                            /* tp_hash  */
     0,                            /* tp_call */
     0,                            /* tp_str */
     0,                            /* tp_getattro */
     0,                            /* tp_setattro */
     0,                            /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT |
         Py_TPFLAGS_BASETYPE,      /* tp_flags */
     "Test object",                /* tp_doc */
     0,                            /* tp_traverse */
     0,                            /* tp_clear */
     0,                            /* tp_richcompare */
     0,                            /* tp_weaklistoffset */
     0,                            /* tp_iter */
     0,                            /* tp_iternext */
     Test_methods,                 /* tp_methods */
     Test_members,                 /* tp_members */
     0,                            /* tp_getset */
     0,                            /* tp_base */
     0,                            /* tp_dict */
     0,                            /* tp_descr_get */
     0,                            /* tp_descr_set */
     0,                            /* tp_dictoffset */
     (initproc)Test_init,          /* tp_init */
     0,                            /* tp_alloc */
     Test_new,                     /* tp_new */
};

static PyModuleDef testmodule = {
     PyModuleDef_HEAD_INIT,
     "test",
     "Example module.",
     -1,
     NULL, NULL, NULL, NULL, NULL
};

PyMODINIT_FUNC
PyInit_test(void)
{
     PyObject* m;

     if (PyType_Ready(&TestType) < 0)
         return NULL;

     m = PyModule_Create(&testmodule);
     if (m == NULL)
         return NULL;

     Py_INCREF(&TestType);
     PyModule_AddObject(m, "Test", (PyObject *)&TestType);
     return m;
}

-----------------------------------------------------------------------------------



More information about the Python-list mailing list