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

Stefan Metzmacher metze at samba.org
Mon Feb 20 17:04:42 UTC 2017


Hi,

I think the attached patches are a start for what we want.

metze

Am 20.02.2017 um 16:21 schrieb Stefan Metzmacher:
> Am 20.02.2017 um 16:09 schrieb Stefan Metzmacher:
>> Hi Andrew,
>>
>>> So we can at least have a public record of your thoughts (because I
>>> respect them greatly) I would like to understand your reasoning here.
>>>
>>> Why, in your view, is it important that we support RHEL6 with Samba 4.7
>>> as an AD DC?  
>>
>> I'll have to check but there might be some SetNet customers using
>> our packages on RHEL/CentOS 6.
>>
>>> I say as an AD DC, because I see an opportunity here to merge the --
>>> disable-python patches at the same time, allowing the file server
>>> production build to avoid python for now and so buy us some time.
>>>
>>> Would your view change if the --disable-python patches were included?
>>
>> No, that won't help.
>>
>> My main point is that it is not reasonable for me to drop python 2.6
>> support just because of the lack of PyCapsule!
>>
>> With our limited usage of PyCObject it should be easy to work around
>> the python 2.6 limitations!
>>
>> Either like this
>> https://lists.samba.org/archive/samba-technical/2017-February/118604.html
>> or the following:
>>
>> Regarding pytalloc_CObject_FromTallocPtr() I think we need an improvement
>> anyway, because pytalloc_CObject_FromTallocPtr is not a symmetric api.
>> We can just leave it in place as it already is only available for python2.
>>
>> What we really want is something like this:
>>
>> PyObject *pytalloc_PointerObject_FromTallocPtr(const void *ptr);
>> void *_pytalloc_PointerObject_AsTallocPtr(PyObject *self, const char *name);
>> #define pytalloc_PointerObject_AsTallocPtr(self, type) \
>> 	_pytalloc_PointerObject_AsTallocPtr(self, #type)
>> int pytalloc_PointerObject_check(PyObject *self);
>> int _pytalloc_PointerObject_checkType(Pyobject *self, type) \
>> #define pytalloc_PointerObject_checkType(self, #type)
>>
>> pytalloc_PointerObject should be able to be based on pytalloc_BaseObject.
> 
> Instead we could also make it simpler by using pytalloc_BaseObject
> directly, just:
> 
>   PyObject *pytalloc_BaseObject_FromTallocPtr(const void *ptr);
> 
> and make use of pytalloc_get_type() on the receiver side.
> 
> A useful addition would be:
> 
>   int _pytalloc_check_type(PyObject *py_obj, const char *type_name);
>   #define pytalloc_check_type(py_obj, type) \
>           _pytalloc_check_type(py_obj, #type);
> 
> metze
> 
-------------- next part --------------
From 0a2e9643f439ec4917ce9905c94f4b0f4d99e8b3 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/2] pytalloc: add
 pytalloc_GenericObject_{steal,reference}[_ex]()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 lib/talloc/pytalloc.c      | 13 +++++++++++++
 lib/talloc/pytalloc.h      | 24 +++++++++++++++++++++++-
 lib/talloc/pytalloc_util.c | 40 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 76 insertions(+), 1 deletion(-)

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..888ce40 100644
--- a/lib/talloc/pytalloc.h
+++ b/lib/talloc/pytalloc.h
@@ -58,8 +58,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_util.c b/lib/talloc/pytalloc_util.c
index cb71dc9..02f510b 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, mem_ctx);
+}
+
+/*
+ * 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, mem_ctx);
+}
+
 _PUBLIC_ int pytalloc_Check(PyObject *obj)
 {
 	PyTypeObject *tp = pytalloc_GetObjectType();
-- 
1.9.1


From 5847d28949529896df30be082702be39ca8b550e 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 2/2] s3:pyrpc_util: make use of
 pytalloc_GenericObject_reference*()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/librpc/rpc/pyrpc_util.c | 51 +++++++++--------------------------------
 1 file changed, 11 insertions(+), 40 deletions(-)

diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c
index cfbb9cb..ae1462d 100644
--- a/source4/librpc/rpc/pyrpc_util.c
+++ b/source4/librpc/rpc/pyrpc_util.c
@@ -394,25 +394,27 @@ 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;
+	const void *in_ptr = 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;
 	}
+	in_ptr = _pytalloc_get_type(in_obj, typename);
+	if (in_ptr == NULL) {
+		Py_XDECREF(mem_ctx_obj);
+		Py_XDECREF(in_obj);
+		return NULL;
+	}
 
 	ret = PyObject_CallMethod((PyObject *)type,
 				  discard_const_p(char, "__import__"),
@@ -430,16 +432,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 +450,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/20170220/81a7ca52/signature.sig>


More information about the samba-technical mailing list