]> granicus.if.org Git - python/commitdiff
SF 569257 -- Name mangle double underscored variable names in __slots__.
authorRaymond Hettinger <python@rcn.com>
Thu, 20 Jun 2002 22:23:15 +0000 (22:23 +0000)
committerRaymond Hettinger <python@rcn.com>
Thu, 20 Jun 2002 22:23:15 +0000 (22:23 +0000)
Include/Python.h
Lib/test/test_descr.py
Objects/typeobject.c
Python/compile.c

index 548ac756cb18f2ac7a93bf6cd52bbfe1eb998450..ff21ad1b85e0282da7558042915d266f4447f05d 100644 (file)
 
 #include "abstract.h"
 
+/* _Py_Mangle is defined in compile.c */
+extern DL_IMPORT(int) _Py_Mangle(char *p, char *name, \
+                                char *buffer, size_t maxlen);
+
 /* PyArg_GetInt is deprecated and should not be used, use PyArg_Parse(). */
 #define PyArg_GetInt(v, a)     PyArg_Parse((v), "i", (a))
 
index 2129a7b7c812f7577b63e303c43ba33ee4fe3f02..dca8ea1760e7a3bdf4682bea2ddaa2ee5f1cff78 100644 (file)
@@ -1060,6 +1060,24 @@ def slots():
     vereq(x.b, 2)
     vereq(x.c, 3)
 
+    class C4(object):
+        """Validate name mangling"""
+        __slots__ = ['__a']
+        def __init__(self, value):
+            self.__a = value
+        def get(self):
+            return self.__a
+    x = C4(5)
+    verify(not hasattr(x, '__dict__'))
+    verify(not hasattr(x, '__a'))
+    vereq(x.get(), 5)
+    try:
+        x.__a = 6
+    except AttributeError:
+        pass
+    else:
+        raise TestFailed, "Double underscored names not mangled"
+
     # Make sure slot names are proper identifiers
     try:
         class C(object):
index 7918af09dbc145871680b38fe312ac97ff14d6d8..47613f51f2a47d2a48889a56c5e5eabe6e2305b3 100644 (file)
@@ -1001,7 +1001,8 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
 {
        PyObject *name, *bases, *dict;
        static char *kwlist[] = {"name", "bases", "dict", 0};
-       PyObject *slots, *tmp;
+       static char buffer[256];
+       PyObject *slots, *tmp, *newslots;
        PyTypeObject *type, *base, *tmptype, *winner;
        etype *et;
        PyMemberDef *mp;
@@ -1115,6 +1116,25 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
                                return NULL;
                        }
                }
+
+               newslots = PyTuple_New(nslots);
+               if (newslots == NULL)
+                       return NULL;
+               for (i = 0; i < nslots; i++) {
+                       tmp = PyTuple_GET_ITEM(slots, i);
+                       if (_Py_Mangle(PyString_AS_STRING(name),
+                               PyString_AS_STRING(tmp),
+                               buffer, sizeof(buffer)))
+                       {
+                               tmp = PyString_FromString(buffer);
+                       } else {
+                               Py_INCREF(tmp);
+                       }
+                       PyTuple_SET_ITEM(newslots, i, tmp);
+               }
+               Py_DECREF(slots);
+               slots = newslots;
+
        }
        if (slots != NULL) {
                /* See if *this* class defines __getstate__ */
index b0e125de8eb4b4fa25497243cb168598284f7dd6..fa53b1ea85a326649c0d8b099a2fe0eae7b2d5b5 100644 (file)
@@ -928,8 +928,8 @@ com_addname(struct compiling *c, PyObject *v)
        return com_add(c, c->c_names, c->c_name_dict, v);
 }
 
-static int
-mangle(char *p, char *name, char *buffer, size_t maxlen)
+int
+_Py_Mangle(char *p, char *name, char *buffer, size_t maxlen)
 {
        /* Name mangling: __private becomes _classname__private.
           This is independent from how the name is used. */
@@ -963,7 +963,7 @@ com_addop_name(struct compiling *c, int op, char *name)
        int i;
        char buffer[MANGLE_LEN];
 
-       if (mangle(c->c_private, name, buffer, sizeof(buffer)))
+       if (_Py_Mangle(c->c_private, name, buffer, sizeof(buffer)))
                name = buffer;
        if (name == NULL || (v = PyString_InternFromString(name)) == NULL) {
                c->c_errors++;
@@ -1000,7 +1000,7 @@ com_addop_varname(struct compiling *c, int kind, char *name)
        int op = STOP_CODE;
        char buffer[MANGLE_LEN];
 
-       if (mangle(c->c_private, name, buffer, sizeof(buffer)))
+       if (_Py_Mangle(c->c_private, name, buffer, sizeof(buffer)))
                name = buffer;
        if (name == NULL || (v = PyString_InternFromString(name)) == NULL) {
                c->c_errors++;
@@ -4956,7 +4956,7 @@ symtable_lookup(struct symtable *st, char *name)
        PyObject *v;
        int flags;
 
-       if (mangle(st->st_private, name, buffer, sizeof(buffer)))
+       if (_Py_Mangle(st->st_private, name, buffer, sizeof(buffer)))
                name = buffer;
        v = PyDict_GetItemString(st->st_cur->ste_symbols, name);
        if (v == NULL) {
@@ -4977,7 +4977,7 @@ symtable_add_def(struct symtable *st, char *name, int flag)
        char buffer[MANGLE_LEN];
        int ret;
 
-       if (mangle(st->st_private, name, buffer, sizeof(buffer)))
+       if (_Py_Mangle(st->st_private, name, buffer, sizeof(buffer)))
                name = buffer;
        if ((s = PyString_InternFromString(name)) == NULL)
                return -1;