From owner-svn-ports-all@freebsd.org Thu Dec 26 00:37:25 2019 Return-Path: Delivered-To: svn-ports-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 50F1F1E9004; Thu, 26 Dec 2019 00:37:25 +0000 (UTC) (envelope-from jbeich@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47jrdK2F1gz4Pjx; Thu, 26 Dec 2019 00:37:25 +0000 (UTC) (envelope-from jbeich@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 47E3A20930; Thu, 26 Dec 2019 00:37:25 +0000 (UTC) (envelope-from jbeich@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xBQ0bPCe075839; Thu, 26 Dec 2019 00:37:25 GMT (envelope-from jbeich@FreeBSD.org) Received: (from jbeich@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xBQ0bPWj075838; Thu, 26 Dec 2019 00:37:25 GMT (envelope-from jbeich@FreeBSD.org) Message-Id: <201912260037.xBQ0bPWj075838@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jbeich set sender to jbeich@FreeBSD.org using -f From: Jan Beich Date: Thu, 26 Dec 2019 00:37:25 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r520889 - in head/audio/alsa-lib: . files X-SVN-Group: ports-head X-SVN-Commit-Author: jbeich X-SVN-Commit-Paths: in head/audio/alsa-lib: . files X-SVN-Commit-Revision: 520889 X-SVN-Commit-Repository: ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the ports tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Dec 2019 00:37:25 -0000 Author: jbeich Date: Thu Dec 26 00:37:24 2019 New Revision: 520889 URL: https://svnweb.freebsd.org/changeset/ports/520889 Log: audio/alsa-lib: backport python3 support from 1.1.6 Added: head/audio/alsa-lib/files/patch-modules_mixer_simple_python.c (contents, props changed) Modified: head/audio/alsa-lib/Makefile (contents, props changed) Modified: head/audio/alsa-lib/Makefile ============================================================================== --- head/audio/alsa-lib/Makefile Thu Dec 26 00:37:18 2019 (r520888) +++ head/audio/alsa-lib/Makefile Thu Dec 26 00:37:24 2019 (r520889) @@ -28,7 +28,7 @@ OPTIONS_DEFINE= PYTHON OPTIONS_SUB= yes PYTHON_CONFIGURE_ENABLE=python -PYTHON_USES= python:2.7 +PYTHON_USES= python post-patch: .SILENT ${REINPLACE_CMD} -e '/LIBS/ { s/-ldl//g; s/-lrt//g; }' \ Added: head/audio/alsa-lib/files/patch-modules_mixer_simple_python.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/audio/alsa-lib/files/patch-modules_mixer_simple_python.c Thu Dec 26 00:37:24 2019 (r520889) @@ -0,0 +1,565 @@ +https://git.alsa-project.org/?p=alsa-lib.git;a=commitdiff;h=345843fc24b3 + +--- modules/mixer/simple/python.c.orig 2016-08-02 17:48:38 UTC ++++ modules/mixer/simple/python.c +@@ -25,6 +25,10 @@ + #include "asoundlib.h" + #include "mixer_abst.h" + ++#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) ++#pragma GCC diagnostic ignored "-Wstrict-aliasing" ++#endif ++ + struct python_priv { + int py_initialized; + PyObject *py_event_func; +@@ -56,20 +60,49 @@ struct pymixer { + + static PyInterpreterState *main_interpreter; + ++#if PY_MAJOR_VERSION >= 3 ++ #define PyInt_FromLong PyLong_FromLong ++#endif ++ ++static inline int get_long(PyObject *o, long *val) ++{ ++#if PY_MAJOR_VERSION < 3 ++ if (PyInt_Check(o)) { ++ *val = PyInt_AsLong(o); ++ return 0; ++ } ++#endif ++ if (PyLong_Check(o)) { ++ *val = PyLong_AsLong(o); ++ return 0; ++ } ++ return 1; ++} ++ ++static inline PyObject *InternFromString(const char *name) ++{ ++#if PY_MAJOR_VERSION < 3 ++ return PyString_InternFromString(name); ++#else ++ return PyUnicode_InternFromString(name); ++#endif ++} ++ + static void *get_C_ptr(PyObject *obj, const char *attr) + { + PyObject *o; ++ long val; + +- o = PyObject_GetAttr(obj, PyString_InternFromString(attr)); ++ o = PyObject_GetAttr(obj, InternFromString(attr)); + if (!o) { + PyErr_Format(PyExc_TypeError, "missing '%s' attribute", attr); + return NULL; + } +- if (!PyInt_Check(o)) { +- PyErr_Format(PyExc_TypeError, "'%s' attribute is not integer", attr); ++ if (get_long(o, &val)) { ++ PyErr_Format(PyExc_TypeError, "'%s' attribute is not Int or Long", attr); + return NULL; + } +- return (void *)PyInt_AsLong(o); ++ return (void *)val; + } + + static struct pymelem *melem_to_pymelem(snd_mixer_elem_t *elem) +@@ -80,11 +113,11 @@ static struct pymelem *melem_to_pymelem(snd_mixer_elem + static int pcall(struct pymelem *pymelem, const char *attr, PyObject *args, PyObject **_res) + { + PyObject *obj = (PyObject *)pymelem, *res; +- int xres = 0; ++ long xres = 0; + + if (_res) + *_res = NULL; +- obj = PyObject_GetAttr(obj, PyString_InternFromString(attr)); ++ obj = PyObject_GetAttr(obj, InternFromString(attr)); + if (!obj) { + PyErr_Format(PyExc_TypeError, "missing '%s' attribute", attr); + PyErr_Print(); +@@ -103,8 +136,12 @@ static int pcall(struct pymelem *pymelem, const char * + *_res = res; + res = PyTuple_GetItem(res, 0); + } +- if (PyInt_Check(res)) { ++ if (PyLong_Check(res)) { ++ xres = PyLong_AsLong(res); ++#if PY_MAJOR_VERSION < 3 ++ } else if (PyInt_Check(res)) { + xres = PyInt_AsLong(res); ++#endif + } else if (res == Py_None) { + xres = 0; + } else if (PyBool_Check(res)) { +@@ -155,7 +192,7 @@ static int is_ops(snd_mixer_elem_t *elem, int dir, int + static int get_x_range_ops(snd_mixer_elem_t *elem, int dir, + long *min, long *max, const char *attr) + { +- PyObject *obj1, *res; ++ PyObject *obj1, *t1, *t2, *res; + struct pymelem *pymelem = melem_to_pymelem(elem); + int err; + +@@ -163,21 +200,23 @@ static int get_x_range_ops(snd_mixer_elem_t *elem, int + PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(dir)); + err = pcall(pymelem, attr, obj1, &res); + if (err >= 0) { +- err = !PyInt_Check(PyTuple_GetItem(res, 1)) || !PyInt_Check(PyTuple_GetItem(res, 2)); +- if (err) { +- err = !PyLong_Check(PyTuple_GetItem(res, 1)) || !PyLong_Check(PyTuple_GetItem(res, 2)); +- if (err) { +- PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); +- PyErr_Print(); +- PyErr_Clear(); +- err = -EIO; +- } else { +- *min = PyLong_AsLong(PyTuple_GetItem(res, 1)); +- *max = PyLong_AsLong(PyTuple_GetItem(res, 2)); +- } +- } else { ++ t1 = PyTuple_GetItem(res, 1); ++ t2 = PyTuple_GetItem(res, 2); ++ if (PyLong_Check(t1) && PyLong_Check(t2)) { ++ *min = PyLong_AsLong(PyTuple_GetItem(res, 1)); ++ *max = PyLong_AsLong(PyTuple_GetItem(res, 2)); ++ err = 0; ++#if PY_MAJOR_VERSION < 3 ++ } else if (PyInt_Check(t1) && PyInt_Check(t2)) { + *min = PyInt_AsLong(PyTuple_GetItem(res, 1)); + *max = PyInt_AsLong(PyTuple_GetItem(res, 2)); ++ err = 0; ++#endif ++ } else { ++ PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); ++ PyErr_Print(); ++ PyErr_Clear(); ++ err = -EIO; + } + } + Py_XDECREF(res); +@@ -207,7 +246,7 @@ static int get_x_ops(snd_mixer_elem_t *elem, int dir, + long channel, long *value, + const char *attr) + { +- PyObject *obj1, *res; ++ PyObject *obj1, *t1, *res; + struct pymelem *pymelem = melem_to_pymelem(elem); + int err; + +@@ -216,19 +255,20 @@ static int get_x_ops(snd_mixer_elem_t *elem, int dir, + PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong(channel)); + err = pcall(pymelem, attr, obj1, &res); + if (err >= 0) { +- err = !PyInt_Check(PyTuple_GetItem(res, 1)); +- if (err) { +- err = !PyLong_Check(PyTuple_GetItem(res, 1)); +- if (err) { +- PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); +- PyErr_Print(); +- PyErr_Clear(); +- err = -EIO; +- } else { +- *value = PyLong_AsLong(PyTuple_GetItem(res, 1)); +- } ++ t1 = PyTuple_GetItem(res, 1); ++ if (PyLong_Check(t1)) { ++ *value = PyLong_AsLong(t1); ++ err = 0; ++#if PY_MAJOR_VERSION < 3 ++ } else if (PyInt_Check(t1)) { ++ *value = PyInt_AsLong(t1); ++ err = 0; ++#endif + } else { +- *value = PyInt_AsLong(PyTuple_GetItem(res, 1)); ++ PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); ++ PyErr_Print(); ++ PyErr_Clear(); ++ err = -EIO; + } + } + Py_XDECREF(res); +@@ -265,7 +305,7 @@ static int ask_dB_vol_ops(snd_mixer_elem_t *elem, + long *dbValue, + int xdir) + { +- PyObject *obj1, *res; ++ PyObject *obj1, *t1, *res; + struct pymelem *pymelem = melem_to_pymelem(elem); + int err; + +@@ -275,19 +315,20 @@ static int ask_dB_vol_ops(snd_mixer_elem_t *elem, + PyTuple_SET_ITEM(obj1, 2, PyInt_FromLong(xdir)); + err = pcall(pymelem, "opsGetDBVol", obj1, &res); + if (err >= 0) { +- err = !PyInt_Check(PyTuple_GetItem(res, 1)); +- if (err) { +- err = !PyLong_Check(PyTuple_GetItem(res, 1)); +- if (err) { +- PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); +- PyErr_Print(); +- PyErr_Clear(); +- err = -EIO; +- } else { +- *dbValue = PyLong_AsLong(PyTuple_GetItem(res, 1)); +- } ++ t1 = PyTuple_GetItem(res, 1); ++ if (PyLong_Check(t1)) { ++ *dbValue = PyLong_AsLong(t1); ++ err = 0; ++#if PY_MAJOR_VERSION < 3 ++ } else if (PyInt_Check(t1)) { ++ *dbValue = PyInt_AsLong(t1); ++ err = 0; ++#endif + } else { +- *dbValue = PyInt_AsLong(PyTuple_GetItem(res, 1)); ++ PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); ++ PyErr_Print(); ++ PyErr_Clear(); ++ err = -EIO; + } + } + Py_XDECREF(res); +@@ -353,7 +394,7 @@ static int enum_item_name_ops(snd_mixer_elem_t *elem, + unsigned int item, + size_t maxlen, char *buf) + { +- PyObject *obj1, *res; ++ PyObject *obj1, *obj2, *t1, *res; + struct pymelem *pymelem = melem_to_pymelem(elem); + int err; + unsigned int len; +@@ -363,19 +404,35 @@ static int enum_item_name_ops(snd_mixer_elem_t *elem, + PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(item)); + err = pcall(pymelem, "opsGetEnumItemName", obj1, &res); + if (err >= 0) { +- err = !PyString_Check(PyTuple_GetItem(res, 1)); +- if (err) { +- PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); +- PyErr_Print(); +- PyErr_Clear(); +- err = -EIO; +- } else { +- s = PyString_AsString(PyTuple_GetItem(res, 1)); ++ t1 = PyTuple_GetItem(res, 1); ++ if (PyUnicode_Check(t1)) { ++ obj2 = PyUnicode_AsEncodedString(t1, "utf-8", "strict"); ++ if (obj2) { ++ s = PyBytes_AsString(obj2); ++ len = strlen(s); ++ if (maxlen - 1 > len) ++ len = maxlen - 1; ++ memcpy(buf, s, len); ++ buf[len] = '\0'; ++ Py_DECREF(obj2); ++ } else { ++ goto errlbl; ++ } ++#if PY_MAJOR_VERSION < 3 ++ } else if (PyString_Check(t1)) { ++ s = PyString_AsString(t1); + len = strlen(s); + if (maxlen - 1 > len) + len = maxlen - 1; + memcpy(buf, s, len); + buf[len] = '\0'; ++#endif ++ } else { ++errlbl: ++ PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); ++ PyErr_Print(); ++ PyErr_Clear(); ++ err = -EIO; + } + } + Py_XDECREF(res); +@@ -386,7 +443,7 @@ static int get_enum_item_ops(snd_mixer_elem_t *elem, + snd_mixer_selem_channel_id_t channel, + unsigned int *itemp) + { +- PyObject *obj1, *res; ++ PyObject *obj1, *t1, *res; + struct pymelem *pymelem = melem_to_pymelem(elem); + int err; + +@@ -394,14 +451,20 @@ static int get_enum_item_ops(snd_mixer_elem_t *elem, + PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(channel)); + err = pcall(pymelem, "opsGetEnumItem", obj1, &res); + if (err >= 0) { +- err = !PyInt_Check(PyTuple_GetItem(res, 1)); +- if (err) { ++ t1 = PyTuple_GetItem(res, 1); ++ if (PyLong_Check(t1)) { ++ *itemp = PyLong_AsLong(t1); ++ err = 0; ++#if PY_MAJOR_VERSION < 3 ++ } else if (PyInt_Check(t1)) { ++ *itemp = PyInt_AsLong(t1); ++ err = 0; ++#endif ++ } else { + PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); + PyErr_Print(); + PyErr_Clear(); + err = -EIO; +- } else { +- *itemp = PyInt_AsLong(PyTuple_GetItem(res, 1)); + } + } + Py_XDECREF(res); +@@ -464,7 +527,7 @@ pymelem_get_caps(struct pymelem *pymelem, void *priv A + static PyObject * + pymelem_get_name(struct pymelem *pymelem, void *priv ATTRIBUTE_UNUSED) + { +- return PyString_FromString(snd_mixer_selem_id_get_name(pymelem->selem.id)); ++ return PyUnicode_FromString(snd_mixer_selem_id_get_name(pymelem->selem.id)); + } + + static PyObject * +@@ -476,12 +539,18 @@ pymelem_get_index(struct pymelem *pymelem, void *priv + static int + pymelem_set_caps(struct pymelem *pymelem, PyObject *val, void *priv ATTRIBUTE_UNUSED) + { +- if (!PyInt_Check(val)) { +- PyErr_SetString(PyExc_TypeError, "The last attribute value must be an integer"); +- return -1; ++ if (PyLong_Check(val)) { ++ pymelem->selem.caps = PyLong_AsLong(val); ++ return 0; + } +- pymelem->selem.caps = PyInt_AsLong(val); +- return 0; ++#if PY_MAJOR_VERSION < 3 ++ if (PyInt_Check(val)) { ++ pymelem->selem.caps = PyInt_AsLong(val); ++ return 0; ++ } ++#endif ++ PyErr_SetString(PyExc_TypeError, "The last attribute value must be an integer"); ++ return -1; + } + + static PyObject * +@@ -588,7 +657,6 @@ static void + pymelem_dealloc(struct pymelem *self) + { + selem_free(self->melem); +- self->ob_type->tp_free(self); + } + + static PyGetSetDef pymelem_getseters[] = { +@@ -634,7 +702,7 @@ static PyMethodDef pymelem_methods[] = { + }; + + static PyTypeObject pymelem_type = { +- PyObject_HEAD_INIT(0) ++ PyVarObject_HEAD_INIT(NULL, 0) + tp_name: "smixer_python.InternalMElement", + tp_basicsize: sizeof(struct pymelem), + tp_dealloc: (destructor)pymelem_dealloc, +@@ -708,7 +776,7 @@ pymixer_melement_new(struct pymixer *pymixer, PyObject + obj1 = PyTuple_New(4); + if (PyTuple_SET_ITEM(obj1, 0, (PyObject *)pymixer)) + Py_INCREF((PyObject *)pymixer); +- PyTuple_SET_ITEM(obj1, 1, PyString_FromString(name)); ++ PyTuple_SET_ITEM(obj1, 1, PyUnicode_FromString(name)); + PyTuple_SET_ITEM(obj1, 2, PyInt_FromLong(index)); + PyTuple_SET_ITEM(obj1, 3, PyInt_FromLong(weight)); + obj2 = PyObject_CallObject(obj, obj1); +@@ -800,7 +868,6 @@ static void + pymixer_dealloc(struct pymixer *self) + { + pymixer_free(self); +- self->ob_type->tp_free(self); + } + + static PyGetSetDef pymixer_getseters[] = { +@@ -816,7 +883,7 @@ static PyMethodDef pymixer_methods[] = { + }; + + static PyTypeObject pymixer_type = { +- PyObject_HEAD_INIT(0) ++ PyVarObject_HEAD_INIT(NULL, 0) + tp_name: "smixer_python.InternalMixer", + tp_basicsize: sizeof(struct pymixer), + tp_dealloc: (destructor)pymixer_dealloc, +@@ -910,12 +977,12 @@ int alsa_mixer_simple_event(snd_mixer_class_t *class, + snd_hctl_elem_t *helem, snd_mixer_elem_t *melem) + { + struct python_priv *priv = snd_mixer_sbasic_get_private(class); +- PyThreadState *tstate, *origstate; ++ PyThreadState *tstate; + PyObject *t, *o, *r; + int res = -ENOMEM; + + tstate = PyThreadState_New(main_interpreter); +- origstate = PyThreadState_Swap(tstate); ++ PyThreadState_Swap(tstate); + + t = PyTuple_New(3); + if (t) { +@@ -935,8 +1002,12 @@ int alsa_mixer_simple_event(snd_mixer_class_t *class, + r = PyObject_CallObject(priv->py_event_func, t); + Py_DECREF(t); + if (r) { +- if (PyInt_Check(r)) { ++ if (PyLong_Check(r)) { ++ res = PyLong_AsLong(r); ++#if PY_MAJOR_VERSION < 3 ++ } else if (PyInt_Check(r)) { + res = PyInt_AsLong(r); ++#endif + } else if (r == Py_None) { + res = 0; + } +@@ -966,6 +1037,71 @@ static void alsa_mixer_simple_free(snd_mixer_class_t * + free(priv); + } + ++static int alsa_mixer_simple_pyinit(struct python_priv *priv, ++ PyObject *py_mod, ++ FILE *fp, ++ const char *file, ++ snd_mixer_class_t *class, ++ snd_mixer_t *mixer, ++ const char *device) ++{ ++ PyObject *obj, *obj1, *obj2, *mdict; ++ ++ mdict = priv->py_mdict = PyModule_GetDict(py_mod); ++ obj = PyUnicode_FromString(file); ++ if (obj) ++ PyDict_SetItemString(mdict, "__file__", obj); ++ Py_XDECREF(obj); ++ obj = PyUnicode_FromString(device); ++ if (obj) ++ PyDict_SetItemString(mdict, "device", obj); ++ Py_XDECREF(obj); ++ Py_INCREF(&pymelem_type); ++ Py_INCREF(&pymixer_type); ++ PyModule_AddObject(py_mod, "InternalMElement", (PyObject *)&pymelem_type); ++ PyModule_AddObject(py_mod, "InternalMixer", (PyObject *)&pymixer_type); ++ obj = PyDict_GetItemString(mdict, "InternalMixer"); ++ if (obj) { ++ obj1 = PyTuple_New(3); ++ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong((long)class)); ++ PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong((long)mixer)); ++ if (PyTuple_SET_ITEM(obj1, 2, mdict)) ++ Py_INCREF(mdict); ++ obj2 = PyObject_CallObject(obj, obj1); ++ Py_XDECREF(obj1); ++ PyDict_SetItemString(mdict, "mixer", obj2); ++ priv->py_mixer = obj2; ++ } else { ++ SNDERR("Unable to create InternalMixer object"); ++ return -EIO; ++ } ++ ++ obj = PyRun_FileEx(fp, file, Py_file_input, mdict, mdict, 1); ++ if (obj == NULL) ++ PyErr_Print(); ++ Py_XDECREF(obj); ++ priv->py_event_func = PyDict_GetItemString(mdict, "event"); ++ if (priv->py_event_func == NULL) { ++ SNDERR("Unable to find python function 'event'"); ++ return -EIO; ++ } ++ return 0; ++} ++ ++#if PY_MAJOR_VERSION >= 3 ++static struct PyModuleDef smixer_python_module = { ++ PyModuleDef_HEAD_INIT, ++ "smixer_python", ++ NULL, ++ 0, ++ python_methods, ++ NULL, ++ NULL, ++ NULL, ++ NULL ++}; ++#endif ++ + int alsa_mixer_simple_finit(snd_mixer_class_t *class, + snd_mixer_t *mixer, + const char *device) +@@ -973,7 +1109,7 @@ int alsa_mixer_simple_finit(snd_mixer_class_t *class, + struct python_priv *priv; + FILE *fp; + const char *file; +- PyObject *obj, *obj1, *obj2, *py_mod, *mdict; ++ PyObject *obj, *py_mod; + + priv = calloc(1, sizeof(*priv)); + if (priv == NULL) +@@ -993,54 +1129,21 @@ int alsa_mixer_simple_finit(snd_mixer_class_t *class, + } + + Py_Initialize(); +- if (PyType_Ready(&pymelem_type) < 0) ++ if (PyType_Ready(&pymelem_type) < 0 || ++ PyType_Ready(&pymixer_type) < 0) { ++ fclose(fp); + return -EIO; +- if (PyType_Ready(&pymixer_type) < 0) +- return -EIO; ++ } ++#if PY_MAJOR_VERSION < 3 + Py_InitModule("smixer_python", python_methods); ++#else ++ PyModule_Create(&smixer_python_module); ++#endif + priv->py_initialized = 1; + main_interpreter = PyThreadState_Get()->interp; + obj = PyImport_GetModuleDict(); + py_mod = PyDict_GetItemString(obj, "__main__"); +- if (py_mod) { +- mdict = priv->py_mdict = PyModule_GetDict(py_mod); +- obj = PyString_FromString(file); +- if (obj) +- PyDict_SetItemString(mdict, "__file__", obj); +- Py_XDECREF(obj); +- obj = PyString_FromString(device); +- if (obj) +- PyDict_SetItemString(mdict, "device", obj); +- Py_XDECREF(obj); +- Py_INCREF(&pymixer_type); +- PyModule_AddObject(py_mod, "InternalMElement", (PyObject *)&pymelem_type); +- PyModule_AddObject(py_mod, "InternalMixer", (PyObject *)&pymixer_type); +- obj = PyDict_GetItemString(mdict, "InternalMixer"); +- if (obj) { +- obj1 = PyTuple_New(3); +- PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong((long)class)); +- PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong((long)mixer)); +- if (PyTuple_SET_ITEM(obj1, 2, mdict)) +- Py_INCREF(mdict); +- obj2 = PyObject_CallObject(obj, obj1); +- Py_XDECREF(obj1); +- PyDict_SetItemString(mdict, "mixer", obj2); +- priv->py_mixer = obj2; +- } else { +- SNDERR("Unable to create InternalMixer object"); +- return -EIO; +- } +- +- +- obj = PyRun_FileEx(fp, file, Py_file_input, mdict, mdict, 1); +- if (obj == NULL) +- PyErr_Print(); +- Py_XDECREF(obj); +- priv->py_event_func = PyDict_GetItemString(mdict, "event"); +- if (priv->py_event_func == NULL) { +- SNDERR("Unable to find python function 'event'"); +- return -EIO; +- } +- } ++ if (py_mod) ++ alsa_mixer_simple_pyinit(priv, py_mod, fp, file, class, mixer, device); + return 0; + }