From c5d0685c76927dd97fa28118c03a418867d7ba05 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Oct 17 2013 14:48:06 +0000 Subject: add python3 support (#963839) --- diff --git a/newt-python3.patch b/newt-python3.patch new file mode 100644 index 0000000..e93287a --- /dev/null +++ b/newt-python3.patch @@ -0,0 +1,509 @@ +commit ba3eb78a2c8536ff01150a6c4b75ca0d777cf549 +Author: Matthias Klose +Date: Thu Oct 17 15:19:58 2013 +0200 + + 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); + } diff --git a/newt.spec b/newt.spec index cc75e83..2651291 100644 --- a/newt.spec +++ b/newt.spec @@ -11,6 +11,9 @@ BuildRequires: popt-devel python-devel slang-devel BuildRequires: docbook-utils Provides: snack = %{version}-%{release} +Patch1: newt-python3.patch +BuildRequires: autoconf + %package devel Summary: Newt windowing toolkit development files Requires: slang-devel %{name}%{?_isa} = %{version}-%{release} @@ -56,8 +59,10 @@ providing a python API for creating text mode ionterfaces. %prep %setup -q +%patch1 -p1 %build +autoconf # gpm support seems to smash the stack w/ we use help in anaconda?? # --with-gpm-support %configure --without-tcl