Name: pytalloc-util
Description: Utility functions for using talloc objects with Python
Version: @TALLOC_VERSION@
-Libs: @LIB_RPATH@ -L${libdir} -lpytalloc-util
+Libs: @LIB_RPATH@ -L${libdir} -lpytalloc-util@PYTHON_SO_ABI_FLAG@
Cflags: -I${includedir}
URL: http://talloc.samba.org/
#include <talloc.h>
#include <pytalloc.h>
-void inittalloc(void);
+static PyTypeObject TallocObject_Type;
+
+#if PY_MAJOR_VERSION >= 3
+#define PyStr_FromFormat PyUnicode_FromFormat
+#else
+#define PyStr_FromFormat PyString_FromFormat
+#endif
/* print a talloc tree report for a talloc python object */
static PyObject *pytalloc_report_full(PyObject *self, PyObject *args)
pytalloc_Object *talloc_obj = (pytalloc_Object *)obj;
PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj);
- return PyString_FromFormat("<%s talloc object at 0x%p>",
- type->tp_name, talloc_obj->ptr);
+ return PyStr_FromFormat("<%s talloc object at 0x%p>",
+ type->tp_name, talloc_obj->ptr);
}
/**
/**
* Default (but only slightly more useful than the default) implementation of cmp.
*/
+#if PY_MAJOR_VERSION >= 3
+static PyObject *pytalloc_default_richcmp(PyObject *obj1, PyObject *obj2, int op)
+{
+ void *ptr1;
+ void *ptr2;
+ if (Py_TYPE(obj1) == Py_TYPE(obj2)) {
+ /* When types match, compare pointers */
+ ptr1 = pytalloc_get_ptr(obj1);
+ ptr2 = pytalloc_get_ptr(obj2);
+ } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) {
+ /* Otherwise, compare types */
+ ptr1 = Py_TYPE(obj1);
+ ptr2 = Py_TYPE(obj2);
+ } else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ switch (op) {
+ case Py_EQ: return PyBool_FromLong(ptr1 == ptr2);
+ case Py_NE: return PyBool_FromLong(ptr1 != ptr2);
+ case Py_LT: return PyBool_FromLong(ptr1 < ptr2);
+ case Py_GT: return PyBool_FromLong(ptr1 > ptr2);
+ case Py_LE: return PyBool_FromLong(ptr1 <= ptr2);
+ case Py_GE: return PyBool_FromLong(ptr1 >= ptr2);
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+#else
static int pytalloc_default_cmp(PyObject *_obj1, PyObject *_obj2)
{
pytalloc_Object *obj1 = (pytalloc_Object *)_obj1,
return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2));
}
+#endif
static PyTypeObject TallocObject_Type = {
.tp_name = "talloc.Object",
.tp_dealloc = (destructor)pytalloc_dealloc,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.tp_repr = pytalloc_default_repr,
+#if PY_MAJOR_VERSION >= 3
+ .tp_richcompare = pytalloc_default_richcmp,
+#else
.tp_compare = pytalloc_default_cmp,
+#endif
};
-void inittalloc(void)
+#define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.")
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "talloc",
+ .m_doc = MODULE_DOC,
+ .m_size = -1,
+ .m_methods = talloc_methods,
+};
+#endif
+
+static PyObject *module_init(void);
+static PyObject *module_init(void)
{
PyObject *m;
if (PyType_Ready(&TallocObject_Type) < 0)
- return;
+ return NULL;
- m = Py_InitModule3("talloc", talloc_methods,
- "Python wrapping of talloc-maintained objects.");
+#if PY_MAJOR_VERSION >= 3
+ m = PyModule_Create(&moduledef);
+#else
+ m = Py_InitModule3("talloc", talloc_methods, MODULE_DOC);
+#endif
if (m == NULL)
- return;
+ return NULL;
Py_INCREF(&TallocObject_Type);
PyModule_AddObject(m, "Object", (PyObject *)&TallocObject_Type);
+ return m;
+}
+
+#if PY_MAJOR_VERSION >= 3
+PyMODINIT_FUNC PyInit_talloc(void);
+PyMODINIT_FUNC PyInit_talloc(void)
+{
+ return module_init();
+}
+#else
+void inittalloc(void);
+void inittalloc(void)
+{
+ module_init();
}
+#endif
#define pytalloc_new(type, typeobj) pytalloc_steal(typeobj, talloc_zero(NULL, type))
+#if PY_MAJOR_VERSION < 3
PyObject *pytalloc_CObject_FromTallocPtr(void *);
+#endif
#endif /* _PYTALLOC_H_ */
bindings for you but it will make it easier to write C bindings that involve
talloc, and take away some of the boiler plate.
+Python 3
+--------
+
+pytalloc can be used with Python 3. Usage from Python extension remains
+the same, but for the C utilities, the library to link to is tagged with
+Python's PEP3149 ABI tag, for example "pytalloc.cpython34m".
+To make a build for Python 3, configure with PYTHON=/usr/bin/python3.
+.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
pytalloc_Object
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.
+
Debug function for talloc in Python
-----------------------------------
return (PyObject *)ret;
}
+#if PY_MAJOR_VERSION < 3
+
static void py_cobject_talloc_free(void *ptr)
{
talloc_free(ptr);
return PyCObject_FromVoidPtr(ptr, py_cobject_talloc_free);
}
+#endif
+
_PUBLIC_ int pytalloc_Check(PyObject *obj)
{
PyTypeObject *tp = pytalloc_GetObjectType();
.tp_doc = "test talloc object that calls a function when underlying data is freed\n",
};
-#define MODULE_DOC "Test utility module for pytalloc"
+#define MODULE_DOC PyDoc_STR("Test utility module for pytalloc")
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "_test_pytalloc",
+ .m_doc = PyDoc_STR("Test utility module for pytalloc"),
+ .m_size = -1,
+ .m_methods = test_talloc_methods,
+};
+#endif
-void init_test_pytalloc(void);
-void init_test_pytalloc(void)
+static PyObject *module_init(void);
+static PyObject *module_init(void)
{
PyObject *m;
DObject_Type.tp_base = pytalloc_GetObjectType();
if (PyType_Ready(&DObject_Type) < 0) {
- return;
+ return NULL;
}
+#if PY_MAJOR_VERSION >= 3
+ m = PyModule_Create(&moduledef);
+#else
m = Py_InitModule3("_test_pytalloc", test_talloc_methods, MODULE_DOC);
+#endif
if (m == NULL) {
- return;
+ return NULL;
}
Py_INCREF(&DObject_Type);
Py_INCREF(DObject_Type.tp_base);
PyModule_AddObject(m, "DObject", (PyObject *)&DObject_Type);
+
+ return m;
+}
+
+
+#if PY_MAJOR_VERSION >= 3
+PyMODINIT_FUNC PyInit__test_pytalloc(void);
+PyMODINIT_FUNC PyInit__test_pytalloc(void)
+{
+ return module_init();
+}
+#else
+void init_test_pytalloc(void);
+void init_test_pytalloc(void)
+{
+ module_init();
}
+#endif
def test_compare_different_types(self):
# object comparison falls back to comparing types
+ if sys.version_info >= (3, 0):
+ # In Python 3, types are unorderable -- nothing to test
+ return
if talloc.Object < _test_pytalloc.DObject:
obj1 = _test_pytalloc.new()
obj2 = _test_pytalloc.DObject(dummy_func)
if not conf.env.disable_python:
# also disable if we don't have the python libs installed
- conf.find_program('python', var='PYTHON')
- conf.check_tool('python')
- conf.check_python_version((2,4,2))
+ conf.SAMBA_CHECK_PYTHON(mandatory=False, version=(2,4,2))
conf.SAMBA_CHECK_PYTHON_HEADERS(mandatory=False)
if not conf.env.HAVE_PYTHON_H:
Logs.warn('Disabling pytalloc-util as python devel libs not found')
manpages='man/talloc.3')
if not bld.CONFIG_SET('USING_SYSTEM_PYTALLOC_UTIL') and not bld.env.disable_python:
- bld.SAMBA_LIBRARY('pytalloc-util',
+ name = bld.pyembed_libname('pytalloc-util')
+
+ bld.SAMBA_LIBRARY(name,
source='pytalloc_util.c',
public_deps='talloc',
pyembed=True,
)
bld.SAMBA_PYTHON('pytalloc',
'pytalloc.c',
- deps='talloc pytalloc-util',
+ deps='talloc ' + name,
enabled=True,
realname='talloc.so')