diff --git a/CMakeLists.txt b/CMakeLists.txt index 07102c211..6561e449c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.25) project( daisy - VERSION 7.1.4 + VERSION 7.1.5 DESCRIPTION "Mechanistic simulation of agricultural fields" HOMEPAGE_URL https://daisy.ku.dk/ LANGUAGES CXX C diff --git a/src/daisy/chemicals/adsorption_Python.C b/src/daisy/chemicals/adsorption_Python.C index 6fbc7598a..1b3f84870 100644 --- a/src/daisy/chemicals/adsorption_Python.C +++ b/src/daisy/chemicals/adsorption_Python.C @@ -66,10 +66,11 @@ struct AdsorptionPython : public Adsorption { py_module = pybind11::module::import (pmodule.name ().c_str ()); } - catch (...) + catch (std::exception &e) { Assertion::message ("Could not find Python module '" + pmodule + "."); + Assertion::message (e.what()); state = state_t::error; return; } @@ -79,10 +80,11 @@ struct AdsorptionPython : public Adsorption { py_C_to_M = py_module.attr(pC_to_M.name ().c_str ()); } - catch (...) + catch (std::exception &e) { Assertion::message ("Can't find Python function '" + pC_to_M + "' in '" + pmodule + "'."); + Assertion::message (e.what()); state = state_t::error; return; } @@ -93,10 +95,11 @@ struct AdsorptionPython : public Adsorption { py_M_to_C = py_module.attr(pM_to_C.name ().c_str ()); } - catch (...) + catch (std::exception &e) { Assertion::message ("Can't find Python function '" + pM_to_C + "' in '" + pmodule + "'."); + Assertion::message (e.what()); state = state_t::error; return; } @@ -141,10 +144,11 @@ public: pybind11::object py_object = py_C_to_M (**kwargs); return py_object.cast (); } - catch (...) + catch (std::exception &e) { Assertion::message ("Call to Python function '" + pC_to_M + "' in '" + pmodule + "' failed"); + Assertion::message (e.what()); const double Theta_sat = soil.Theta_sat (i); // [cm^3 W/cm^3 Sp] const double rho_b = soil.dry_bulk_density (i); // [g/cm^3 Sp] const double f_OC = soil.humus (i) * c_fraction_in_humus; // [g/g] @@ -204,10 +208,11 @@ public: pybind11::object py_object = py_M_to_C (**kwargs); return py_object.cast (); } - catch (...) + catch (std::exception &e) { Assertion::message ("Call to Python function '" + pM_to_C + "' in '" + pmodule + "' failed"); + Assertion::message (e.what()); const double Theta_sat = soil.Theta_sat (i); // [cm^3 W/cm^3 Sp] const double rho_b = soil.dry_bulk_density (i); // [g/cm^3 Sp] const double f_OC = soil.humus (i) * c_fraction_in_humus; // [g/g] diff --git a/src/daisy/chemicals/reaction_Python.C b/src/daisy/chemicals/reaction_Python.C index ee302ece8..ae8bb224a 100644 --- a/src/daisy/chemicals/reaction_Python.C +++ b/src/daisy/chemicals/reaction_Python.C @@ -169,10 +169,11 @@ struct ReactionPython : public Reaction array[i] = value; } } - catch (...) + catch (std::exception &e) { msg.error ("Call to Python function '" + psoil + "' in '" + pmodule + "' failed"); + msg.error (e.what()); state = state_t::error; break; } @@ -201,10 +202,11 @@ struct ReactionPython : public Reaction { pybind11::object py_object = py_top (); } - catch (...) + catch (std::exception &e) { msg.error ("Call to Python function '" + ptop + "' in '" + pmodule + "' failed"); + msg.error (e.what()); state = state_t::error; } return; @@ -251,15 +253,15 @@ struct ReactionPython : public Reaction case state_t::working: return; case state_t::uninitialized: - // Find module. try { py_module = pybind11::module::import (pmodule.name ().c_str ()); } - catch (...) + catch (std::exception &e) { Assertion::message ("Could not find Python module '" + pmodule + "'."); + Assertion::message (e.what()); state = state_t::error; return; } @@ -270,10 +272,11 @@ struct ReactionPython : public Reaction { py_soil = py_module.attr(psoil.name ().c_str ()); } - catch (...) + catch (std::exception &e) { Assertion::message ("Can't find Python function '" + psoil + "' in '" + pmodule + "'."); + Assertion::message (e.what()); state = state_t::error; return; } @@ -284,10 +287,11 @@ struct ReactionPython : public Reaction { py_top = py_module.attr(ptop.name ().c_str ()); } - catch (...) + catch (std::exception &e) { Assertion::message ("Can't find Python function '" + ptop + "' in '" + pmodule + "'."); + Assertion::message (e.what()); state = state_t::error; return; } diff --git a/src/object_model/function_Python.C b/src/object_model/function_Python.C index 4ab6d941f..530a83b3b 100644 --- a/src/object_model/function_Python.C +++ b/src/object_model/function_Python.C @@ -53,10 +53,11 @@ struct FunctionPython : public Function { py_module = pybind11::module::import (pmodule.name ().c_str ()); } - catch (...) + catch (std::exception &e) { Assertion::message ("Could not find Python module '" + pmodule + "."); + Assertion::message (e.what()); break; } @@ -65,10 +66,11 @@ struct FunctionPython : public Function { py_function = py_module.attr(pname.name ().c_str ()); } - catch (...) + catch (std::exception &e) { Assertion::message ("Can't find Python function '" + pname + "' in '" + pmodule + "'."); + Assertion::message (e.what()); break; } state = state_t::working; @@ -79,10 +81,11 @@ struct FunctionPython : public Function pybind11::object py_object = py_function (arg); return py_object.cast (); } - catch (...) + catch (std::exception &e) { Assertion::message ("Call to Python function '" + pname + "' in '" + pmodule + "' failed."); + Assertion::message (e.what()); } } state = state_t::error; diff --git a/src/object_model/toplevel.C b/src/object_model/toplevel.C index 438af46fc..666f1aeaa 100644 --- a/src/object_model/toplevel.C +++ b/src/object_model/toplevel.C @@ -51,6 +51,7 @@ struct Toplevel::Implementation : boost::noncopyable { #ifdef BUILD_PYTHON + // Start python interpreter pybind11::scoped_interpreter guard; #endif const symbol preferred_ui; @@ -506,6 +507,14 @@ Toplevel::command_line (int& argc, char**& argv) } #endif // _WIN32 +#ifdef BUILD_PYTHON + // Add any extra input directories to the python path + // This makes it possible for spawn programs that run in a subdirectory to access python files in + // the current directory. + pybind11::module_ sys = pybind11::module_::import("sys"); + pybind11::list path = sys.attr("path"); +#endif + // Loop over all arguments. bool options_finished = false; // "--" ends command line options. @@ -527,6 +536,11 @@ Toplevel::command_line (int& argc, char**& argv) { const std::string dir = get_arg (argc, argv); impl->metalib.path ().set_input_directory (dir); +#ifdef BUILD_PYTHON + // Add input directory to python path + path.append(dir); + msg().message ("Adding '" + dir + "' to pythonpath"); +# endif } break; case 'd':