Flow123d  DF_patch_fe_data_tables-fa7c8cb
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 
22 #include "global_defs.h"
23 #include "system/exceptions.hh" // for ExcStream, operator<<, DECLARE_E...
24 
25 #include <string>
26 //#include <pybind11/pybind11.h>
27 #include <pybind11/embed.h>
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  */
56 public:
57  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 __attribute__((visibility("default"))) 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();
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 pybind11::module_ 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  * Module contains one function with name @p func_name. Function must be defined in @p source_strimg.
107  * Resulting module has to be deallocated by Py_DECREF() macro.
108  */
109  static pybind11::module_ load_module_from_string(const std::string& module_name, const std::string& func_name, const std::string& source_string);
110  /**
111  * Method which loads module by given module_name
112  * module_name can (and probably will) contain packages path (will contain dots '.' which detonates package)
113  *
114  * Example:
115  * PyObject * python_module = PythonLoader::load_module_by_name ("profiler.profiler_formatter_module")
116  *
117  * will import module 'profiler_formatter_module' from package 'profiler'
118  */
119  static pybind11::module_ load_module_by_name(const std::string& module_name);
120  /**
121  * Formats and throws ExcPythonError exception.
122  */
123  static void throw_error(const pybind11::error_already_set &ex);
124  /**
125  * Add path to python sys_path.
126  */
127  static void add_sys_path(const std::string &path);
128  /**
129  * Returns vector of Python paths.
130  */
131  static std::vector<std::string> get_python_path();
132 };
133 
134 
135 
136 #endif /* PYTHON_UTILS_HH_ */
Global macros to enhance readability and debugging, general constants.
#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
void throw_error(spirit_namespace::position_iterator< Iter_type > i, const std::string &reason)
class __attribute__((visibility("default"))) PythonLoader