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

Stefan Metzmacher metze at samba.org
Thu Feb 9 16:18:42 UTC 2017


Hi Petr,

>>>> I've started a thread to have us move to just using PyCapsule by
>>>> requiring 2.7.  I think this is likely to get up, but we will know
>>>> soon.  This will kill a number of birds with one stone, so can you re-
>>>> work the patches to rely on PyCapsule?
>>>
>>> Requiring 2.7 is two questions in one:
>>> - the minimum version for Samba
>>> - the minimum version for independent libraries like pytalloc
>>>
>>> But thinking about this, I realized pytalloc can
>>> - export pytalloc_CObject_FromTallocPtr for Python 2
>>> - export pytalloc_PyCapsule_FromTallocPtr for Python 3 *and* 2.7
>>>
>>> Then Samba could use only PyCapsule (if it doesn't need 2.6
>>> compatibility), while talloc maintains backwards compatibility.
>>
>> Maybe to naive, but can't we somehow simulate PyCapsule on top of
>> CObject for 2.6?
>> And use PyCapsule everywhere in the code?
> 
> That's roughly what the proposed patchset does -- it even references the
> comment below. It's possible, but not particularly pretty.

Why I had a brief look and everything but PyCapsule_Import() should be
pretty easy
to similate on top of PyCObject.

In the last patchset from Andrew I'm wondering why
PyCapsulate_GetContext() is used,
I'd guess PyCObject_GetDesc should be replaced by PyCapsule_GetName().

I don't think we actually need PyCapsulate_{Get,Set}Context() for our usage.
PyCapsule_New() and PyCapsule_GetPointer() should be enough.
I only used PyCObject_GetDesc() because PyCObject_AsVoidPtr() doesn't have
a way to check the description.

Something like this should work and provide PyCapsulate
for all samba callers even with python 2.6

#ifdef PYTHON2.6
#define PyCapsule_Destructor \
	_compat_PyCapsule_Destructor
#define PyCapsule_New(pointer, name, destructor_fn) \
	_compat_PyCapsule_New(pointer, name, destructor_fn)
#define PyCapsule_CheckExact(p) \
	_compat_PyCapsule_CheckExact(p)
#define PyCapsule_IsValid(capsule, name) \
	_compat_PyCapsule_IsValid(capsule, name)
#define PyCapsule_GetPointer(capsule, name) \
	_compat_PyCapsule_GetPointer(capsule, name)

typedef void (*PyCapsule_Destructor)(PyObject *);
PyObject* PyCapsule_New(void *pointer, const char *name,
PyCapsule_Destructor destructor_fn);
int PyCapsule_CheckExact(PyObject *p);
int PyCapsule_IsValid(PyObject *capsule, const char *name);
void* PyCapsule_GetPointer(PyObject *capsule, const char *name);

#endif /* PYTHON2.7 */

struct _compat_PyCapsule {
	PyObject *self;
	void *pointer;
	const char *name;
	PyCapsule_Destructor destructor_fn;
}

static const char *_compat_PyCapsule_desc = "_compat_PyCapsule_desc";

static void _compat_PyCapsule_destructor_wrapper(void *_capsule, void
*_desc)
{
	
	struct _compat_PyCapsule *capsule =
		(struct _compat_PyCapsule *)_capsule;

	assert(_desc == _compat_PyCapsule_desc);

	if (capsule->destructor_fn != NULL) {
		capsule->destructor_fn(capsule->self);
	}

	free(capsule);
}

PyObject *_compat_PyCapsule_New(void *pointer, const char *name,
PyCapsule_Destructor destructor_fn)
{
	struct _compat_PyCapsule *capsule = NULL;

	assert(pointer != NULL);
	assert(name != NULL);

	capsule = calloc(1, sizeof(*capsule));
	if (capsule == NULL) {
		return NULL;
	}
	capsule->pointer = pointer;
	capsule->name = name;
	capsule->destructor_fn = destructor_fn;
	capsule->self = PyCObject_FromVoidPtrAndDesc(capsule,
				_compat_PyCapsule_desc,
				_compat_PyCapsule_destructor_wrapper);
	if (capsule->self == NULL) {
		free(capsule);
		return NULL;
	}

	return capsule->self;
}

int PyCapsule_CheckExact(PyObject *p)
{
	int tmp;
	void *desc = NULL;
	void *_capsule = NULL;
	struct _compat_PyCapsule *capsule = NULL;

	tmp = PyCObject_Check(p);
	if (tmp == 0) {
		return 0;
	}

	desc = PyCObject_GetDesc(p);
	if (desc == NULL) {
		return 0;
	}

	if (desc == _compat_PyCapsule_desc) {
		return 1;
	}

	return 0;
}

void *PyCapsule_GetPointer(PyObject *self, const char *name)
{
	int tmp;
	void *_capsule = NULL;
	struct _compat_PyCapsule *capsule = NULL;

	tmp = PyCapsule_CheckExact(self);
	if (tmp == 0) {
		return 0;
	}

	_capsule = PyCObject_AsVoidPtr(self);
	capsule = (struct _compat_PyCapsule *)_capsule;

	tmp = strcmp(capsule->name, name);
	if (tmp != 0) {
		return 0;
	}

	return capsule->pointer;
}

int PyCapsule_IsValid(PyObject *self, const char *name)
{
	void *pointer;

	pointer = PyCapsule_GetPointer(self);
	if (pointer != NULL) {
		return 1;
	}

	return 0;
}

-------------- 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/20170209/5b784e94/signature.sig>


More information about the samba-technical mailing list