#2989: add PyType_Modified().
authorGeorg Brandl <georg@python.org>
Wed, 28 May 2008 11:21:39 +0000 (11:21 +0000)
committerGeorg Brandl <georg@python.org>
Wed, 28 May 2008 11:21:39 +0000 (11:21 +0000)
Doc/c-api/type.rst
Include/object.h
Misc/NEWS
Objects/typeobject.c

index 762c003c7470e2874d89ba629d4ede76fc651c82..e4e2e380b7d23c738c2028eac9735821cb6bd972 100644 (file)
@@ -37,7 +37,16 @@ Type Objects
 
 .. cfunction:: unsigned int PyType_ClearCache(void)
 
-   Clears the internal lookup cache. Return the current version tag.
+   Clear the internal lookup cache. Return the current version tag.
+
+   .. versionadded:: 2.6
+
+
+.. cfunction:: void PyType_Modified(PyTypeObject *type)
+
+   Invalidate the internal lookup cache for the type and all of its
+   subtypes.  This function must be called after any manual
+   modification of the attributes or base classes of the type.
 
    .. versionadded:: 2.6
 
index 2bdeb3246fa73ad48fb8ceb3b3c6ab66dd523d5e..e0f5650d588ba53e65fa5ecb27dd418ce9f74f3c 100644 (file)
@@ -460,6 +460,7 @@ PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *,
                                               PyObject *, PyObject *);
 PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
 PyAPI_FUNC(unsigned int) PyType_ClearCache(void);
+PyAPI_FUNC(void) PyType_Modified(PyTypeObject *);
 
 /* Generic operations on objects */
 PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
index 1decc90e2b361d9bf22c4e210a5360f8a620e8c6..e5f251abaf752610b8fcc73a7f64472023edff0a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -239,7 +239,9 @@ Build
 C API
 -----
 
-- The PyBytes functions have been renamed to PyByteArray
+- Add ``PyType_Modified()`` as a public API to clear the type cache.
+
+- The PyBytes functions have been renamed to PyByteArray.
 
 - The PyString functions have been renamed to PyBytes. A batch of
   defines were added so that the linker still sees the original
index 2ea3d295faff164ba075214b180f5ddcf5a638a0..151ea69f4f9dc30e1a9efe5d3e9ebc2be91526eb 100644 (file)
@@ -32,7 +32,6 @@ struct method_cache_entry {
 
 static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP];
 static unsigned int next_version_tag = 0;
-static void type_modified(PyTypeObject *);
 
 unsigned int
 PyType_ClearCache(void)
@@ -47,12 +46,12 @@ PyType_ClearCache(void)
        }
        next_version_tag = 0;
        /* mark all version tags as invalid */
-       type_modified(&PyBaseObject_Type);
+       PyType_Modified(&PyBaseObject_Type);
        return cur_version_tag;
 }
 
-static void
-type_modified(PyTypeObject *type)
+void
+PyType_Modified(PyTypeObject *type)
 {
        /* Invalidate any cached data for the specified type and all
           subclasses.  This function is called after the base
@@ -86,7 +85,7 @@ type_modified(PyTypeObject *type)
                        ref = PyList_GET_ITEM(raw, i);
                        ref = PyWeakref_GET_OBJECT(ref);
                        if (ref != Py_None) {
-                               type_modified((PyTypeObject *)ref);
+                               PyType_Modified((PyTypeObject *)ref);
                        }
                }
        }
@@ -172,7 +171,7 @@ assign_version_tag(PyTypeObject *type)
                        Py_INCREF(Py_None);
                }
                /* mark all version tags as invalid */
-               type_modified(&PyBaseObject_Type);
+               PyType_Modified(&PyBaseObject_Type);
                return 1;
        }
        bases = type->tp_bases;
@@ -300,7 +299,7 @@ type_set_module(PyTypeObject *type, PyObject *value, void *context)
                return -1;
        }
 
-       type_modified(type);
+       PyType_Modified(type);
 
        return PyDict_SetItemString(type->tp_dict, "__module__", value);
 }
@@ -328,7 +327,7 @@ type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context)
        int res = PyDict_SetItemString(type->tp_dict,
                                       "__abstractmethods__", value);
        if (res == 0) {
-               type_modified(type);
+               PyType_Modified(type);
                if (value && PyObject_IsTrue(value)) {
                        type->tp_flags |= Py_TPFLAGS_IS_ABSTRACT;
                }
@@ -1621,7 +1620,7 @@ mro_internal(PyTypeObject *type)
           from the custom MRO */
        type_mro_modified(type, type->tp_bases);
 
-       type_modified(type);
+       PyType_Modified(type);
 
        return 0;
 }
@@ -6092,7 +6091,7 @@ update_slot(PyTypeObject *type, PyObject *name)
           update_subclasses() recursion below, but carefully:
           they each have their own conditions on which to stop
           recursing into subclasses. */
-       type_modified(type);
+       PyType_Modified(type);
 
        init_slotdefs();
        pp = ptrs;