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

pytalloc: Port to Python 3

- Use native string for repr

- Use rich comparison
  Removes the deprecated tp_compare in favor of tp_richcompare.
  Disparate types cannot be compared (except for == and !=),
  and True or False objects are returned explicitly.

- Use Py_TYPE instead of ob_type
  This changed to conform to C aliasing rules,
  see http://legacy.python.org/dev/peps/pep-3123/

- Don't provide CObject creation function
  A PyCapsule based replacement would be possible,
  but might not be necessary considering the function is
  not used much.

- Use new-style module initialization

Build changes:

- Use ABI flag in the lib name and pkg-config template

- Use the SAMBA_CHECK_PYTHON macro for finding Python

Signed-off-by: Petr Viktorin <pviktori@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Jelmer Vernooij <jelmer@samba.org>
This commit is contained in:
Petr Viktorin 2015-01-15 14:07:09 +01:00 committed by Andrew Bartlett
parent 9f71b96ba0
commit cd6615ecbd
8 changed files with 140 additions and 19 deletions

View File

@ -6,6 +6,6 @@ includedir=@includedir@
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/

View File

@ -21,7 +21,13 @@
#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)
@ -79,8 +85,8 @@ static PyObject *pytalloc_default_repr(PyObject *obj)
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);
}
/**
@ -97,6 +103,35 @@ static void pytalloc_dealloc(PyObject* self)
/**
* 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,
@ -106,6 +141,7 @@ static int pytalloc_default_cmp(PyObject *_obj1, PyObject *_obj2)
return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2));
}
#endif
static PyTypeObject TallocObject_Type = {
.tp_name = "talloc.Object",
@ -114,21 +150,56 @@ static PyTypeObject TallocObject_Type = {
.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

View File

@ -52,6 +52,8 @@ 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 *);
#endif
#endif /* _PYTALLOC_H_ */

View File

@ -20,6 +20,14 @@ for objects that wrap talloc-maintained memory in C. It won't write your
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
@ -126,6 +134,8 @@ 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.
Debug function for talloc in Python
-----------------------------------

View File

@ -97,6 +97,8 @@ _PUBLIC_ PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_
return (PyObject *)ret;
}
#if PY_MAJOR_VERSION < 3
static void py_cobject_talloc_free(void *ptr)
{
talloc_free(ptr);
@ -110,6 +112,8 @@ _PUBLIC_ PyObject *pytalloc_CObject_FromTallocPtr(void *ptr)
return PyCObject_FromVoidPtr(ptr, py_cobject_talloc_free);
}
#endif
_PUBLIC_ int pytalloc_Check(PyObject *obj)
{
PyTypeObject *tp = pytalloc_GetObjectType();

View File

@ -104,25 +104,56 @@ static PyTypeObject DObject_Type = {
.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")
void init_test_pytalloc(void);
void init_test_pytalloc(void)
#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
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

View File

@ -78,6 +78,9 @@ class TallocComparisonTests(unittest.TestCase):
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)

View File

@ -60,9 +60,7 @@ def configure(conf):
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')
@ -118,7 +116,9 @@ def build(bld):
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,
@ -132,7 +132,7 @@ def build(bld):
)
bld.SAMBA_PYTHON('pytalloc',
'pytalloc.c',
deps='talloc pytalloc-util',
deps='talloc ' + name,
enabled=True,
realname='talloc.so')