Flow123d  release_3.0.0-1106-ga3b2e4c
python_loader.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file python_loader.hh
15  * @brief
16  */
17 
18 #ifndef PYTHON_UTILS_HH_
19 #define PYTHON_UTILS_HH_
20 
21 #include <boost/exception/info.hpp> // for error_info::~error_info<Tag, T>
22 #include "config.h" // for FLOW123D_HAVE_PYTHON
23 #include "Python.h" // for PyObject
24 #include "system/exceptions.hh" // for ExcStream, operator<<, DECLARE_E...
25 
26 #ifdef FLOW123D_HAVE_PYTHON
27 
28 #include <string>
29 
30 /*
31  * Notes on Python 3 API
32  *
33  * - PyObject * PyUnicode_FromString(const char * u):
34  * Create a Unicode object from a UTF-8 encoded
35  * null-terminated char buffer u
36  *
37  * - const char * PyUnicode_AsUTF8(PyObject *unicode):
38  * Return a pointer to the UTF-8 encoding of the Unicode object.
39  * Reverse action of PyUnicode_FromString.
40  *
41  * Our functions are only converting from string to wstring and back during
42  * initialization
43  *
44  * - wstring to_py_string(const string &str):
45  * useful when setting program name, and altering path
46  *
47  * - string from_py_string(const wstring &wstr):
48  * so far no usage in the program, but serves for converting wstring to
49  * string
50  */
51 
52 
53 namespace internal {
54 /**
55  * Class to implement initialization and finalization of the python module
56  */
57 class PythonRunning {
58 public:
59  PythonRunning(const std::string &python_home);
60  ~PythonRunning();
61 };
62 } // close namespace internal
63 
64 
65 
66 /**
67  * Class with static only members, should be used to load and compile Python sources either from file or from string.
68  * Implement correct initialization and finalization.
69  * TODO:
70  * - check validity of results and throw exceptions
71  * - better loading of modules from files
72  * - explain and resolve RuntimeWarning:
73  * "flow123d_python_loader:1: RuntimeWarning: Parent module 'field_python_script' not found while handling absolute import"
74  * that appears during field_python_test.cpp
75  *
76  */
77 class PythonLoader {
78 public:
79 
80  /**
81  * Definition of exception thrown by python compiler or interpreter.
82  */
83  TYPEDEF_ERR_INFO(EI_PythonMessage, std::string);
84  DECLARE_EXCEPTION(ExcPythonError,
85  << "Python Error: " << EI_PythonMessage::val << "\n");
86 
87 
88  /**
89  * Calls python initialization and guarantee that appropriate finalization will be called.
90  * Do nothing if initialization was done.
91  *
92  * The method with no parameters is called at the beginning of every function of this class, so an explicit call
93  * to it has only sense if one would like to provide alternative python home directories.
94  * The string has form <prefix>[:<exec_prefix>] where <prefix> is prefix for platform independent libraries
95  * (namely sources of python standard libraries) and <exec_prefix> is prefix for platform dependent libraries namely
96  * for the python executable.
97  */
98 
99  static void initialize(const std::string &python_home="");
100 
101  /**
102  * This function loads a module from the given file.
103  * Resulting module has to be deallocated by Py_DECREF() macro.
104  */
105  static PyObject * load_module_from_file(const std::string& fname);
106  /**
107  * This function compile code in the given string and creates a module with name @p module_name.
108  * Resulting module has to be deallocated by Py_DECREF() macro.
109  */
110  static PyObject * load_module_from_string(const std::string& module_name, const std::string& source_string);
111  /**
112  * Method which loads module by given module_name
113  * module_name can (and probably will) contain packages path (will contain dots '.' which detonates package)
114  *
115  * Example:
116  * PyObject * python_module = PythonLoader::load_module_by_name ("profiler.profiler_formatter_module")
117  *
118  * will import module 'profiler_formatter_module' from package 'profiler'
119  */
120  static PyObject * load_module_by_name(const std::string& module_name);
121  /**
122  * Tests whether the error indicator is set, if yes formats and throws exception.
123  */
124  static void check_error();
125  /**
126  * Check if python function is callable, if not throws exception.
127  */
128  static PyObject * get_callable(PyObject *module, const std::string &func_name);
129  /**
130  * all paths which are set in every python call (sys.path) value. Values are
131  * separated by path separator(colon on unix, semicolono on windows). This
132  * value is generated
133  */
134  static std::string sys_path;
135 };
136 
137 
138 
139 #endif // FLOW123D_HAVE_PYTHON
140 
141 #endif /* PYTHON_UTILS_HH_ */
#define DECLARE_EXCEPTION(ExcName, Format)
Macro for simple definition of exceptions.
Definition: exceptions.hh:158
#define TYPEDEF_ERR_INFO(EI_Type, Type)
Macro to simplify declaration of error_info types.
Definition: exceptions.hh:194