Flow123d  release_2.1.0-87-gfbc1563
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 "global_defs.h"
22 
23 #ifdef FLOW123D_HAVE_PYTHON
24 
25 #include "Python.h"
26 #include <string>
27 
28 /*
29  * Notes on Python 3 API
30  *
31  * - PyObject * PyUnicode_FromString(const char * u):
32  * Create a Unicode object from a UTF-8 encoded
33  * null-terminated char buffer u
34  *
35  * - const char * PyUnicode_AsUTF8(PyObject *unicode):
36  * Return a pointer to the UTF-8 encoding of the Unicode object.
37  * Reverse action of PyUnicode_FromString.
38  *
39  * Our functions are only converting from string to wstring and back during
40  * initialization
41  *
42  * - wstring to_py_string(const string &str):
43  * useful when setting program name, and altering path
44  *
45  * - string from_py_string(const wstring &wstr):
46  * so far no usage in the program, but serves for converting wstring to
47  * string
48  */
49 
50 
51 namespace internal {
52 /**
53  * Class to implement initialization and finalization of the python module
54  */
55 class PythonRunning {
56 public:
57  PythonRunning(const std::string &python_home);
58  ~PythonRunning();
59 };
60 } // close namespace internal
61 
62 
63 
64 /**
65  * Class with static only members, should be used to load and compile Python sources either from file or from string.
66  * Implement correct initialization and finalization.
67  * TODO:
68  * - check validity of results and throw exceptions
69  * - better loading of modules from files
70  * - explain and resolve RuntimeWarning:
71  * "flow123d_python_loader:1: RuntimeWarning: Parent module 'field_python_script' not found while handling absolute import"
72  * that appears during field_python_test.cpp
73  *
74  */
75 class PythonLoader {
76 public:
77 
78  /**
79  * Definition of exception thrown by python compiler or interpreter.
80  */
81  TYPEDEF_ERR_INFO(EI_PythonMessage, std::string);
82  DECLARE_EXCEPTION(ExcPythonError,
83  << "Python Error: " << EI_PythonMessage::val << "\n");
84 
85 
86  /**
87  * Calls python initialization and guarantee that appropriate finalization will be called.
88  * Do nothing if initialization was done.
89  *
90  * The method with no parameters is called at the beginning of every function of this class, so an explicit call
91  * to it has only sense if one would like to provide alternative python home directories.
92  * The string has form <prefix>[:<exec_prefix>] where <prefix> is prefix for platform independent libraries
93  * (namely sources of python standard libraries) and <exec_prefix> is prefix for platform dependent libraries namely
94  * for the python executable.
95  */
96 
97  static void initialize(const std::string &python_home="");
98 
99  /**
100  * This function loads a module from the given file.
101  * Resulting module has to be deallocated by Py_DECREF() macro.
102  */
103  static PyObject * load_module_from_file(const std::string& fname);
104  /**
105  * This function compile code in the given string and creates a module with name @p module_name.
106  * Resulting module has to be deallocated by Py_DECREF() macro.
107  */
108  static PyObject * load_module_from_string(const std::string& module_name, const std::string& source_string);
109  /**
110  * Method which loads module by given module_name
111  * module_name can (and probably will) contain packages path (will contain dots '.' which detonates package)
112  *
113  * Example:
114  * PyObject * python_module = PythonLoader::load_module_by_name ("profiler.profiler_formatter_module")
115  *
116  * will import module 'profiler_formatter_module' from package 'profiler'
117  */
118  static PyObject * load_module_by_name(const std::string& module_name);
119  /**
120  * Tests whether the error indicator is set, if yes formats and throws exception.
121  */
122  static void check_error();
123  /**
124  * Check if python function is callable, if not throws exception.
125  */
126  static PyObject * get_callable(PyObject *module, const std::string &func_name);
127  /**
128  * all paths which are set in every python call (sys.path) value. Values are
129  * separated by path separator(colon on unix, semicolono on windows). This
130  * value is generated
131  */
132  static std::string sys_path;
133 };
134 
135 
136 
137 #endif // FLOW123D_HAVE_PYTHON
138 
139 #endif /* PYTHON_UTILS_HH_ */
#define DECLARE_EXCEPTION(ExcName, Format)
Macro for simple definition of exceptions.
Definition: exceptions.hh:150
Global macros to enhance readability and debugging, general constants.
#define TYPEDEF_ERR_INFO(EI_Type, Type)
Macro to simplify declaration of error_info types.
Definition: exceptions.hh:186