]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
pytalloc: add pytalloc_GenericObject_{steal,reference}[_ex]()
authorStefan Metzmacher <metze@samba.org>
Mon, 20 Feb 2017 16:33:42 +0000 (17:33 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 25 Feb 2017 01:39:11 +0000 (02:39 +0100)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/talloc/ABI/pytalloc-util-2.1.8.sigs
lib/talloc/ABI/pytalloc-util.py3-2.1.8.sigs
lib/talloc/pytalloc.c
lib/talloc/pytalloc.h
lib/talloc/pytalloc_guide.txt
lib/talloc/pytalloc_util.c

index 666fec047f5fffbaa78b9727efb05d6bd2c3936f..9d4d4d142c88bc9ad2b2a764abdab621f50950de 100644 (file)
@@ -1,3 +1,4 @@
+_pytalloc_check_type: int (PyObject *, const char *)
 _pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *)
 _pytalloc_get_ptr: void *(PyObject *)
 _pytalloc_get_type: void *(PyObject *, const char *)
@@ -6,6 +7,8 @@ pytalloc_BaseObject_check: int (PyObject *)
 pytalloc_BaseObject_size: size_t (void)
 pytalloc_CObject_FromTallocPtr: PyObject *(void *)
 pytalloc_Check: int (PyObject *)
+pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *)
+pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *)
 pytalloc_GetBaseObjectType: PyTypeObject *(void)
 pytalloc_GetObjectType: PyTypeObject *(void)
 pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
index 4410f110cb299ef5eaaeac54d43c5712d6beeb98..62f066f7d5f5f8e4139c5a56926ed141500bbc0b 100644 (file)
@@ -1,3 +1,4 @@
+_pytalloc_check_type: int (PyObject *, const char *)
 _pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *)
 _pytalloc_get_ptr: void *(PyObject *)
 _pytalloc_get_type: void *(PyObject *, const char *)
@@ -5,6 +6,8 @@ pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *)
 pytalloc_BaseObject_check: int (PyObject *)
 pytalloc_BaseObject_size: size_t (void)
 pytalloc_Check: int (PyObject *)
+pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *)
+pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *)
 pytalloc_GetBaseObjectType: PyTypeObject *(void)
 pytalloc_GetObjectType: PyTypeObject *(void)
 pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
index 2039528a08f6cd748ae049513ee5f17f4491b088..3532fdf529149ed636b6de351b210f0734f46d92 100644 (file)
@@ -238,6 +238,14 @@ static PyTypeObject TallocBaseObject_Type = {
 #endif
 };
 
+static PyTypeObject TallocGenericObject_Type = {
+       .tp_name = "talloc.GenericObject",
+       .tp_doc = "Python wrapper for a talloc-maintained object.",
+       .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+       .tp_base = &TallocBaseObject_Type,
+       .tp_basicsize = sizeof(pytalloc_BaseObject),
+};
+
 #define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.")
 
 #if PY_MAJOR_VERSION >= 3
@@ -261,6 +269,9 @@ static PyObject *module_init(void)
        if (PyType_Ready(&TallocBaseObject_Type) < 0)
                return NULL;
 
+       if (PyType_Ready(&TallocGenericObject_Type) < 0)
+               return NULL;
+
 #if PY_MAJOR_VERSION >= 3
        m = PyModule_Create(&moduledef);
 #else
@@ -273,6 +284,8 @@ static PyObject *module_init(void)
        PyModule_AddObject(m, "Object", (PyObject *)&TallocObject_Type);
        Py_INCREF(&TallocBaseObject_Type);
        PyModule_AddObject(m, "BaseObject", (PyObject *)&TallocBaseObject_Type);
+       Py_INCREF(&TallocGenericObject_Type);
+       PyModule_AddObject(m, "GenericObject", (PyObject *)&TallocGenericObject_Type);
        return m;
 }
 
index 6a0ac187288c8cca63fdb0e29c028af8fa1bb122..11653bf64cff894b007e6f7f6c8ce0f6e1dcd2e4 100644 (file)
@@ -40,6 +40,10 @@ int pytalloc_Check(PyObject *);
 
 int pytalloc_BaseObject_check(PyObject *);
 
+int _pytalloc_check_type(PyObject *py_obj, const char *type_name);
+#define pytalloc_check_type(py_obj, type) \
+       _pytalloc_check_type((PyObject *)(py_obj), #type)
+
 /* Retrieve the pointer for a pytalloc_object. Like talloc_get_type() 
  * but for pytalloc_Objects. */
 void *_pytalloc_get_type(PyObject *py_obj, const char *type_name);
@@ -58,8 +62,30 @@ PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void
 #define pytalloc_new(type, typeobj) pytalloc_steal(typeobj, talloc_zero(NULL, type))
 
 #if PY_MAJOR_VERSION < 3
-PyObject *pytalloc_CObject_FromTallocPtr(void *);
+/*
+ * Don't use this anymore! Use pytalloc_GenericObject_steal()
+ * or pytalloc_GenericObject_reference().
+ */
+#ifndef _DEPRECATED_
+#ifdef HAVE___ATTRIBUTE__
+#define _DEPRECATED_ __attribute__ ((deprecated))
+#else
+#define _DEPRECATED_
+#endif
 #endif
+PyObject *pytalloc_CObject_FromTallocPtr(void *) _DEPRECATED_;
+#endif
+
+/*
+ * Wrap a generic talloc pointer into a talloc.GenericObject,
+ * this is a subclass of talloc.BaseObject.
+ */
+PyObject *pytalloc_GenericObject_steal_ex(TALLOC_CTX *mem_ctx, void *ptr);
+#define pytalloc_GenericObject_steal(talloc_ptr) \
+       pytalloc_GenericObject_steal_ex(talloc_ptr, talloc_ptr)
+PyObject *pytalloc_GenericObject_reference_ex(TALLOC_CTX *mem_ctx, void *ptr);
+#define pytalloc_GenericObject_reference(talloc_ptr) \
+       pytalloc_GenericObject_reference_ex(talloc_ptr, talloc_ptr)
 
 size_t pytalloc_BaseObject_size(void);
 
index 962d44933ba2b45fa51688d842c4592c3ab09b61..bd2b68c0213db80563f60ab39d9742934b0983b2 100644 (file)
@@ -91,6 +91,15 @@ int pytalloc_BaseObject_Check(PyObject *)
 Check whether a specific object is a talloc BaseObject. Returns non-zero if it is
 a pytalloc_BaseObject and zero otherwise.
 
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+int pytalloc_check_type(PyObject *py_obj, type)
+
+Check if the object based on `pytalloc_*Object` py_obj. type should be a
+C type, similar to a type passed to `talloc_get_type`.
+This can be used as a check before using pytalloc_get_type()
+or an alternative codepath. Returns non-zero if it is
+an object of the expected type and zero otherwise.
+
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 type *pytalloc_get_type(PyObject *py_obj, type)
 
@@ -113,7 +122,9 @@ Retrieve the talloc context associated with a pytalloc_Object or pytalloc_BaseOb
 PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr)
 
 Create a new Python wrapping object for a talloc pointer and context, with
-py_type as associated Python sub type object.
+py_type as associated Python sub type object. This typically used
+when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element.
+`pytalloc_get_ptr()` can be used to get the pointer out of the object again.
 
 This will *not* increment the reference counter for the talloc context,
 so the caller should make sure such an increment has happened. When the Python
@@ -123,7 +134,9 @@ object goes away, it will unreference the talloc context.
 PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr)
 
 Create a new Python wrapping object for a talloc pointer and context, with
-py_type as associated Python sub type object.
+py_type as associated Python sub type object. The pointer will also be used
+as the talloc context. `pytalloc_get_type()` can be used to get
+the pointer out of the object again.
 
 This will *not* increment the reference counter for the talloc context,
 so the caller should make sure such an increment has happened. When the Python
@@ -133,7 +146,9 @@ object goes away, it will unreference the talloc context.
 PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr)
 
 Create a new Python wrapping object for a talloc pointer and context, with
-py_type as associated Python sub type object.
+py_type as associated Python sub type object. This typically used
+when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element.
+`pytalloc_get_ptr()` can be used to get the pointer out of the object again.
 
 This will increment the reference counter for the talloc context.
 
@@ -142,7 +157,8 @@ PyObject *pytalloc_reference(PyTypeObject *py_type, void *talloc_ptr)
 
 Create a new Python wrapping object for a talloc pointer, with
 py_type as associated Python sub type object. The pointer will also be used
-as the talloc context.
+as the talloc context. `pytalloc_get_type()` can be used to get
+the pointer out of the object again.
 
 This will increment the reference counter for the talloc context.
 
@@ -153,14 +169,59 @@ Create a new, empty pytalloc_Object with the specified Python type object. type
 should be a C type, similar to talloc_new().
 
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-PyObject *pytalloc_CObject_FromTallocPtr(void *);
+PyObject *pytalloc_GenericObject_steal_ex(void *ptr)
+
+Create a new Python wrapping object for a generic talloc pointer,
+as sub type of `pytalloc_BaseObject`. This typically used
+when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element.
+`pytalloc_get_ptr()` can be used to get the pointer out of the object again.
+
+This will *not* increment the reference counter for the talloc context,
+so the caller should make sure such an increment has happened. When the Python
+object goes away, it will unreference the talloc context.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+PyObject *pytalloc_GenericObject_steal(void *ptr)
+
+Create a new Python wrapping object for a generic talloc pointer,
+as sub type of `pytalloc_BaseObject`. The pointer will also be used
+as the talloc context. `pytalloc_get_type()` can be used to get
+the pointer out of the object again.
+
+This will *not* increment the reference counter for the talloc context,
+so the caller should make sure such an increment has happened. When the Python
+object goes away, it will unreference the talloc context.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+PyObject *pytalloc_GenericObject_reference_ex(void *ptr)
+
+Create a new Python wrapping object for a generic talloc pointer,
+as sub type of `pytalloc_BaseObject`. This typically used
+when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element.
+`pytalloc_get_ptr()` can be used to get the pointer out of the object again.
+
+This will increment the reference counter for the talloc context.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+PyObject *pytalloc_GenericObject_reference(void *ptr)
+
+Create a new Python wrapping object for a generic talloc pointer,
+as sub type of `pytalloc_BaseObject`. The pointer will also be used
+as the talloc context. `pytalloc_get_type()` can be used to get
+the pointer out of the object again.
+
+This will increment the reference counter for the talloc context.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+DEPRECATED! PyObject *pytalloc_CObject_FromTallocPtr(void *);
 
 Create a new pytalloc_Object for an abitrary talloc-maintained C pointer. This will
 use a generic VoidPtr Python type, which just provides an opaque object in
 Python. The caller is responsible for incrementing the talloc reference count before calling
 this function - it will dereference the talloc pointer when it is garbage collected.
 
-This function is only available on Python 2.
+This function is deprecated and only available on Python 2.
+Use pytalloc_GenericObject_{reference,steal}[_ex]() instead.
 
 Debug function for talloc in Python
 -----------------------------------
index cb71dc975ccf65e77c0c0a87e344d0b4ebca9384..923fe5d634fd0c5f30c574fc06e3dc8788394ea7 100644 (file)
@@ -64,6 +64,26 @@ _PUBLIC_ PyTypeObject *pytalloc_GetBaseObjectType(void)
        return type;
 }
 
+static PyTypeObject *pytalloc_GetGenericObjectType(void)
+{
+       static PyTypeObject *type = NULL;
+       PyObject *mod;
+
+       if (type != NULL) {
+               return type;
+       }
+
+       mod = PyImport_ImportModule("talloc");
+       if (mod == NULL) {
+               return NULL;
+       }
+
+       type = (PyTypeObject *)PyObject_GetAttrString(mod, "GenericObject");
+       Py_DECREF(mod);
+
+       return type;
+}
+
 /**
  * Import an existing talloc pointer into a Python object.
  */
@@ -204,6 +224,26 @@ _PUBLIC_ PyObject *pytalloc_CObject_FromTallocPtr(void *ptr)
 
 #endif
 
+/*
+ * Wrap a generic talloc pointer into a talloc.GenericObject,
+ * this is a subclass of talloc.BaseObject.
+ */
+_PUBLIC_ PyObject *pytalloc_GenericObject_steal_ex(TALLOC_CTX *mem_ctx, void *ptr)
+{
+       PyTypeObject *tp = pytalloc_GetGenericObjectType();
+       return pytalloc_steal_ex(tp, mem_ctx, ptr);
+}
+
+/*
+ * Wrap a generic talloc pointer into a talloc.GenericObject,
+ * this is a subclass of talloc.BaseObject.
+ */
+_PUBLIC_ PyObject *pytalloc_GenericObject_reference_ex(TALLOC_CTX *mem_ctx, void *ptr)
+{
+       PyTypeObject *tp = pytalloc_GetGenericObjectType();
+       return pytalloc_reference_ex(tp, mem_ctx, ptr);
+}
+
 _PUBLIC_ int pytalloc_Check(PyObject *obj)
 {
        PyTypeObject *tp = pytalloc_GetObjectType();
@@ -223,21 +263,66 @@ _PUBLIC_ size_t pytalloc_BaseObject_size(void)
        return sizeof(pytalloc_BaseObject);
 }
 
-_PUBLIC_ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name)
+static void *_pytalloc_get_checked_type(PyObject *py_obj, const char *type_name,
+                                       bool check_only, const char *function)
 {
-       void *ptr = _pytalloc_get_ptr(py_obj);
+       TALLOC_CTX *mem_ctx;
+       void *ptr = NULL;
        void *type_obj = talloc_check_name(ptr, type_name);
 
+       mem_ctx = _pytalloc_get_mem_ctx(py_obj);
+       ptr = _pytalloc_get_ptr(py_obj);
+
+       if (mem_ctx != ptr) {
+               if (check_only) {
+                       return NULL;
+               }
+
+               PyErr_Format(PyExc_TypeError, "%s: expected %s, "
+                            "but the pointer is no talloc pointer, "
+                            "pytalloc_get_ptr() would get the raw pointer.",
+                            function, type_name);
+               return NULL;
+       }
+
+       type_obj = talloc_check_name(ptr, type_name);
        if (type_obj == NULL) {
-               const char *name = talloc_get_name(ptr);
-               PyErr_Format(PyExc_TypeError, "pytalloc: expected %s, got %s",
-                            type_name, name);
+               const char *name = NULL;
+
+               if (check_only) {
+                       return NULL;
+               }
+
+               name = talloc_get_name(ptr);
+               PyErr_Format(PyExc_TypeError, "%s: expected %s, got %s",
+                            function, type_name, name);
                return NULL;
        }
 
        return ptr;
 }
 
+_PUBLIC_ int _pytalloc_check_type(PyObject *py_obj, const char *type_name)
+{
+       void *ptr = NULL;
+
+       ptr = _pytalloc_get_checked_type(py_obj, type_name,
+                                        true, /* check_only */
+                                        "pytalloc_check_type");
+       if (ptr == NULL) {
+               return 0;
+       }
+
+       return 1;
+}
+
+_PUBLIC_ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name)
+{
+       return _pytalloc_get_checked_type(py_obj, type_name,
+                                         false, /* not check_only */
+                                         "pytalloc_get_type");
+}
+
 _PUBLIC_ void *_pytalloc_get_ptr(PyObject *py_obj)
 {
        if (pytalloc_BaseObject_check(py_obj)) {