1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-27 22:50:26 +03:00

pytalloc: add pytalloc_GenericObject_{steal,reference}[_ex]()

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Stefan Metzmacher 2017-02-20 17:33:42 +01:00 committed by Andrew Bartlett
parent 73180972db
commit 2cae14df12
6 changed files with 203 additions and 12 deletions

View 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 *)

View 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 *)

View 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;
}

View 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);

View 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
-----------------------------------

View 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)) {