]> granicus.if.org Git - python/commitdiff
#6201: Fix test_winreg on Windows:
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>
Tue, 9 Jun 2009 23:08:13 +0000 (23:08 +0000)
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>
Tue, 9 Jun 2009 23:08:13 +0000 (23:08 +0000)
since the introduction of the SETUP_WITH opcode,
__enter__ and __exit__ methods must belong to the type,
and are not retrieved at the instance level (__dict__ or __getattr__).

Add a note in whatsnew about this incompatibility;
old style classes are not affected.

Doc/whatsnew/2.7.rst
PC/_winreg.c

index df7601fbcd096b61b813061a986b56a3205d9a82..01dcc9f3cc5abe6ad7d0eed28f83e72a932f1cf0 100644 (file)
@@ -669,7 +669,11 @@ Porting to Python 2.7
 This section lists previously described changes and other bugfixes
 that may require changes to your code:
 
-To be written.
+* Because of an optimization for the :keyword:`with` statement, the special
+  methods :meth:`__enter__` and :meth:`__exit__` must belong to the object's
+  type, and cannot be directly attached to the object's instance.  This
+  affects new-styles classes (derived from :class:`object`) or C extension
+  types.  (:issue:`6101`.)
 
 .. ======================================================================
 
index 9f234a1a18a354b94924b730b524ee5fbe4b7d41..a79b0a0b0b1864cf97ec69b1bd6b93ced65e2d6c 100644 (file)
@@ -469,9 +469,23 @@ static PyNumberMethods PyHKEY_NumberMethods =
        PyHKEY_unaryFailureFunc,        /* nb_hex */
 };
 
+static PyObject *PyHKEY_CloseMethod(PyObject *self, PyObject *args);
+static PyObject *PyHKEY_DetachMethod(PyObject *self, PyObject *args);
+static PyObject *PyHKEY_Enter(PyObject *self);
+static PyObject *PyHKEY_Exit(PyObject *self, PyObject *args);
 
-/* fwd declare __getattr__ */
-static PyObject *PyHKEY_getattr(PyObject *self, const char *name);
+static struct PyMethodDef PyHKEY_methods[] = {
+       {"Close",  PyHKEY_CloseMethod, METH_VARARGS, PyHKEY_Close_doc},
+       {"Detach", PyHKEY_DetachMethod, METH_VARARGS, PyHKEY_Detach_doc},
+       {"__enter__", (PyCFunction)PyHKEY_Enter, METH_NOARGS, NULL},
+       {"__exit__", PyHKEY_Exit, METH_VARARGS, NULL},
+       {NULL}
+};
+
+static PyMemberDef PyHKEY_memberlist[] = {
+       {"handle", T_PYSSIZET, offsetof(PyHKEYObject, hkey), READONLY},
+       {NULL}    /* Sentinel */
+};
 
 /* The type itself */
 PyTypeObject PyHKEY_Type =
@@ -482,7 +496,7 @@ PyTypeObject PyHKEY_Type =
        0,
        PyHKEY_deallocFunc,             /* tp_dealloc */
        PyHKEY_printFunc,               /* tp_print */
-       PyHKEY_getattr,                 /* tp_getattr */
+       0,                              /* tp_getattr */
        0,                              /* tp_setattr */
        PyHKEY_compareFunc,             /* tp_compare */
        0,                              /* tp_repr */
@@ -495,15 +509,16 @@ PyTypeObject PyHKEY_Type =
        0,                              /* tp_getattro */
        0,                              /* tp_setattro */
        0,                              /* tp_as_buffer */
-       0,                              /* tp_flags */
+       Py_TPFLAGS_DEFAULT,             /* tp_flags */
        PyHKEY_doc,                     /* tp_doc */
-};
-
-#define OFF(e) offsetof(PyHKEYObject, e)
-
-static struct memberlist PyHKEY_memberlist[] = {
-       {"handle",      T_INT,      OFF(hkey)},
-       {NULL}    /* Sentinel */
+       0,                              /* tp_traverse */
+       0,                              /* tp_clear */
+       0,                              /* tp_richcompare */
+       0,                              /* tp_weaklistoffset */
+       0,                              /* tp_iter */
+       0,                              /* tp_iternext */
+       PyHKEY_methods,                 /* tp_methods */
+       PyHKEY_memberlist,              /* tp_members */
 };
 
 /************************************************************************
@@ -550,28 +565,6 @@ PyHKEY_Exit(PyObject *self, PyObject *args)
 }
 
 
-static struct PyMethodDef PyHKEY_methods[] = {
-       {"Close",  PyHKEY_CloseMethod, METH_VARARGS, PyHKEY_Close_doc},
-       {"Detach", PyHKEY_DetachMethod, METH_VARARGS, PyHKEY_Detach_doc},
-       {"__enter__", (PyCFunction)PyHKEY_Enter, METH_NOARGS, NULL},
-       {"__exit__", PyHKEY_Exit, METH_VARARGS, NULL},
-       {NULL}
-};
-
-/*static*/ PyObject *
-PyHKEY_getattr(PyObject *self, const char *name)
-{
-       PyObject *res;
-
-       res = Py_FindMethod(PyHKEY_methods, self, name);
-       if (res != NULL)
-               return res;
-       PyErr_Clear();
-       if (strcmp(name, "handle") == 0)
-               return PyLong_FromVoidPtr(((PyHKEYObject *)self)->hkey);
-       return PyMember_Get((char *)self, PyHKEY_memberlist, name);
-}
-
 /************************************************************************
    The public PyHKEY API (well, not public yet :-)
 ************************************************************************/
@@ -1634,7 +1627,8 @@ PyMODINIT_FUNC init_winreg(void)
        if (m == NULL)
                return;
        d = PyModule_GetDict(m);
-       PyHKEY_Type.ob_type = &PyType_Type;
+       if (PyType_Ready(&PyHKEY_Type) < 0)
+               return;
        PyHKEY_Type.tp_doc = PyHKEY_doc;
        Py_INCREF(&PyHKEY_Type);
        if (PyDict_SetItemString(d, "HKEYType",