From 7d742f704fd495fc6b4cda85e0ee0f517bb77797 Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 18 Jul 2016 01:27:23 +0100 Subject: [PATCH] Fix prof module init for python3 --- configure-debug | 1 + configure.ac | 1 - src/plugins/python_api.c | 36 +++++++++++++++++++-------------- src/plugins/python_api.h | 4 +++- src/plugins/python_plugins.c | 39 +++++++++++++++++++++++++----------- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/configure-debug b/configure-debug index a787e746..82734474 100755 --- a/configure-debug +++ b/configure-debug @@ -1,3 +1,4 @@ #!/bin/sh ./configure PYTHON_VERSION=3 CFLAGS='-g3 -O0' CXXFLAGS='-g3 -O0' --enable-python-plugins $@ +#./configure CFLAGS='-g3 -O0' CXXFLAGS='-g3 -O0' --enable-python-plugins $@ diff --git a/configure.ac b/configure.ac index e6ee131e..8d06ecfe 100644 --- a/configure.ac +++ b/configure.ac @@ -96,7 +96,6 @@ elif test "x$enable_python_plugins" = xyes; then fi fi AS_IF([test "x$PLATFORM" = xosx], [rm -f Python.framework]) - AS_IF([test "x$PYTHON_VERSION" = x3], [AC_DEFINE([PYTHON3], [1], [Python 3 build])]) else AM_CONDITIONAL([BUILD_PYTHON_API], [false]) fi diff --git a/src/plugins/python_api.c b/src/plugins/python_api.c index 70e67820..e0d54c1c 100644 --- a/src/plugins/python_api.c +++ b/src/plugins/python_api.c @@ -130,7 +130,7 @@ python_api_register_command(PyObject *self, PyObject *args) Py_ssize_t i = 0; for (i = 0; i < len; i++) { PyObject *item = PyList_GetItem(synopsis, i); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 char *c_item = PyBytes_AS_STRING(PyUnicode_AsUTF8String(item)); #else char *c_item = PyString_AsString(item); @@ -149,14 +149,14 @@ python_api_register_command(PyObject *self, PyObject *args) return Py_BuildValue(""); } PyObject *arg = PyList_GetItem(item, 0); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 char *c_arg = PyBytes_AS_STRING(PyUnicode_AsUTF8String(arg)); #else char *c_arg = PyString_AsString(arg); #endif PyObject *desc = PyList_GetItem(item, 1); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 char *c_desc = PyBytes_AS_STRING(PyUnicode_AsUTF8String(desc)); #else char *c_desc = PyString_AsString(desc); @@ -173,7 +173,7 @@ python_api_register_command(PyObject *self, PyObject *args) i = 0; for (i = 0; i < len; i++) { PyObject *item = PyList_GetItem(examples, i); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 char *c_item = PyBytes_AS_STRING(PyUnicode_AsUTF8String(item)); #else char *c_item = PyString_AsString(item); @@ -236,7 +236,7 @@ python_api_completer_add(PyObject *self, PyObject *args) Py_ssize_t i = 0; for (i = 0; i < len; i++) { PyObject *item = PyList_GetItem(items, i); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 char *c_item = PyBytes_AS_STRING(PyUnicode_AsUTF8String(item)); #else char *c_item = PyString_AsString(item); @@ -273,7 +273,7 @@ python_api_completer_remove(PyObject *self, PyObject *args) Py_ssize_t i = 0; for (i = 0; i < len; i++) { PyObject *item = PyList_GetItem(items, i); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 char *c_item = PyBytes_AS_STRING(PyUnicode_AsUTF8String(item)); #else char *c_item = PyString_AsString(item); @@ -809,7 +809,7 @@ python_window_callback(PluginWindowCallback *window_callback, char *tag, char *l static PyMethodDef apiMethods[] = { { "cons_alert", python_api_cons_alert, METH_NOARGS, "Highlight the console window in the status bar." }, - { "cons_show", (PyCFunction)python_api_cons_show, METH_VARARGS, "Print a line to the console." }, + { "cons_show", python_api_cons_show, METH_VARARGS, "Print a line to the console." }, { "cons_show_themed", python_api_cons_show_themed, METH_VARARGS, "Print a themed line to the console" }, { "cons_bad_cmd_usage", python_api_cons_bad_cmd_usage, METH_VARARGS, "Show invalid command message in console" }, { "register_command", python_api_register_command, METH_VARARGS, "Register a command." }, @@ -845,22 +845,28 @@ static PyMethodDef apiMethods[] = { { NULL, NULL, 0, NULL } }; -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 static struct PyModuleDef profModule = { PyModuleDef_HEAD_INIT, - "prof", /* name of module */ - "", /* module documentation, may be NULL */ - -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ + "prof", + "", + -1, apiMethods }; #endif -void +PyMODINIT_FUNC python_api_init(void) { -#ifdef PYTHON3 - PyModule_Create(&profModule); +#if PY_MAJOR_VERSION >= 3 + PyObject *result = PyModule_Create(&profModule); + if (!result) { + log_debug("Failed to initialise prof module"); + } else { + log_debug("Initialised prof module"); + } + return result; #else Py_InitModule("prof", apiMethods); #endif @@ -871,7 +877,7 @@ _python_plugin_name(void) { PyThreadState *ts = PyThreadState_Get(); PyFrameObject *frame = ts->frame; -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 char const *filename = PyBytes_AS_STRING(PyUnicode_AsUTF8String(frame->f_code->co_filename)); #else char const* filename = PyString_AsString(frame->f_code->co_filename); diff --git a/src/plugins/python_api.h b/src/plugins/python_api.h index f936a9cb..339ac06b 100644 --- a/src/plugins/python_api.h +++ b/src/plugins/python_api.h @@ -35,8 +35,10 @@ #ifndef PYTHON_API_H #define PYTHON_API_H +#include + void python_env_init(void); -void python_api_init(void); +PyMODINIT_FUNC python_api_init(void); void python_shutdown(void); void python_command_callback(PluginCommand *command, gchar **args); diff --git a/src/plugins/python_plugins.c b/src/plugins/python_plugins.c index ab50c10e..670dd46f 100644 --- a/src/plugins/python_plugins.c +++ b/src/plugins/python_plugins.c @@ -68,22 +68,34 @@ _unref_module(PyObject *module) void python_env_init(void) { + loaded_modules = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_unref_module); +#if PY_MAJOR_VERSION >= 3 + PyImport_AppendInittab("prof", python_api_init); + Py_Initialize(); + PyEval_InitThreads(); +#else Py_Initialize(); PyEval_InitThreads(); python_api_init(); +#endif + const char *ver = Py_GetVersion(); + cons_show("PYTHON: %s", ver); + + gchar *plugins_dir = plugins_get_dir(); GString *path = g_string_new("import sys\n"); g_string_append(path, "sys.path.append(\""); - gchar *plugins_dir = plugins_get_dir(); g_string_append(path, plugins_dir); - g_free(plugins_dir); g_string_append(path, "/\")\n"); PyRun_SimpleString(path->str); + python_check_error(); g_string_free(path, TRUE); + g_free(plugins_dir); + allow_python_threads(); } @@ -98,7 +110,9 @@ python_plugin_create(const char *const filename) } else { gchar *module_name = g_strndup(filename, strlen(filename) - 3); p_module = PyImport_ImportModule(module_name); - g_hash_table_insert(loaded_modules, strdup(filename), p_module); + if (p_module) { + g_hash_table_insert(loaded_modules, strdup(filename), p_module); + } g_free(module_name); } @@ -280,7 +294,7 @@ python_pre_chat_message_display_hook(ProfPlugin *plugin, const char *const jid, python_check_error(); Py_XDECREF(p_function); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 if (result != Py_None) { char *result_str = strdup(PyBytes_AS_STRING(PyUnicode_AsUTF8String(result))); Py_XDECREF(result); @@ -350,7 +364,7 @@ python_pre_chat_message_send_hook(ProfPlugin *plugin, const char * const jid, co python_check_error(); Py_XDECREF(p_function); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 if (result != Py_None) { char *result_str = strdup(PyBytes_AS_STRING(PyUnicode_AsUTF8String(result))); Py_XDECREF(result); @@ -420,7 +434,7 @@ python_pre_room_message_display_hook(ProfPlugin *plugin, const char * const room python_check_error(); Py_XDECREF(p_function); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 if (result != Py_None) { char *result_str = strdup(PyBytes_AS_STRING(PyUnicode_AsUTF8String(result))); Py_XDECREF(result); @@ -491,7 +505,7 @@ python_pre_room_message_send_hook(ProfPlugin *plugin, const char *const room, co python_check_error(); Py_XDECREF(p_function); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 if (result != Py_None) { char *result_str = strdup(PyBytes_AS_STRING(PyUnicode_AsUTF8String(result))); Py_XDECREF(result); @@ -584,7 +598,7 @@ python_pre_priv_message_display_hook(ProfPlugin *plugin, const char *const room, python_check_error(); Py_XDECREF(p_function); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 if (result != Py_None) { char *result_str = strdup(PyBytes_AS_STRING(PyUnicode_AsUTF8String(result))); Py_XDECREF(result); @@ -656,7 +670,7 @@ python_pre_priv_message_send_hook(ProfPlugin *plugin, const char *const room, co python_check_error(); Py_XDECREF(p_function); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 if (result != Py_None) { char *result_str = strdup(PyBytes_AS_STRING(PyUnicode_AsUTF8String(result))); Py_XDECREF(result); @@ -727,7 +741,7 @@ python_on_message_stanza_send_hook(ProfPlugin *plugin, const char *const text) python_check_error(); Py_XDECREF(p_function); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 if (result != Py_None) { char *result_str = strdup(PyBytes_AS_STRING(PyUnicode_AsUTF8String(result))); Py_XDECREF(result); @@ -805,7 +819,7 @@ python_on_presence_stanza_send_hook(ProfPlugin *plugin, const char *const text) python_check_error(); Py_XDECREF(p_function); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 if (result != Py_None) { char *result_str = strdup(PyBytes_AS_STRING(PyUnicode_AsUTF8String(result))); Py_XDECREF(result); @@ -883,7 +897,7 @@ python_on_iq_stanza_send_hook(ProfPlugin *plugin, const char *const text) python_check_error(); Py_XDECREF(p_function); -#ifdef PYTHON3 +#if PY_MAJOR_VERSION >= 3 if (result != Py_None) { char *result_str = strdup(PyBytes_AS_STRING(PyUnicode_AsUTF8String(result))); Py_XDECREF(result); @@ -1036,6 +1050,7 @@ python_check_error(void) { if (PyErr_Occurred()) { PyErr_Print(); + PyRun_SimpleString("import sys\nsys.stdout.flush()"); PyErr_Clear(); } }