diff --git a/0001-alsaseq-fix-constant-objects-in-Python-3.patch b/0001-alsaseq-fix-constant-objects-in-Python-3.patch new file mode 100644 index 0000000..e85bddf --- /dev/null +++ b/0001-alsaseq-fix-constant-objects-in-Python-3.patch @@ -0,0 +1,260 @@ +From a64a6cc703d08db5c223a16bf812a569534ba464 Mon Sep 17 00:00:00 2001 +From: Hector Martin +Date: Thu, 6 Aug 2020 00:42:43 +0900 +Subject: [PATCH] alsaseq: fix constant objects in Python 3 + +In Py3 everything is a long, so we can't get away with duplicating the +integer object layout any more. Properly subclass PyLong_Type instead, +with a bit of a hack to add an extra name field after the variable-sized +data section. + +Also get rid of the enum type stuff, which seems to be unused cruft, and +the numprotocol stuff, because the base type can take care of that (and +we can't map arbitrary arithmetic results back to constants anyway). + +Signed-off-by: Hector Martin +Signed-off-by: Takashi Iwai +--- + pyalsa/alsaseq.c | 149 +++++++++++++++++------------------------------ + 1 file changed, 52 insertions(+), 97 deletions(-) + +diff --git a/pyalsa/alsaseq.c b/pyalsa/alsaseq.c +index 0e7cc35bb99c..9d9b1a9cf4cc 100644 +--- a/pyalsa/alsaseq.c ++++ b/pyalsa/alsaseq.c +@@ -51,9 +51,6 @@ + /* the C variable of a constant dict */ + #define TDICT(subtype) _dictPYALSASEQ_CONST_##subtype + +-/* the C enumeration of a constant dict */ +-#define TTYPE(subtype) PYALSASEQ_CONST_##subtype +- + /* defines constant dict by type */ + #define TCONSTDICT(subtype) \ + static PyObject * TDICT(subtype); +@@ -71,7 +68,7 @@ + /* creates a typed constant and add it to the module and dictionary */ + #define TCONSTADD(module, subtype, name) { \ + PyObject *tmp = \ +- Constant_create(#name, SND_##name, TTYPE(subtype)); \ ++ Constant_create(#name, SND_##name); \ + if (tmp == NULL) { \ + return MOD_ERROR_VAL; \ + } \ +@@ -109,46 +106,6 @@ + } \ + } + +- +-/* num protocol support for binary Constant operations */ +-#define NUMPROTOCOL2(name, oper) \ +- static PyObject * \ +- Constant_##name (PyObject *v, PyObject *w) { \ +- int type = 0; \ +- long val1, val2, val; \ +- if (get_long1(v, &val1) || get_long1(w, &val2)) { \ +- Py_INCREF(Py_NotImplemented); \ +- return Py_NotImplemented; \ +- } \ +- val = val1 oper val2; \ +- /* always asume left will be the type */ \ +- if (PyObject_TypeCheck(v, &ConstantType)) { \ +- type = ((ConstantObject *) v)->type; \ +- } else if (PyObject_TypeCheck(w, &ConstantType)) { \ +- type = ((ConstantObject *) w)->type; \ +- } \ +- PyObject *self = Constant_create(#oper, val, type); \ +- return self; \ +- } +- +-/* num protocol support for unary Constant operations */ +-#define NUMPROTOCOL1(name, oper) \ +- static PyObject * \ +- Constant_##name (PyObject *v) { \ +- int type = 0; \ +- long val1, val; \ +- if (get_long1(v, &val1)) { \ +- Py_INCREF(Py_NotImplemented); \ +- return Py_NotImplemented; \ +- } \ +- val = oper val1; \ +- if (PyObject_TypeCheck(v, &ConstantType)) { \ +- type = ((ConstantObject *) v)->type; \ +- } \ +- PyObject *self = Constant_create(#oper, val, type); \ +- return self; \ +- } +- + /* sets the object into the dict */ + #define SETDICTOBJ(name, object) \ + PyDict_SetItemString(dict, name, object) +@@ -328,21 +285,6 @@ + // alsaseq.Constant implementation + ////////////////////////////////////////////////////////////////////////////// + +-/* alsaseq.Constant->type enumeration */ +-enum { +- PYALSASEQ_CONST_STREAMS, +- PYALSASEQ_CONST_MODE, +- PYALSASEQ_CONST_QUEUE, +- PYALSASEQ_CONST_CLIENT_TYPE, +- PYALSASEQ_CONST_PORT_CAP, +- PYALSASEQ_CONST_PORT_TYPE, +- PYALSASEQ_CONST_EVENT_TYPE, +- PYALSASEQ_CONST_EVENT_TIMESTAMP, +- PYALSASEQ_CONST_EVENT_TIMEMODE, +- PYALSASEQ_CONST_ADDR_CLIENT, +- PYALSASEQ_CONST_ADDR_PORT, +-}; +- + // constants dictionaries + + TCONSTDICT(STREAMS); +@@ -390,34 +332,66 @@ PyDoc_STRVAR(Constant__doc__, + "Python number protocol." + ); + +-/** alsaseq.Constant object structure type */ ++/** alsaseq.Constant additional fields */ ++/* This follows the variable length portion of the Long type */ + typedef struct { +- PyObject_HEAD +- ; +- +- /* value of constant */ +- unsigned long int value; + /* name of constant */ + const char *name; +- /* type of constant */ +- int type; ++} ConstantExtraFields; ++ ++/** alsaseq.Constant object structure type */ ++typedef struct { ++#if PY_MAJOR_VERSION < 3 ++ PyIntObject base; ++#else ++ /* NOTE: this only works if the value fits in one digit */ ++ PyLongObject base; ++#endif ++ /* This field is actually offset by the base type's variable size portion */ ++ ConstantExtraFields extra; + } ConstantObject; + ++#if PY_MAJOR_VERSION < 3 ++/* PyInt is fixed size in Python 2 */ ++# define CONST_VALUE(x) PyInt_AsLong((PyObject *)x) ++# define CONST_EXTRA(x) (&(x->extra)) ++#else ++/* PyLong is variable size in Python 3 */ ++# define CONST_VALUE(x) PyLong_AsLong((PyObject *)x) ++# define CONST_EXTRA(x) \ ++ ((ConstantExtraFields *)( \ ++ ((intptr_t)(&x->extra)) \ ++ + abs(Py_SIZE(&x->base)) * Py_TYPE(x)->tp_itemsize \ ++ )) ++#endif ++ + /** alsaseq.Constant type (initialized later...) */ + static PyTypeObject ConstantType; + + /** alsaseq.Constant internal create */ + static PyObject * +-Constant_create(const char *name, long value, int type) { +- ConstantObject *self = PyObject_New(ConstantObject, &ConstantType); ++Constant_create(const char *name, long value) { ++#if PY_MAJOR_VERSION < 3 ++ PyObject *val = PyInt_FromLong(value); ++#else ++ PyObject *val = PyLong_FromLong(value); ++#endif ++ ++ PyObject *args = PyTuple_Pack(1, val); ++ Py_DECREF(val); ++ ++#if PY_MAJOR_VERSION < 3 ++ ConstantObject *self = (ConstantObject *)PyInt_Type.tp_new(&ConstantType, args, NULL); ++#else ++ ConstantObject *self = (ConstantObject *)PyLong_Type.tp_new(&ConstantType, args, NULL); ++#endif ++ Py_DECREF(args); + + if (self == NULL) { + return NULL; + } + +- self->value = value; +- self->name = name; +- self->type = type; ++ CONST_EXTRA(self)->name = name; + + return (PyObject *)self; + } +@@ -426,34 +400,16 @@ Constant_create(const char *name, long value, int type) { + static PyObject * + Constant_repr(ConstantObject *self) { + return PyUnicode_FromFormat("%s(0x%x)", +- self->name, +- (unsigned int)self->value); ++ CONST_EXTRA(self)->name, ++ (unsigned int)CONST_VALUE(self)); + } + + /** alsaseq.Constant tp_str */ + static PyObject * + Constant_str(ConstantObject *self) { + return PyUnicode_FromFormat("%s", +- self->name); +-} +- +-/** alsaseq.Constant Number protocol support (note: not all ops supported) */ +-NUMPROTOCOL2(Add, +) +-NUMPROTOCOL2(Subtract, -) +-NUMPROTOCOL2(Xor, ^) +-NUMPROTOCOL2(Or, |) +-NUMPROTOCOL2(And, &) +-NUMPROTOCOL1(Invert, ~) +- +-/** alsaseq.Constant number protocol methods */ +-static PyNumberMethods Constant_as_number = { +- nb_add: (binaryfunc)Constant_Add, +- nb_subtract: (binaryfunc)Constant_Subtract, +- nb_xor: (binaryfunc)Constant_Xor, +- nb_or: (binaryfunc)Constant_Or, +- nb_and: (binaryfunc)Constant_And, +- nb_invert: (unaryfunc)Constant_Invert +-}; ++ CONST_EXTRA(self)->name); ++} + + /** alsaseq.Constant type */ + static PyTypeObject ConstantType = { +@@ -464,7 +420,7 @@ static PyTypeObject ConstantType = { + #else + tp_base: &PyLong_Type, + #endif +- tp_basicsize: sizeof(ConstantObject), ++ tp_basicsize: sizeof(ConstantObject) + sizeof(ConstantExtraFields), + tp_flags: + #if PY_MAJOR_VERSION < 3 + Py_TPFLAGS_HAVE_GETCHARBUFFER +@@ -474,7 +430,6 @@ static PyTypeObject ConstantType = { + 0, + #endif + tp_doc: Constant__doc__, +- tp_as_number: &Constant_as_number, + tp_free: PyObject_Del, + tp_str: (reprfunc)Constant_str, + tp_repr: (reprfunc)Constant_repr +@@ -1730,7 +1685,7 @@ SeqEvent_repr(SeqEventObject *self) { + unsigned int ntime = 0; + Py_DECREF(key); + if (constObject != NULL) { +- typestr = constObject->name; ++ typestr = constObject->extra.name; + } + + if (snd_seq_ev_is_real(self->event)) { +-- +2.31.1 + diff --git a/0002-Fix-PyTuple_SET_ITEM-usage-no-return-value.patch b/0002-Fix-PyTuple_SET_ITEM-usage-no-return-value.patch new file mode 100644 index 0000000..476ff5e --- /dev/null +++ b/0002-Fix-PyTuple_SET_ITEM-usage-no-return-value.patch @@ -0,0 +1,49 @@ +From 5ea2f8709b4d091700750661231f8a3ddce0fc7c Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Thu, 10 Dec 2020 16:00:50 +0100 +Subject: [PATCH] Fix PyTuple_SET_ITEM() usage - no return value + +As noted in bpo-30459 (link bellow) the PyTuple_SET_ITEM() macro +has not a return value. Let's make code compatible with python 3.10. + +Link: https://bugs.python.org/issue30459 +BugLink: https://github.com/alsa-project/alsa-python/issues/2 +Signed-off-by: Jaroslav Kysela +--- + pyalsa/alsahcontrol.c | 4 ++-- + pyalsa/alsamixer.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/pyalsa/alsahcontrol.c b/pyalsa/alsahcontrol.c +index ebee1b7c094a..7c9321f811a0 100644 +--- a/pyalsa/alsahcontrol.c ++++ b/pyalsa/alsahcontrol.c +@@ -1543,8 +1543,8 @@ static int element_callback(snd_hctl_elem_t *elem, unsigned int mask) + + t = PyTuple_New(2); + if (t) { +- if (PyTuple_SET_ITEM(t, 0, (PyObject *)pyhelem)) +- Py_INCREF(pyhelem); ++ PyTuple_SET_ITEM(t, 0, (PyObject *)pyhelem); ++ Py_INCREF(pyhelem); + PyTuple_SET_ITEM(t, 1, PyInt_FromLong(mask)); + r = PyObject_CallObject(o, t); + Py_DECREF(t); +diff --git a/pyalsa/alsamixer.c b/pyalsa/alsamixer.c +index 39d7387500c4..91fe198c7b37 100644 +--- a/pyalsa/alsamixer.c ++++ b/pyalsa/alsamixer.c +@@ -1348,8 +1348,8 @@ static int element_callback(snd_mixer_elem_t *elem, unsigned int mask) + + t = PyTuple_New(2); + if (t) { +- if (PyTuple_SET_ITEM(t, 0, (PyObject *)pyelem)) +- Py_INCREF(pyelem); ++ PyTuple_SET_ITEM(t, 0, (PyObject *)pyelem); ++ Py_INCREF(pyelem); + PyTuple_SET_ITEM(t, 1, PyInt_FromLong(mask)); + r = PyObject_CallObject(o, t); + Py_DECREF(t); +-- +2.31.1 + diff --git a/python-alsa.changes b/python-alsa.changes index 3071e23..45768cd 100644 --- a/python-alsa.changes +++ b/python-alsa.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Dec 2 12:31:11 CET 2021 - tiwai@suse.de + +- Fix Obsoletes with version comparison +- Backport upstream fixes for python3: + 0001-alsaseq-fix-constant-objects-in-Python-3.patch + 0002-Fix-PyTuple_SET_ITEM-usage-no-return-value.patch + ------------------------------------------------------------------- Mon May 31 17:23:58 UTC 2021 - Ferdinand Thiessen diff --git a/python-alsa.spec b/python-alsa.spec index f522125..b82062f 100644 --- a/python-alsa.spec +++ b/python-alsa.spec @@ -27,12 +27,14 @@ URL: https://www.alsa-project.org Source: %{url}/files/pub/pyalsa/pyalsa-%{version}.tar.bz2 Source1: COPYING Source2: COPYING.LIB +Patch1: 0001-alsaseq-fix-constant-objects-in-Python-3.patch +Patch2: 0002-Fix-PyTuple_SET_ITEM-usage-no-return-value.patch BuildRequires: %{python_module devel} BuildRequires: %{python_module setuptools} BuildRequires: alsa-devel BuildRequires: python-rpm-macros Provides: pyalsa = %{version} -Obsoletes: pyalsa +Obsoletes: pyalsa < %{version} %python_subpackages %description @@ -40,6 +42,8 @@ This package provides the Python binding to ALSA. %prep %setup -q -n pyalsa-%{version} +%patch1 -p1 +%patch2 -p1 cp %{SOURCE1} %{SOURCE2} . %build