/**********************************************************************
PythonInterpreter - Python Internal Interactive Interpreter
Copyright (C) 2008 Donald Ephraim Curtis
This file is part of the Avogadro molecular editor project.
For more information, see
Avogadro 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 2 of the License, or
(at your option) any later version.
Avogadro 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
**********************************************************************/
#include "pythoninterpreter.h"
#include
#include
#include
#include
using namespace boost::python;
namespace Avogadro {
class PythonInterpreterPrivate
{
public:
PythonInterpreterPrivate() : molecule(0)
{
}
dict local_namespace;
Molecule *molecule;
};
int PythonInterpreter::m_initCount = 0;
PythonInterpreter::PythonInterpreter() : d(new PythonInterpreterPrivate)
{
static bool isInitialized = false;
if (!isInitialized) {
isInitialized = true;
try {
Py_Initialize();
} catch( error_already_set ) {
PyErr_Print();
}
return;
}
}
PythonInterpreter::~PythonInterpreter()
{
delete d;
//Py_Finalize();
}
void PythonInterpreter::setMolecule(Molecule *molecule)
{
d->molecule = molecule;
}
object PythonInterpreter::execWrapper(const QString &command, object main, object local)
{
try
{
return boost::python::exec(command.toAscii().constData(), main, local);
}
catch(error_already_set const &)
{
PyErr_Print();
}
return object();
}
object PythonInterpreter::evalWrapper(const QString &command, object main, object local)
{
try
{
return boost::python::eval(command.toAscii().constData(), main, local);
}
catch(error_already_set const &)
{
PyErr_Print();
}
return object();
}
QString PythonInterpreter::eval(const QString &string, object local)
{
object main_module = object(( handle<>(borrowed(PyImport_AddModule("__main__")))));
object main_namespace = main_module.attr("__dict__");
object result = evalWrapper(string, main_namespace, local);
try
{
return QString(extract(result));
}
catch(error_already_set const &)
{
return QString();
}
}
void PythonInterpreter::addSearchPath(const QString &path)
{
object main_module = object(( handle<>(borrowed(PyImport_AddModule("__main__")))));
object main_namespace = main_module.attr("__dict__");
execWrapper("import sys", main_namespace, main_namespace);
QString exp("sys.path.insert(0,\"");
exp.append(path);
exp.append("\")");
execWrapper(exp, main_namespace, main_namespace);
}
QString PythonInterpreter::exec(const QString &command, object local)
{
object main_module = object(( handle<>(borrowed(PyImport_AddModule("__main__")))));
object main_namespace = main_module.attr("__dict__");
try
{
object avogadro_module(handle<>(PyImport_ImportModule("Avogadro")) );
if(d->molecule)
avogadro_module.attr("molecule") = ptr(d->molecule);
}
catch(error_already_set const &)
{
qDebug() << "Could not find python module...";
}
local["sys"] = object(handle<>(PyImport_ImportModule("sys")));
local["cStringIO"] = object(handle<>(PyImport_ImportModule("cStringIO")));
execWrapper("CIO = cStringIO.StringIO()", main_namespace, local);
execWrapper("sys.stdout=CIO", main_namespace, local);
execWrapper("sys.stderr=CIO", main_namespace, local);
object ignored = execWrapper(command.toAscii().constData(), main_namespace, local);
object result = evalWrapper("str(CIO.getvalue())", main_namespace, local);
try
{
return QString(extract(result));
}
catch(error_already_set const &)
{
return QString();
}
}
QString PythonInterpreter::exec(const QString &command)
{
return exec(command, d->local_namespace);
}
}