From ba3eb78a2c8536ff01150a6c4b75ca0d777cf549 Mon Sep 17 00:00:00 2001 From: Matthias Klose Date: Oct 17 2013 14:14:19 +0000 Subject: add python3 support (#963839) --- diff --git a/configure.ac b/configure.ac index 02f9d6d..6da9899 100644 --- a/configure.ac +++ b/configure.ac @@ -60,7 +60,7 @@ if test "x$with_python" = "xno"; then AC_MSG_RESULT([skipped]) PYTHONVERS= else - PYTHONVERS=$(ls /usr/include/python2.*/Python.h 2> /dev/null | sed 's|/usr/include/\([[^/]]*\)/Python.h|\1|g' | tr '\n' ' ') + PYTHONVERS=$(ls /usr/include/python*/Python.h 2> /dev/null | sed 's|.*\(python[[0-9]]*\.[[0-9]]*\).*|\1|g' | tr '\n' ' ') AC_MSG_RESULT([$PYTHONVERS]) fi AC_SUBST([PYTHONVERS]) diff --git a/peanuts.py b/peanuts.py index 608a5fb..535571d 100755 --- a/peanuts.py +++ b/peanuts.py @@ -2,6 +2,7 @@ # Demo program to show use of python-newt module +from __future__ import absolute_import, print_function, unicode_literals from snack import * screen = SnackScreen() @@ -38,8 +39,8 @@ result = g.runOnce() screen.finish() -print result -print "listbox:", li.current() -print "rb:", rb.getSelection() -print "bb:", bb.buttonPressed(result) -print "checkboxtree:", ct.getSelection() +print(result) +print("listbox:", li.current()) +print("rb:", rb.getSelection()) +print("bb:", bb.buttonPressed(result)) +print("checkboxtree:", ct.getSelection()) diff --git a/popcorn.py b/popcorn.py index 9798218..5d5a345 100755 --- a/popcorn.py +++ b/popcorn.py @@ -1,5 +1,6 @@ #!/usr/bin/python +from __future__ import absolute_import, print_function, unicode_literals from snack import * import sys @@ -45,7 +46,7 @@ r1 = SingleRadioButton("Radio 1", None, 1) r2 = SingleRadioButton("Radio 2", r1) def something(): - print hello + print(hello) screen = SnackScreen() @@ -99,14 +100,14 @@ g.runOnce() screen.finish() -print "val", e.value() -print "check", cb.value() -print "r1", r1.selected() -print "listbox", li.current() +print("val", e.value()) +print("check", cb.value()) +print("r1", r1.selected()) +print("listbox", li.current()) # returns a tuple of the wrapped text, the actual width, and the actual height -print res +print(res) -print foo -print 'lbcw', lbcw -print "ct selected", ct.getSelection() -print "ct current", ct.getCurrent() +print(foo) +print('lbcw', lbcw) +print("ct selected", ct.getSelection()) +print("ct current", ct.getCurrent()) diff --git a/snack.py b/snack.py index 09506a4..0e42112 100644 --- a/snack.py +++ b/snack.py @@ -39,9 +39,11 @@ Functions: - EntryWindow """ + +from __future__ import absolute_import, print_function, unicode_literals import _snack -import types import string +import sys from _snack import FLAG_DISABLED, FLAGS_SET, FLAGS_RESET, FLAGS_TOGGLE, FD_READ, FD_WRITE, FD_EXCEPT @@ -304,7 +306,7 @@ hotkeys = { "F1" : _snack.KEY_F1, "F2" : _snack.KEY_F2, "F3" : _snack.KEY_F3, "INSERT": _snack.KEY_INSERT, " " : ord(" ") } -for n in hotkeys.keys(): +for n in list(hotkeys.keys()): hotkeys[hotkeys[n]] = n for o,c in [ (ord(c),c) for c in string.ascii_letters+string.digits ]: hotkeys[c] = o @@ -328,14 +330,14 @@ class Form: self.w.addhotkey(hotkeys[keyname]) def add(self, widget): - if widget.__dict__.has_key('hotkeys'): + if 'hotkeys' in widget.__dict__: for key in widget.hotkeys.keys(): self.addHotKey(key) - if widget.__dict__.has_key('gridmembers'): + if 'gridmembers' in widget.__dict__: for w in widget.gridmembers: self.add(w) - elif widget.__dict__.has_key('w'): + elif 'w' in widget.__dict__: self.trans[widget.w.key] = widget return self.w.add(widget.w) return None @@ -408,14 +410,14 @@ class Grid: if (growy): gridFlags = gridFlags | _snack.GRID_GROWY - if (what.__dict__.has_key('g')): + if 'g' in what.__dict__: return self.g.setfield(col, row, what.g, padding, anchorFlags, gridFlags) else: return self.g.setfield(col, row, what.w, padding, anchorFlags) def __init__(self, *args): - self.g = apply(_snack.grid, args) + self.g = _snack.grid(*args) self.gridmembers = [] colorsets = { "ROOT" : _snack.COLORSET_ROOT, @@ -604,9 +606,9 @@ class ButtonBar(Grid): self.item = 0 Grid.__init__(self, len(buttonlist), 1) for blist in buttonlist: - if (type(blist) == types.StringType): + if isinstance(blist, str if sys.version >= '3' else basestring): title = blist - value = string.lower(blist) + value = blist.lower() elif len(blist) == 2: (title, value) = blist else: @@ -622,7 +624,7 @@ class ButtonBar(Grid): self.item = self.item + 1 def buttonPressed(self, result): - if self.hotkeys.has_key(result): + if result in self.hotkeys: return self.hotkeys[result] for (button, value) in self.list: @@ -657,7 +659,7 @@ class GridFormHelp(Grid): self.form_created = 0 args = list(args) args[:0] = [self] - apply(Grid.__init__, tuple(args)) + Grid.__init__(*tuple(args)) def add(self, widget, col, row, padding = (0, 0, 0, 0), anchorLeft = 0, anchorTop = 0, anchorRight = 0, @@ -713,7 +715,7 @@ class GridForm(GridFormHelp): """ def __init__(self, screen, title, *args): myargs = (self, screen, title, None) + args - apply(GridFormHelp.__init__, myargs) + GridFormHelp.__init__(*myargs) class CheckboxTree(Widget): """ CheckboxTree combo widget, @@ -788,7 +790,7 @@ def ListboxChoiceWindow(screen, title, text, items, l = Listbox(height, scroll = scroll, returnExit = 1) count = 0 for item in items: - if (type(item) == types.TupleType): + if type(item) == tuple: (text, key) = item else: text = item @@ -848,9 +850,9 @@ def EntryWindow(screen, title, text, prompts, allowCancel = 1, width = 40, count = 0 entryList = [] for n in prompts: - if (type(n) == types.TupleType): + if type(n) == tuple: (n, e) = n - if (type(e) in types.StringTypes): + if isinstance(e, str if sys.version >= '3' else basestring): e = Entry(entryWidth, e) else: e = Entry(entryWidth) diff --git a/snackmodule.c b/snackmodule.c index a566d46..f42fc65 100644 --- a/snackmodule.c +++ b/snackmodule.c @@ -12,10 +12,24 @@ #include #include "Python.h" +#include "structmember.h" #include "nls.h" #include "newt.h" #include "newt_pr.h" +#if PY_MAJOR_VERSION >= 3 + #define PyInt_FromLong PyLong_FromLong + #define PyInt_AsLong PyLong_AsLong + #define PyString_FromString PyUnicode_FromString + #define MOD_ERROR_VAL NULL + #define MOD_SUCCESS_VAL(val) val + #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void) +#else + #define MOD_ERROR_VAL + #define MOD_SUCCESS_VAL(val) + #define MOD_INIT(name) void init##name(void) +#endif + typedef struct snackWidget_s snackWidget; typedef struct snackGrid_s snackGrid; typedef struct snackForm_s snackForm; @@ -68,6 +82,8 @@ static snackWidget * textWidget(PyObject * s, PyObject * args); static PyObject * ternaryWindow(PyObject * s, PyObject * args); static snackWidget * checkboxTreeWidget(PyObject * s, PyObject * args, PyObject * kwargs); static PyObject * pywstrlen(PyObject * s, PyObject * args); +static PyObject * widget_get_checkboxValue(PyObject *self, void *closure); +static PyObject * widget_get_radioValue(PyObject *self, void *closure); static PyMethodDef snackModuleMethods[] = { { "button", (PyCFunction) buttonWidget, METH_VARARGS, NULL }, @@ -107,12 +123,31 @@ static PyMethodDef snackModuleMethods[] = { { NULL } } ; +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_snack", /* m_name */ + NULL, /* m_doc */ + -1, /* m_size */ + snackModuleMethods, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ + }; +#endif + +static struct PyGetSetDef widget_getset[] = { + { "checkboxValue", widget_get_checkboxValue, 0, NULL, NULL }, + { "radioValue", widget_get_radioValue, 0, NULL, NULL }, + { NULL } +}; + struct snackGrid_s { PyObject_HEAD newtGrid grid; } ; -static PyObject * gridGetAttr(PyObject * s, char * name); static PyObject * gridPlace(snackGrid * s, PyObject * args); static PyObject * gridSetField(snackGrid * s, PyObject * args); @@ -123,20 +158,34 @@ static PyMethodDef gridMethods[] = { }; static PyTypeObject snackGridType = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /* ob_size */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) "snackgrid", /* tp_name */ sizeof(snackGrid), /* tp_size */ 0, /* tp_itemsize */ emptyDestructor, /* tp_dealloc */ 0, /* tp_print */ - gridGetAttr, /* tp_getattr */ + 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + gridMethods /* tp_methods */ }; struct snackForm_s { @@ -144,7 +193,6 @@ struct snackForm_s { newtComponent fo; } ; -static PyObject * formGetAttr(PyObject * s, char * name); static PyObject * formAdd(snackForm * s, PyObject * args); static PyObject * formDraw(snackForm * s, PyObject * args); static PyObject * formRun(snackForm * s, PyObject * args); @@ -165,20 +213,34 @@ static PyMethodDef formMethods[] = { }; static PyTypeObject snackFormType = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /* ob_size */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) "snackform", /* tp_name */ sizeof(snackForm), /* tp_size */ 0, /* tp_itemsize */ emptyDestructor, /* tp_dealloc */ 0, /* tp_print */ - formGetAttr, /* tp_getattr */ + 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + formMethods /* tp_methods */ }; struct snackWidget_s { @@ -191,7 +253,6 @@ struct snackWidget_s { } ; static PyObject * widgetAddCallback(snackWidget * s, PyObject * args); -static PyObject * widgetGetAttr(PyObject * s, char * name); static void widgetDestructor(PyObject * s); static PyObject * widgetEntrySetValue(snackWidget * s, PyObject * args); static PyObject * widgetLabelText(snackWidget * s, PyObject * args); @@ -255,21 +316,43 @@ static PyMethodDef widgetMethods[] = { { NULL } }; +static PyMemberDef widget_members[] = { + { "key" , T_INT, offsetof(snackWidget, co), 0, NULL }, + { "entryValue", T_STRING, offsetof(snackWidget, apointer), 0, NULL }, + { NULL } +}; + static PyTypeObject snackWidgetType = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /* ob_size */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) "snackwidget", /* tp_name */ sizeof(snackWidget), /* tp_size */ 0, /* tp_itemsize */ widgetDestructor, /* tp_dealloc */ 0, /* tp_print */ - widgetGetAttr, /* tp_getattr */ + 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + widgetMethods, /* tp_methods */ + widget_members, /* tp_members */ + widget_getset /* tp_getset */ }; static snackWidget * snackWidgetNew (void) { @@ -859,10 +942,6 @@ static snackGrid * gridCreate(PyObject * s, PyObject * args) { return grid; } -static PyObject * gridGetAttr(PyObject * s, char * name) { - return Py_FindMethod(gridMethods, s, name); -} - static PyObject * gridPlace(snackGrid * grid, PyObject * args) { int x, y; @@ -886,7 +965,7 @@ static PyObject * gridSetField(snackGrid * grid, PyObject * args) { &anchorFlags, &growFlags)) return NULL; - if (w->ob_type == &snackWidgetType) { + if (Py_TYPE(w) == &snackWidgetType) { newtGridSetField(grid->grid, x, y, NEWT_GRID_COMPONENT, w->co, pLeft, pTop, pRight, pBottom, anchorFlags, growFlags); @@ -901,10 +980,6 @@ static PyObject * gridSetField(snackGrid * grid, PyObject * args) { return Py_None; } -static PyObject * formGetAttr(PyObject * s, char * name) { - return Py_FindMethod(formMethods, s, name); -} - static PyObject * formDraw(snackForm * s, PyObject * args) { newtDrawForm(s->fo); @@ -996,20 +1071,18 @@ static PyObject * formSetCurrent(snackForm * form, PyObject * args) { return Py_None; } -static PyObject * widgetGetAttr(PyObject * s, char * name) { - snackWidget * w = (snackWidget *) s; +static PyObject * widget_get_checkboxValue(PyObject *self, void *closure) +{ + snackWidget *w = (snackWidget *)self; - if (!strcmp(name, "key")) { - return Py_BuildValue("i", w->co); - } else if (!strcmp(name, "entryValue")) { - return Py_BuildValue("s", w->apointer); - } else if (!strcmp(name, "checkboxValue")) { return Py_BuildValue("i", w->achar == ' ' ? 0 : 1); - } else if (!strcmp(name, "radioValue")) { - return Py_BuildValue("i", newtRadioGetCurrent(w->co)); - } +} + +static PyObject * widget_get_radioValue(PyObject *self, void *closure) +{ + snackWidget *w = (snackWidget *)self; - return Py_FindMethod(widgetMethods, s, name); + return Py_BuildValue("i", newtRadioGetCurrent(w->co)); } static void widgetDestructor(PyObject * o) { @@ -1351,10 +1424,19 @@ static void setitemstring_decref(PyObject * dict, Py_DECREF(o); } -void init_snack(void) { +MOD_INIT(_snack) +{ PyObject * d, * m; +#if PY_MAJOR_VERSION >= 3 + m = PyModule_Create(&moduledef); +#else m = Py_InitModule("_snack", snackModuleMethods); +#endif + + if (!m) + return MOD_ERROR_VAL; + d = PyModule_GetDict(m); setitemstring_decref(d, "ANCHOR_LEFT", PyInt_FromLong(NEWT_ANCHOR_LEFT)); @@ -1431,4 +1513,6 @@ void init_snack(void) { setitemstring_decref(d, "COLORSET_COMPACTBUTTON", PyInt_FromLong(NEWT_COLORSET_COMPACTBUTTON)); setitemstring_decref(d, "COLORSET_ACTSELLISTBOX", PyInt_FromLong(NEWT_COLORSET_ACTSELLISTBOX)); setitemstring_decref(d, "COLORSET_SELLISTBOX", PyInt_FromLong(NEWT_COLORSET_SELLISTBOX)); + + return MOD_SUCCESS_VAL(m); }