Developer Documentation

PyLogHook.h
1 //MIT License
2 //
3 //Copyright(c) 2017 Matthias M�ller
4 //https://github.com/TinyTinni/PyLogHook
5 //
6 //Permission is hereby granted, free of charge, to any person obtaining a copy
7 //of this software and associated documentation files(the "Software"), to deal
8 //in the Software without restriction, including without limitation the rights
9 //to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10 //copies of the Software, and to permit persons to whom the Software is
11 //furnished to do so, subject to the following conditions :
12 //
13 //The above copyright notice and this permission notice shall be included in all
14 //copies or substantial portions of the Software.
15 //
16 //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19 //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 //SOFTWARE.
23
24 #pragma once
25
26 #include <utility>
27 #include <string>
28
29 #ifdef TYTI_PYLOGHOOK_USE_BOOST
30 #include <boost/python.hpp>
31 #else
32 #include <pybind11/pybind11.h>
33 #endif
34
35
36 namespace tyti {
37 namespace pylog {
38 namespace detail {
39
40 #ifdef TYTI_PYLOGHOOK_USE_BOOST
41 template <typename T>
42 inline boost::python::object LogHookMakeObject(T t)
43 {
44 return boost::python::object(boost::python::make_function(
45 std::forward<T>(t),
46 boost::python::default_call_policies(),
47 boost::mpl::vector<void, const char*>() // signature
48 ));
49 }
50 #else
51 template<typename T>
52 inline pybind11::object LogHookMakeObject(T t)
53 {
54 return pybind11::cpp_function(std::forward<T>(t));
55 }
56
57 #endif
58 template<typename T>
59 void redirect_syspipe(T t, const char* pipename)
60 {
61 assert(Py_IsInitialized());
62
63 PyObject* out = PySys_GetObject(pipename);
64
65 // in case python couldnt create stdout/stderr
66 // this happens in some gui application
67 // just register a new nameless type for this
68
69 if (out == NULL || out == Py_None)
70 {
71 std::string register_read_write = std::string("import sys\n\
72 sys.") + pipename + std::string(" = type(\"\",(object,),{\"write\":lambda self, txt: None, \"flush\":lambda self: None})()\n");
73
74 PyRun_SimpleString(register_read_write.c_str());
75 out = PySys_GetObject(pipename);
76 }
77 // overwrite write function
78 PyObject_SetAttrString(out, "write",
79 detail::LogHookMakeObject(std::forward<T>(t)).ptr());
80
81 }
82 } // namespace detail
83
99 template<typename T>
100 inline void redirect_stdout(T t)
101 {
102 detail::redirect_syspipe(std::forward<T>(t), "stdout");
103 }
104
105 template<typename T>
106 inline void redirect_stderr(T t)
107 {
108 detail::redirect_syspipe(std::forward<T>(t), "stderr");
109 }
110 }
111 }
tyti
Definition: PyLogHook.h:36