mirror of
https://github.com/triqs/dft_tools
synced 2024-12-25 13:53:40 +01:00
magic : redirect std::cout to python sys.out.write
- for all functions, except when GIL option (not implemented) is here we use a triqs::py_stream, which redirect the stream to python sys.write - so that a simple C++ code with a std::cout print its output in the notebook... - NB : it only works for the code within the cell. If it calls another function on the lib which uses cout, print is not redirected. Designed for simple tests.... - cerr not (yet) redirected. (useful ?).
This commit is contained in:
parent
aa126e178b
commit
f1c32012a6
@ -6,7 +6,7 @@ Triqs magic
|
|||||||
{TRIQS_DOC}
|
{TRIQS_DOC}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import imp,os,sys,subprocess, hashlib
|
import imp,os,sys,subprocess, hashlib,re
|
||||||
from IPython.core.error import UsageError
|
from IPython.core.error import UsageError
|
||||||
from IPython.core.magic import Magics, magics_class, line_magic, cell_magic
|
from IPython.core.magic import Magics, magics_class, line_magic, cell_magic
|
||||||
from IPython.core import display, magic_arguments
|
from IPython.core import display, magic_arguments
|
||||||
@ -53,6 +53,7 @@ def desc_file(c_decl, use) :
|
|||||||
from wrap_generator import *
|
from wrap_generator import *
|
||||||
module = module_(full_name = "ext", doc = "")
|
module = module_(full_name = "ext", doc = "")
|
||||||
module.add_include("<triqs/arrays.hpp>")
|
module.add_include("<triqs/arrays.hpp>")
|
||||||
|
module.add_include("<triqs/python_tools/py_stream.hpp>")
|
||||||
module.add_using("namespace triqs::arrays")
|
module.add_using("namespace triqs::arrays")
|
||||||
module.add_preamble('#include "./ext.cpp"')
|
module.add_preamble('#include "./ext.cpp"')
|
||||||
"""
|
"""
|
||||||
@ -137,9 +138,16 @@ class TriqsMagics(Magics):
|
|||||||
if '-v' in line:
|
if '-v' in line:
|
||||||
self.triqs.parser.set_defaults(verbosity=0)
|
self.triqs.parser.set_defaults(verbosity=0)
|
||||||
|
|
||||||
|
## Add GIL argument ?
|
||||||
|
use_GIL = False
|
||||||
args = magic_arguments.parse_argstring(self.triqs, line)
|
args = magic_arguments.parse_argstring(self.triqs, line)
|
||||||
|
|
||||||
code = cell if cell.endswith('\n') else cell + '\n'
|
code = cell if cell.endswith('\n') else cell + '\n'
|
||||||
|
|
||||||
|
#if not GIL, we replace std::cout by triqs::py_out for capture in the notebook
|
||||||
|
if not use_GIL :
|
||||||
|
code = re.sub("std::cout", "triqs::py_stream()", code)
|
||||||
|
|
||||||
key = code, line, sys.version_info, sys.executable
|
key = code, line, sys.version_info, sys.executable
|
||||||
|
|
||||||
c_decl = self.extract_signature(code)
|
c_decl = self.extract_signature(code)
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
//#define CHECK_OR_THROW(Cond, Mess)
|
//#define CHECK_OR_THROW(Cond, Mess)
|
||||||
#define CHECK_OR_THROW(Cond, Mess) \
|
#define CHECK_OR_THROW(Cond, Mess) \
|
||||||
if (!Cond) TRIQS_RUNTIME_ERROR << "Error in h5 (de)serialization " << Mess;
|
if (!(Cond)) TRIQS_RUNTIME_ERROR << "Error in h5 (de)serialization " << Mess;
|
||||||
|
|
||||||
namespace triqs {
|
namespace triqs {
|
||||||
namespace h5 {
|
namespace h5 {
|
||||||
|
36
triqs/python_tools/py_stream.cpp
Normal file
36
triqs/python_tools/py_stream.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 by O. Parcollet
|
||||||
|
*
|
||||||
|
* TRIQS is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
#define TRIQS_LIB_CPP
|
||||||
|
#include "./py_stream.hpp"
|
||||||
|
#include "../utility/exceptions.hpp"
|
||||||
|
|
||||||
|
namespace triqs {
|
||||||
|
|
||||||
|
using py_tools::pyref;
|
||||||
|
|
||||||
|
py_stream::py_stream() {
|
||||||
|
if (!Py_IsInitialized()) TRIQS_RUNTIME_ERROR << "Construction of a py_stream before the interpreter is initialized !!";
|
||||||
|
sys = pyref::module("sys");
|
||||||
|
sys_out = sys.attr("stdout");
|
||||||
|
}
|
||||||
|
|
||||||
|
void py_stream::_write(const char* s) { pyref res = PyObject_CallMethod(sys_out, "write", "s", s); }
|
||||||
|
}
|
58
triqs/python_tools/py_stream.hpp
Normal file
58
triqs/python_tools/py_stream.hpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 by O. Parcollet
|
||||||
|
*
|
||||||
|
* TRIQS is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
#include <ostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include "./pyref.hpp"
|
||||||
|
|
||||||
|
namespace triqs {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
class py_stream {
|
||||||
|
|
||||||
|
py_tools::pyref sys, sys_out;
|
||||||
|
void _write(const char* s);
|
||||||
|
|
||||||
|
public:
|
||||||
|
py_stream();
|
||||||
|
|
||||||
|
template <class T> py_stream& operator<<(T const& x) {
|
||||||
|
std::stringstream fs;
|
||||||
|
fs << x;
|
||||||
|
_write(fs.str().c_str());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is the type of std::cout
|
||||||
|
typedef std::basic_ostream<char, std::char_traits<char>> CoutType;
|
||||||
|
|
||||||
|
// this is the function signature of std::endl
|
||||||
|
typedef CoutType& (*StandardEndLine)(CoutType&);
|
||||||
|
|
||||||
|
// define an operator<< to take in std::endl
|
||||||
|
py_stream& operator<<(StandardEndLine manip) {
|
||||||
|
_write("\n");
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
62
triqs/python_tools/pyref.hpp
Normal file
62
triqs/python_tools/pyref.hpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
namespace triqs {
|
||||||
|
namespace py_tools {
|
||||||
|
|
||||||
|
//--------------------- pyref -----------------------------
|
||||||
|
|
||||||
|
// a little class to hold an owned ref, make sure it is decref at destruction
|
||||||
|
class pyref {
|
||||||
|
PyObject *ob = NULL;
|
||||||
|
|
||||||
|
public:
|
||||||
|
pyref() = default;
|
||||||
|
pyref(PyObject *new_ref) : ob(new_ref) {}
|
||||||
|
~pyref() { Py_XDECREF(ob); }
|
||||||
|
operator PyObject *() const { return ob; }
|
||||||
|
PyObject *new_ref() const {
|
||||||
|
Py_XINCREF(ob);
|
||||||
|
return ob;
|
||||||
|
}
|
||||||
|
explicit operator bool() const { return (ob != NULL); }
|
||||||
|
bool is_null() const { return ob == NULL; }
|
||||||
|
bool is_None() const { return ob == Py_None; }
|
||||||
|
|
||||||
|
pyref attr(const char *s) {
|
||||||
|
return (ob ? PyObject_GetAttrString(ob, s) : NULL);
|
||||||
|
} // NULL : pass the error in chain call x.attr().attr()....
|
||||||
|
|
||||||
|
pyref operator()(PyObject *a1) {
|
||||||
|
return (ob ? PyObject_CallFunctionObjArgs(ob, a1, NULL) : NULL);
|
||||||
|
} // NULL : pass the error in chain call x.attr().attr()....
|
||||||
|
|
||||||
|
pyref operator()(PyObject *a1, PyObject *a2) {
|
||||||
|
return (ob ? PyObject_CallFunctionObjArgs(ob, a1, a2, NULL) : NULL);
|
||||||
|
} // NULL : pass the error in chain call x.attr().attr()....
|
||||||
|
|
||||||
|
pyref(pyref const &p) {
|
||||||
|
ob = p.ob;
|
||||||
|
Py_XINCREF(ob);
|
||||||
|
}
|
||||||
|
pyref(pyref &&p) {
|
||||||
|
ob = p.ob;
|
||||||
|
p.ob = NULL;
|
||||||
|
}
|
||||||
|
pyref &operator=(pyref const &) = delete;
|
||||||
|
pyref &operator=(pyref &&p) {
|
||||||
|
ob = p.ob;
|
||||||
|
p.ob = NULL;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
static pyref module(std::string const &module_name) { return PyImport_ImportModule(module_name.c_str()); }
|
||||||
|
static pyref string(std::string const &s) { return PyString_FromString(s.c_str()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
inline pyref borrowed(PyObject *ob) {
|
||||||
|
Py_XINCREF(ob);
|
||||||
|
return {ob};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@
|
|||||||
#include <complex>
|
#include <complex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <triqs/utility/exceptions.hpp>
|
#include <triqs/utility/exceptions.hpp>
|
||||||
|
#include "./pyref.hpp"
|
||||||
|
|
||||||
#pragma clang diagnostic ignored "-Wdeprecated-writable-strings"
|
#pragma clang diagnostic ignored "-Wdeprecated-writable-strings"
|
||||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||||
@ -26,33 +27,6 @@
|
|||||||
|
|
||||||
namespace triqs { namespace py_tools {
|
namespace triqs { namespace py_tools {
|
||||||
|
|
||||||
//--------------------- pyref -----------------------------
|
|
||||||
|
|
||||||
// a little class to hold an owned ref, make sure it is decref at destruction
|
|
||||||
class pyref {
|
|
||||||
PyObject * ob = NULL;
|
|
||||||
public:
|
|
||||||
pyref() = default;
|
|
||||||
pyref(PyObject *new_ref) : ob(new_ref){}
|
|
||||||
~pyref() { Py_XDECREF(ob);}
|
|
||||||
operator PyObject *() const { return ob;}
|
|
||||||
PyObject * new_ref() const { Py_XINCREF(ob); return ob;}
|
|
||||||
explicit operator bool() const { return (ob!=NULL);}
|
|
||||||
bool is_null() const { return ob==NULL;}
|
|
||||||
bool is_None() const { return ob==Py_None;}
|
|
||||||
pyref attr(const char * s) { return (ob ? PyObject_GetAttrString(ob,s) : NULL);} // NULL : pass the error in chain call x.attr().attr()....
|
|
||||||
pyref operator()(PyObject * a1) { return (ob ? PyObject_CallFunctionObjArgs(ob,a1,NULL) : NULL);} // NULL : pass the error in chain call x.attr().attr()....
|
|
||||||
pyref operator()(PyObject * a1,PyObject * a2) { return (ob ? PyObject_CallFunctionObjArgs(ob,a1,a2,NULL) : NULL);} // NULL : pass the error in chain call x.attr().attr()....
|
|
||||||
pyref(pyref const&p) {ob = p.ob; Py_XINCREF(ob);}
|
|
||||||
pyref(pyref && p){ ob = p.ob; p.ob=NULL;}
|
|
||||||
pyref& operator =(pyref const&) = delete;
|
|
||||||
pyref& operator =(pyref &&p) {ob = p.ob; p.ob=NULL; return *this;}
|
|
||||||
static pyref module(std::string const &module_name) { return PyImport_ImportModule(module_name.c_str()); }
|
|
||||||
static pyref string(std::string const &s) { return PyString_FromString(s.c_str());}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline pyref borrowed(PyObject * ob) { Py_XINCREF(ob); return {ob};}
|
|
||||||
|
|
||||||
//--------------------- py_converters -----------------------------
|
//--------------------- py_converters -----------------------------
|
||||||
|
|
||||||
// default version for a wrapped type. To be specialized later.
|
// default version for a wrapped type. To be specialized later.
|
||||||
|
Loading…
Reference in New Issue
Block a user