From 2c77b8292329f00fd22e9542848c1a32888ca8f5 Mon Sep 17 00:00:00 2001 From: Andy Clayton Date: Tue, 24 Mar 2020 23:57:51 -0500 Subject: py3: fix builtin ledger module for python command With python3 the `python` ledger command wound up loading the ledger module shared library rather than using the builtin module as intended. This resulted in duplicated initialization and crashing on cleanup. It was also visible as duplicate converter warnings when importing ledger: $ ./ledger --no-pager python Python 3.7.5 (default, Nov 20 2019, 09:21:52) [...] >>> import ledger /usr/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: to-Python converter for boost::posix_time::ptime already registered; second conversion method ignored. [...] /usr/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: to-Python converter for ledger::xact_t already registered; second conversion method ignored. [...] >>> ledger >>> exit() Segmentation fault (core dumped) After this change: Python 3.7.5 (default, Nov 20 2019, 09:21:52) [...] >>> import ledger >>> ledger >>> exit() $ Switches to PyImport_AppendInittab from python::detail::init_module because 1) that is what the boost docs and examples show and 2) init_module appears to be undocumented and not intended for outside use. Fixes #1867 --- src/pyinterp.cc | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'src/pyinterp.cc') diff --git a/src/pyinterp.cc b/src/pyinterp.cc index aeafd2bd..5381758e 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -61,6 +61,10 @@ void export_utils(); void export_value(); void export_xact(); +#if PY_MAJOR_VERSION >= 3 +extern "C" PyObject* PyInit_ledger(); +#endif + void initialize_for_python() { export_times(); @@ -146,26 +150,19 @@ void python_interpreter_t::initialize() try { DEBUG("python.interp", "Initializing Python"); +#if PY_MAJOR_VERSION >= 3 + // PyImport_AppendInittab docs: "This should be called before Py_Initialize()". + PyImport_AppendInittab((char*)"ledger", PyInit_ledger); +#endif + Py_Initialize(); assert(Py_IsInitialized()); hack_system_paths(); main_module = import_module("__main__"); - #if PY_MAJOR_VERSION >= 3 - static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "ledger", /* m_name */ - NULL, /* m_doc */ - -1, /* m_size */ - NULL, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ - }; - python::detail::init_module(moduledef, &initialize_for_python); + PyImport_ImportModule("ledger"); #else python::detail::init_module("ledger", &initialize_for_python); #endif -- cgit v1.2.3