[PATCH] Python3 compatible modules - credentials, param, _glue

Stefan Metzmacher metze at samba.org
Wed Feb 22 17:41:11 UTC 2017


Am 21.02.2017 um 23:10 schrieb Andrew Bartlett:
> On Tue, 2017-02-21 at 11:08 +0100, Lumir Balhar wrote:
>>
>> Hello.
>>
>> I completely understand that there are several customers with Python
>> 2.6 
>> and we still have to support them.
>>
>> Patch 12 in the previous patchset [0] was designed to keep Python
>> 2.6 
>> compatibility by redefining PyCapsule_* functions with PyCObject 
>> alternatives which is a simple solution without much impact on
>> pytalloc. 
>> Also, the whole codebase can be developed and maintained with
>> PyCapsule 
>> only which is better for clear code and future maintainability.
>> Then, when we'll decide to drop Python 2.6 support we just need to 
>> delete this macros/function from py3compat.h file and continue with 
>> PyCapsule only.
>> Or we can redesign the API using something like the proposed 
>> pytalloc_GenericObject. However, given our currently limited use of 
>> CObject, I think this would need more discussion about the intended 
>> direction of this API before going to redesign it. CObject currently 
>> works, and PyCapsule is the obvious replacement, so I believe a
>> patchset 
>> for porting to Python 3 should use PyCapsule.
> 
> What more needs to be done.  I think porting fully to PyCapsule with a
> emulation layer is the correct approach, and would avoid the uglier
> changes in the PIDL generated code. 

Sorry, but I disagree. We should avoid using PyCapsule and use
pytalloc_GenericObject. It makes the code much simpler.

I'm currently doing private autobuilds with the attached patchset,
which removes all usage of PyCObject and uses pytalloc_GenericObject
instead.

Please have look, but don't push it yet.

I think we may also backport this to 4.6 as the py_{ex,im}port_union()
framework was new in 4.6 and I think it should be consistent between master
and the production 4.6 release.

metze



-------------- next part --------------
From f766ea044bc10ff21517d7de2c21d07a2746992a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 20 Feb 2017 17:33:42 +0100
Subject: [PATCH 1/6] pytalloc: add
 pytalloc_GenericObject_{steal,reference}[_ex]()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 lib/talloc/ABI/pytalloc-util-2.1.8.sigs     |  3 +
 lib/talloc/ABI/pytalloc-util.py3-2.1.8.sigs |  3 +
 lib/talloc/pytalloc.c                       | 13 ++++
 lib/talloc/pytalloc.h                       | 28 ++++++++-
 lib/talloc/pytalloc_guide.txt               | 73 ++++++++++++++++++++--
 lib/talloc/pytalloc_util.c                  | 95 +++++++++++++++++++++++++++--
 6 files changed, 203 insertions(+), 12 deletions(-)

diff --git a/lib/talloc/ABI/pytalloc-util-2.1.8.sigs b/lib/talloc/ABI/pytalloc-util-2.1.8.sigs
index 666fec0..9d4d4d1 100644
--- a/lib/talloc/ABI/pytalloc-util-2.1.8.sigs
+++ b/lib/talloc/ABI/pytalloc-util-2.1.8.sigs
@@ -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 *)
diff --git a/lib/talloc/ABI/pytalloc-util.py3-2.1.8.sigs b/lib/talloc/ABI/pytalloc-util.py3-2.1.8.sigs
index 4410f11..62f066f 100644
--- a/lib/talloc/ABI/pytalloc-util.py3-2.1.8.sigs
+++ b/lib/talloc/ABI/pytalloc-util.py3-2.1.8.sigs
@@ -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 *)
diff --git a/lib/talloc/pytalloc.c b/lib/talloc/pytalloc.c
index 2039528..3532fdf 100644
--- a/lib/talloc/pytalloc.c
+++ b/lib/talloc/pytalloc.c
@@ -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;
 }
 
diff --git a/lib/talloc/pytalloc.h b/lib/talloc/pytalloc.h
index 6a0ac18..11653bf 100644
--- a/lib/talloc/pytalloc.h
+++ b/lib/talloc/pytalloc.h
@@ -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);
 
diff --git a/lib/talloc/pytalloc_guide.txt b/lib/talloc/pytalloc_guide.txt
index 962d449..bd2b68c 100644
--- a/lib/talloc/pytalloc_guide.txt
+++ b/lib/talloc/pytalloc_guide.txt
@@ -92,6 +92,15 @@ Check whether a specific object is a talloc BaseObject. Returns non-zero if it i
 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)
 
 Retrieve the pointer from a `pytalloc_Object` py_obj. type should be a
@@ -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
 -----------------------------------
diff --git a/lib/talloc/pytalloc_util.c b/lib/talloc/pytalloc_util.c
index cb71dc9..0df6185 100644
--- a/lib/talloc/pytalloc_util.c
+++ b/lib/talloc/pytalloc_util.c
@@ -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 rar 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)) {
-- 
1.9.1


From 8bea2653aab6d1fa0023cfea026a6fe76ff326a0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 22 Feb 2017 08:00:10 +0100
Subject: [PATCH 2/6] TODO talloc: version 2.1.9

---
 lib/talloc/ABI/pytalloc-util-2.1.8.sigs     |  3 --
 lib/talloc/ABI/pytalloc-util-2.1.9.sigs     | 16 +++++++
 lib/talloc/ABI/pytalloc-util.py3-2.1.8.sigs |  3 --
 lib/talloc/ABI/pytalloc-util.py3-2.1.9.sigs | 15 +++++++
 lib/talloc/ABI/talloc-2.1.9.sigs            | 65 +++++++++++++++++++++++++++++
 lib/talloc/wscript                          |  2 +-
 6 files changed, 97 insertions(+), 7 deletions(-)
 create mode 100644 lib/talloc/ABI/pytalloc-util-2.1.9.sigs
 create mode 100644 lib/talloc/ABI/pytalloc-util.py3-2.1.9.sigs
 create mode 100644 lib/talloc/ABI/talloc-2.1.9.sigs

diff --git a/lib/talloc/ABI/pytalloc-util-2.1.8.sigs b/lib/talloc/ABI/pytalloc-util-2.1.8.sigs
index 9d4d4d1..666fec0 100644
--- a/lib/talloc/ABI/pytalloc-util-2.1.8.sigs
+++ b/lib/talloc/ABI/pytalloc-util-2.1.8.sigs
@@ -1,4 +1,3 @@
-_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 *)
@@ -7,8 +6,6 @@ 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 *)
diff --git a/lib/talloc/ABI/pytalloc-util-2.1.9.sigs b/lib/talloc/ABI/pytalloc-util-2.1.9.sigs
new file mode 100644
index 0000000..9d4d4d1
--- /dev/null
+++ b/lib/talloc/ABI/pytalloc-util-2.1.9.sigs
@@ -0,0 +1,16 @@
+_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 *)
+pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *)
+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 *)
+pytalloc_steal: PyObject *(PyTypeObject *, void *)
+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
diff --git a/lib/talloc/ABI/pytalloc-util.py3-2.1.8.sigs b/lib/talloc/ABI/pytalloc-util.py3-2.1.8.sigs
index 62f066f..4410f11 100644
--- a/lib/talloc/ABI/pytalloc-util.py3-2.1.8.sigs
+++ b/lib/talloc/ABI/pytalloc-util.py3-2.1.8.sigs
@@ -1,4 +1,3 @@
-_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,8 +5,6 @@ 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 *)
diff --git a/lib/talloc/ABI/pytalloc-util.py3-2.1.9.sigs b/lib/talloc/ABI/pytalloc-util.py3-2.1.9.sigs
new file mode 100644
index 0000000..62f066f
--- /dev/null
+++ b/lib/talloc/ABI/pytalloc-util.py3-2.1.9.sigs
@@ -0,0 +1,15 @@
+_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 *)
+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 *)
+pytalloc_steal: PyObject *(PyTypeObject *, void *)
+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
diff --git a/lib/talloc/ABI/talloc-2.1.9.sigs b/lib/talloc/ABI/talloc-2.1.9.sigs
new file mode 100644
index 0000000..9969ce3
--- /dev/null
+++ b/lib/talloc/ABI/talloc-2.1.9.sigs
@@ -0,0 +1,65 @@
+_talloc: void *(const void *, size_t)
+_talloc_array: void *(const void *, size_t, unsigned int, const char *)
+_talloc_free: int (void *, const char *)
+_talloc_get_type_abort: void *(const void *, const char *, const char *)
+_talloc_memdup: void *(const void *, const void *, size_t, const char *)
+_talloc_move: void *(const void *, const void *)
+_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t)
+_talloc_realloc: void *(const void *, void *, size_t, const char *)
+_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *)
+_talloc_reference_loc: void *(const void *, const void *, const char *)
+_talloc_set_destructor: void (const void *, int (*)(void *))
+_talloc_steal_loc: void *(const void *, const void *, const char *)
+_talloc_zero: void *(const void *, size_t, const char *)
+_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *)
+talloc_asprintf: char *(const void *, const char *, ...)
+talloc_asprintf_append: char *(char *, const char *, ...)
+talloc_asprintf_append_buffer: char *(char *, const char *, ...)
+talloc_autofree_context: void *(void)
+talloc_check_name: void *(const void *, const char *)
+talloc_disable_null_tracking: void (void)
+talloc_enable_leak_report: void (void)
+talloc_enable_leak_report_full: void (void)
+talloc_enable_null_tracking: void (void)
+talloc_enable_null_tracking_no_autofree: void (void)
+talloc_find_parent_byname: void *(const void *, const char *)
+talloc_free_children: void (void *)
+talloc_get_name: const char *(const void *)
+talloc_get_size: size_t (const void *)
+talloc_increase_ref_count: int (const void *)
+talloc_init: void *(const char *, ...)
+talloc_is_parent: int (const void *, const void *)
+talloc_named: void *(const void *, size_t, const char *, ...)
+talloc_named_const: void *(const void *, size_t, const char *)
+talloc_parent: void *(const void *)
+talloc_parent_name: const char *(const void *)
+talloc_pool: void *(const void *, size_t)
+talloc_realloc_fn: void *(const void *, void *, size_t)
+talloc_reference_count: size_t (const void *)
+talloc_reparent: void *(const void *, const void *, const void *)
+talloc_report: void (const void *, FILE *)
+talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *)
+talloc_report_depth_file: void (const void *, int, int, FILE *)
+talloc_report_full: void (const void *, FILE *)
+talloc_set_abort_fn: void (void (*)(const char *))
+talloc_set_log_fn: void (void (*)(const char *))
+talloc_set_log_stderr: void (void)
+talloc_set_memlimit: int (const void *, size_t)
+talloc_set_name: const char *(const void *, const char *, ...)
+talloc_set_name_const: void (const void *, const char *)
+talloc_show_parents: void (const void *, FILE *)
+talloc_strdup: char *(const void *, const char *)
+talloc_strdup_append: char *(char *, const char *)
+talloc_strdup_append_buffer: char *(char *, const char *)
+talloc_strndup: char *(const void *, const char *, size_t)
+talloc_strndup_append: char *(char *, const char *, size_t)
+talloc_strndup_append_buffer: char *(char *, const char *, size_t)
+talloc_test_get_magic: int (void)
+talloc_total_blocks: size_t (const void *)
+talloc_total_size: size_t (const void *)
+talloc_unlink: int (const void *, void *)
+talloc_vasprintf: char *(const void *, const char *, va_list)
+talloc_vasprintf_append: char *(char *, const char *, va_list)
+talloc_vasprintf_append_buffer: char *(char *, const char *, va_list)
+talloc_version_major: int (void)
+talloc_version_minor: int (void)
diff --git a/lib/talloc/wscript b/lib/talloc/wscript
index d77de26..7f9bad7 100644
--- a/lib/talloc/wscript
+++ b/lib/talloc/wscript
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 APPNAME = 'talloc'
-VERSION = '2.1.8'
+VERSION = '2.1.9'
 
 
 blddir = 'bin'
-- 
1.9.1


From 062218fd286e5f245f34d58042f59d0ba2a9e875 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 22 Feb 2017 10:14:10 +0100
Subject: [PATCH 3/6] py_net: make use of pytalloc_GenericObject_steal()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/libnet/py_net.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/source4/libnet/py_net.c b/source4/libnet/py_net.c
index 3e70c79..5180c24 100644
--- a/source4/libnet/py_net.c
+++ b/source4/libnet/py_net.c
@@ -457,7 +457,7 @@ static PyObject *py_net_replicate_init(py_net_Object *self, PyObject *args, PyOb
 	s->chunk.forest = &s->forest;
 	s->chunk.dest_dsa = &s->dest_dsa;
 
-	return pytalloc_CObject_FromTallocPtr(s);
+	return pytalloc_GenericObject_steal(s);
 }
 
 
@@ -485,9 +485,8 @@ static PyObject *py_net_replicate_chunk(py_net_Object *self, PyObject *args, PyO
 		return NULL;
 	}
 
-	s = talloc_get_type(PyCObject_AsVoidPtr(py_state), struct replicate_state);
+	s = pytalloc_get_type(py_state, struct replicate_state);
 	if (!s) {
-		PyErr_SetString(PyExc_TypeError, "Expected replication_state");
 		return NULL;
 	}
 
-- 
1.9.1


From c444efa4a397958b40df85d10893ae71c5d12cb0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 22 Feb 2017 10:08:46 +0100
Subject: [PATCH 4/6] pidl:Python: make sure print HASH references for STRUCT
 types

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 pidl/lib/Parse/Pidl/Samba4/Python.pm | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 5edf96c..41b50e4 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -245,12 +245,18 @@ sub PythonStruct($$$$$$)
 		$self->pidl("static PyGetSetDef ".$getsetters."[] = {");
 		$self->indent;
 		foreach my $e (@{$d->{ELEMENTS}}) {
+			my $etype = "";
+			if (ref($e->{TYPE}) eq "HASH") {
+				$etype = $e->{TYPE}->{NAME};
+			} else {
+				$etype = $e->{TYPE};
+			}
 			$self->pidl("{");
 			$self->indent;
 			$self->pidl(".name = discard_const_p(char, \"$e->{NAME}\"),");
 			$self->pidl(".get = py_$name\_get_$e->{NAME},");
 			$self->pidl(".set = py_$name\_set_$e->{NAME},");
-			$self->pidl(".doc = discard_const_p(char, \"PIDL-generated element of base type $e->{TYPE}\")");
+			$self->pidl(".doc = discard_const_p(char, \"PIDL-generated element of base type $etype\")");
 			$self->deindent;
 			$self->pidl("},");
 		}
-- 
1.9.1


From 4ba2f8c3d50f96cfc52ed232fbb5298111f4b6a5 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 22 Feb 2017 09:07:54 +0100
Subject: [PATCH 5/6] pidl:Python: replace pytalloc_CObject_FromTallocPtr()
 with pytalloc_GenericObject_reference_ex()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 pidl/lib/Parse/Pidl/Samba4/Python.pm | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 41b50e4..e7b127d 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -1933,12 +1933,12 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
 	}
 
 	if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") {
-		$self->pidl("$target = PyCObject_AsVoidPtr($cvar);");
+		$self->pidl("$target = pytalloc_get_ptr($cvar);");
 		return;
 	}
 
 	if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") {
-		$self->assign($target, "PyCObject_AsVoidPtr($cvar)");
+		$self->assign($target, "pytalloc_get_ptr($cvar)");
 		return;
 	}
 
@@ -2070,9 +2070,9 @@ sub ConvertObjectFromPython($$$$$$$)
 	$self->ConvertObjectFromPythonLevel($env, $mem_ctx, $cvar, $ctype, $ctype->{LEVELS}[0], $target, $fail);
 }
 
-sub ConvertScalarToPython($$$)
+sub ConvertScalarToPython($$$$)
 {
-	my ($self, $ctypename, $cvar) = @_;
+	my ($self, $ctypename, $cvar, $mem_ctx) = @_;
 
 	die("expected string for $cvar, not $ctypename") if (ref($ctypename) eq "HASH");
 
@@ -2127,13 +2127,15 @@ sub ConvertScalarToPython($$$)
 	}
 
 	# Not yet supported
-	if ($ctypename eq "string_array") { return "pytalloc_CObject_FromTallocPtr($cvar)"; }
+	if ($ctypename eq "string_array") {
+		return "pytalloc_GenericObject_reference_ex($mem_ctx, $cvar)";
+	}
 	if ($ctypename eq "ipv4address") { return "PyString_FromStringOrNULL($cvar)"; }
 	if ($ctypename eq "ipv6address") { return "PyString_FromStringOrNULL($cvar)"; }
 	if ($ctypename eq "dnsp_name") { return "PyString_FromStringOrNULL($cvar)"; }
 	if ($ctypename eq "dnsp_string") { return "PyString_FromStringOrNULL($cvar)"; }
 	if ($ctypename eq "pointer") {
-		return "pytalloc_CObject_FromTallocPtr($cvar)";
+		return "pytalloc_GenericObject_reference_ex($mem_ctx, $cvar)";
 	}
 
 	die("Unknown scalar type $ctypename");
@@ -2153,11 +2155,11 @@ sub ConvertObjectToPythonData($$$$$;$$)
 	}
 
 	if ($actual_ctype->{TYPE} eq "ENUM") {
-		return $self->ConvertScalarToPython(Parse::Pidl::Typelist::enum_type_fn($actual_ctype), $cvar);
+		return $self->ConvertScalarToPython(Parse::Pidl::Typelist::enum_type_fn($actual_ctype), $cvar, $mem_ctx);
 	} elsif ($actual_ctype->{TYPE} eq "BITMAP") {
-		return $self->ConvertScalarToPython(Parse::Pidl::Typelist::bitmap_type_fn($actual_ctype), $cvar);
+		return $self->ConvertScalarToPython(Parse::Pidl::Typelist::bitmap_type_fn($actual_ctype), $cvar, $mem_ctx);
 	} elsif ($actual_ctype->{TYPE} eq "SCALAR") {
-		return $self->ConvertScalarToPython($actual_ctype->{NAME}, $cvar);
+		return $self->ConvertScalarToPython($actual_ctype->{NAME}, $cvar, $mem_ctx);
 	} elsif ($actual_ctype->{TYPE} eq "UNION") {
 		my $ctype_name = $self->use_type_variable($ctype);
 		unless (defined($ctype_name)) {
-- 
1.9.1


From fb31d70a3b4371ae02a287cef4f6e907835c03a0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 20 Feb 2017 18:02:09 +0100
Subject: [PATCH 6/6] pidl:Python: use of pytalloc_GenericObject_reference*()
 for pyrpc_{ex,im}port_union() wrapping

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 pidl/lib/Parse/Pidl/Samba4/Python.pm | 85 +++---------------------------------
 source4/librpc/rpc/pyrpc_util.c      | 44 ++-----------------
 2 files changed, 11 insertions(+), 118 deletions(-)

diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index e7b127d..f871e04 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -1181,29 +1181,15 @@ sub PythonType($$$$)
 		my $py_methods = "NULL";
 		my $typename = mapTypeName($d);
 
-		##
-		## PyCapsule (starting with 2.7) vs. PyCObject (up to 3.2)
-		##
-		## As we need to support python 2.6, we can't use PyCapsule yet.
-		##
-		## When we'll get support fpr Python3 we'll have to emulate
-		## PyCObject using PyCapsule and convert these functions to
-		## use PyCapsule.
-		##
 		$self->pidl("static PyObject *py_$d->{NAME}\_import(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
 		$self->pidl("{");
 		$self->indent;
 		$self->pidl("const char * const kwnames[] = { \"mem_ctx\", \"level\", \"in\", NULL };");
 		$self->pidl("PyObject *mem_ctx_obj = NULL;");
-		$self->pidl("static const char *mem_ctx_type = \"TALLOC_CTX\";");
-		$self->pidl("const char *mem_ctx_desc = NULL;");
 		$self->pidl("TALLOC_CTX *mem_ctx = NULL;");
 		$self->pidl("int level = 0;");
 		$self->pidl("PyObject *in_obj = NULL;");
-		$self->pidl("static const char *in_type = \"$typename\";");
-		$self->pidl("const char *in_desc = NULL;");
 		$self->pidl("$typename *in = NULL;");
-		$self->pidl("int cmp;");
 		$self->pidl("");
 		$self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"OiO:import\",");
 		$self->indent;
@@ -1216,54 +1202,20 @@ sub PythonType($$$$)
 		$self->pidl("return NULL;");
 		$self->deindent;
 		$self->pidl("}");
-		$self->pidl("if (!PyCObject_Check(mem_ctx_obj)) {");
-		$self->indent;
-		$self->pidl("PyErr_SetString(PyExc_TypeError, \"mem_ctx needs to be of type PyCObject!\");");
-		$self->pidl("return NULL;");
-		$self->deindent;
-		$self->pidl("}");
-		$self->pidl("mem_ctx_desc = (const char *)PyCObject_GetDesc(mem_ctx_obj);");
-		$self->indent;
-		$self->pidl("if (mem_ctx_desc == NULL) {");
-		$self->pidl("PyErr_SetString(PyExc_TypeError, \"mem_ctx hash no PyCObject_GetDesc()!\");");
-		$self->pidl("return NULL;");
-		$self->deindent;
-		$self->pidl("}");
-		$self->pidl("cmp = strncmp(mem_ctx_type, mem_ctx_desc, strlen(mem_ctx_type) + 1);");
-		$self->pidl("if (cmp != 0) {");
-		$self->indent;
-		$self->pidl("PyErr_Format(PyExc_TypeError, \"mem_ctx should have PyCObject_GetDesc() = %s!\", mem_ctx_type);");
-		$self->pidl("return NULL;");
-		$self->deindent;
-		$self->pidl("}");
-		$self->pidl("mem_ctx = PyCObject_AsVoidPtr(mem_ctx_obj);");
+		$self->pidl("mem_ctx = pytalloc_get_ptr(mem_ctx_obj);");
 		$self->pidl("if (mem_ctx == NULL) {");
 		$self->indent;
 		$self->pidl("PyErr_SetString(PyExc_TypeError, \"mem_ctx is NULL)!\");");
 		$self->pidl("return NULL;");
 		$self->deindent;
 		$self->pidl("}");
-		$self->pidl("if (!PyCObject_Check(in_obj)) {");
-		$self->indent;
-		$self->pidl("PyErr_SetString(PyExc_TypeError, \"in needs to be of type PyCObject!\");");
-		$self->pidl("return NULL;");
-		$self->deindent;
-		$self->pidl("}");
-		$self->pidl("in_desc = (const char *)PyCObject_GetDesc(in_obj);");
+		$self->pidl("in = ($typename *)pytalloc_get_ptr(in_obj);");
+		$self->pidl("if (in == NULL) {");
 		$self->indent;
-		$self->pidl("if (in_desc == NULL) {");
-		$self->pidl("PyErr_SetString(PyExc_TypeError, \"in hash no PyCObject_GetDesc()!\");");
+		$self->pidl("PyErr_Format(PyExc_TypeError, \"in needs to be a pointer to $typename!\");");
 		$self->pidl("return NULL;");
 		$self->deindent;
 		$self->pidl("}");
-		$self->pidl("cmp = strncmp(in_type, in_desc, strlen(in_type) + 1);");
-		$self->pidl("if (cmp != 0) {");
-		$self->indent;
-		$self->pidl("PyErr_Format(PyExc_TypeError, \"in should have PyCObject_GetDesc() = %s!\", in_type);");
-		$self->pidl("return NULL;");
-		$self->deindent;
-		$self->pidl("}");
-		$self->pidl("in = ($typename *)PyCObject_AsVoidPtr(in_obj);");
 		$self->pidl("");
 		$self->pidl("return py_import_$d->{NAME}(mem_ctx, level, in);");
 		$self->deindent;
@@ -1275,14 +1227,10 @@ sub PythonType($$$$)
 		$self->indent;
 		$self->pidl("const char * const kwnames[] = { \"mem_ctx\", \"level\", \"in\", NULL };");
 		$self->pidl("PyObject *mem_ctx_obj = NULL;");
-		$self->pidl("static const char *mem_ctx_type = \"TALLOC_CTX\";");
-		$self->pidl("const char *mem_ctx_desc = NULL;");
 		$self->pidl("TALLOC_CTX *mem_ctx = NULL;");
 		$self->pidl("int level = 0;");
 		$self->pidl("PyObject *in = NULL;");
-		$self->pidl("static const char *out_type = \"$typename\";");
 		$self->pidl("$typename *out = NULL;");
-		$self->pidl("int cmp;");
 		$self->pidl("");
 		$self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"OiO:import\",");
 		$self->indent;
@@ -1295,27 +1243,7 @@ sub PythonType($$$$)
 		$self->pidl("return NULL;");
 		$self->deindent;
 		$self->pidl("}");
-		$self->pidl("if (!PyCObject_Check(mem_ctx_obj)) {");
-		$self->indent;
-		$self->pidl("PyErr_SetString(PyExc_TypeError, \"mem_ctx needs to be of type PyCObject!\");");
-		$self->pidl("return NULL;");
-		$self->deindent;
-		$self->pidl("}");
-		$self->pidl("mem_ctx_desc = (const char *)PyCObject_GetDesc(mem_ctx_obj);");
-		$self->indent;
-		$self->pidl("if (mem_ctx_desc == NULL) {");
-		$self->pidl("PyErr_SetString(PyExc_TypeError, \"mem_ctx hash no PyCObject_GetDesc()!\");");
-		$self->pidl("return NULL;");
-		$self->deindent;
-		$self->pidl("}");
-		$self->pidl("cmp = strncmp(mem_ctx_type, mem_ctx_desc, strlen(mem_ctx_type) + 1);");
-		$self->pidl("if (cmp != 0) {");
-		$self->indent;
-		$self->pidl("PyErr_Format(PyExc_TypeError, \"mem_ctx should have PyCObject_GetDesc() = %s!\", mem_ctx_type);");
-		$self->pidl("return NULL;");
-		$self->deindent;
-		$self->pidl("}");
-		$self->pidl("mem_ctx = PyCObject_AsVoidPtr(mem_ctx_obj);");
+		$self->pidl("mem_ctx = pytalloc_get_ptr(mem_ctx_obj);");
 		$self->pidl("if (mem_ctx == NULL) {");
 		$self->indent;
 		$self->pidl("PyErr_SetString(PyExc_TypeError, \"mem_ctx is NULL)!\");");
@@ -1329,7 +1257,8 @@ sub PythonType($$$$)
 		$self->pidl("return NULL;");
 		$self->deindent;
 		$self->pidl("}");
-		$self->pidl("return PyCObject_FromVoidPtrAndDesc(out, discard_const_p(char, out_type), NULL);");
+		$self->pidl("");
+		$self->pidl("return pytalloc_GenericObject_reference(out);");
 		$self->deindent;
 		$self->pidl("}");
 		$self->pidl("");
diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c
index cfbb9cb..fe0e2de 100644
--- a/source4/librpc/rpc/pyrpc_util.c
+++ b/source4/librpc/rpc/pyrpc_util.c
@@ -394,21 +394,16 @@ PyObject *PyString_FromStringOrNULL(const char *str)
 PyObject *pyrpc_import_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level,
 			     const void *in, const char *typename)
 {
-	static const char *mem_ctx_type = "TALLOC_CTX";
 	PyObject *mem_ctx_obj = NULL;
 	PyObject *in_obj = NULL;
 	PyObject *ret = NULL;
 
-	mem_ctx_obj = PyCObject_FromVoidPtrAndDesc(mem_ctx,
-					discard_const_p(char, mem_ctx_type),
-					NULL);
+	mem_ctx_obj = pytalloc_GenericObject_reference(mem_ctx);
 	if (mem_ctx_obj == NULL) {
 		return NULL;
 	}
 
-	in_obj = PyCObject_FromVoidPtrAndDesc(discard_const(in),
-					discard_const_p(char, typename),
-					NULL);
+	in_obj = pytalloc_GenericObject_reference_ex(mem_ctx, discard_const(in));
 	if (in_obj == NULL) {
 		Py_XDECREF(mem_ctx_obj);
 		return NULL;
@@ -430,16 +425,11 @@ PyObject *pyrpc_import_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level,
 void *pyrpc_export_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level,
 			 PyObject *in, const char *typename)
 {
-	static const char *mem_ctx_type = "TALLOC_CTX";
 	PyObject *mem_ctx_obj = NULL;
 	PyObject *ret_obj = NULL;
-	const char *ret_desc = NULL;
 	void *ret = NULL;
-	int cmp;
 
-	mem_ctx_obj = PyCObject_FromVoidPtrAndDesc(mem_ctx,
-					discard_const_p(char, mem_ctx_type),
-					NULL);
+	mem_ctx_obj = pytalloc_GenericObject_reference(mem_ctx);
 	if (mem_ctx_obj == NULL) {
 		return NULL;
 	}
@@ -453,33 +443,7 @@ void *pyrpc_export_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level,
 		return NULL;
 	}
 
-	if (!PyCObject_Check(ret_obj)) {
-		Py_XDECREF(ret_obj);
-		PyErr_Format(PyExc_TypeError,
-			     "New %s.__export__() returned no PyCObject!",
-			     type->tp_name);
-		return NULL;
-	}
-
-	ret_desc = (const char *)PyCObject_GetDesc(ret_obj);
-	if (ret_desc == NULL) {
-		Py_XDECREF(ret_obj);
-		PyErr_Format(PyExc_TypeError,
-			     "New %s.__export__() returned no PyCObject_GetDesc()!",
-			     type->tp_name);
-		return NULL;
-	}
-
-	cmp = strncmp(typename, ret_desc, strlen(typename) + 1);
-	if (cmp != 0) {
-		Py_XDECREF(ret_obj);
-		PyErr_Format(PyExc_TypeError,
-			     "New %s.__export__() returned PyCObject_GetDesc() != %s!",
-			     type->tp_name, typename);
-		return NULL;
-	}
-
-	ret = PyCObject_AsVoidPtr(ret_obj);
+	ret = _pytalloc_get_type(ret_obj, typename);
 	Py_XDECREF(ret_obj);
 	return ret;
 }
-- 
1.9.1

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20170222/886809ea/signature.sig>


More information about the samba-technical mailing list