source: src/Python/PythonScripting.cpp@ a0d8aa

Candidate_v1.7.0 stable
Last change on this file since a0d8aa was a93896, checked in by Frederik Heber <frederik.heber@…>, 2 months ago

Ignores pyMoleCuilder import in python script.

  • TEST: LoadSession now uses an AS alias for the import.
  • TESTFIX: load session with complex waits does not look for the wait texts but rather for output from the actions in the script.
  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2013 Frederik Heber. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * PythonScripting.cpp
25 *
26 * Created on: Aug 26, 2013
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35// boost::python uses placement new which is incompatible with MemDebug.
36#include "PythonScripting_impl.hpp"
37#include "PythonScripting.hpp"
38
39#include <string>
40
41//#include "CodePatterns/MemDebug.hpp"
42
43bool executePythonScriptFile(const boost::filesystem::path &pythonfilename)
44{
45 if (exists(pythonfilename)) {
46 // parse file into a string
47 std::ifstream pythonfile(pythonfilename.string().c_str());
48 std::string pythonscript( std::istreambuf_iterator<char>(pythonfile),
49 (std::istreambuf_iterator<char>()) );
50 return executePythonScript(pythonscript, pythonfilename.string());
51 }
52 return false;
53}
54
55bool executePythonScript(const std::string &python_string, const std::string &python_scripttitle)
56{
57 std::stringstream input(python_string);
58 std::stringstream buffer_import;
59 std::stringstream buffer_else;
60 // move all lines with "import" to the beginning
61 std::string current_line;
62 std::string moduleName;
63 while(std::getline(input,current_line,'\n')){
64 if (current_line.find("import ") != std::string::npos) {
65 if (current_line.find(PYMOLECUILDER_MODULE_NAME) != std::string::npos) {
66 // ignore a PyMoleCuilder import, use the AS however.
67 const size_t lowerCaseAsPos = current_line.find("as");
68 const size_t upperCaseAsPos = current_line.find("AS");
69 size_t moduleNameStart = std::string::npos;
70 if (lowerCaseAsPos != std::string::npos)
71 moduleNameStart = lowerCaseAsPos+2+1;
72 if (upperCaseAsPos != std::string::npos)
73 moduleNameStart = upperCaseAsPos+2+1;
74 if (moduleNameStart != std::string::npos) {
75 const size_t moduleNameEnd = current_line.find(" ", moduleNameStart);
76 moduleName = current_line.substr(
77 moduleNameStart,
78 moduleNameEnd == std::string::npos ? moduleNameEnd : moduleNameEnd - moduleNameStart
79 );
80 ELOG(2, "Ignoring found " << PYMOLECUILDER_MODULE_NAME << " import, but keeping AS name " << moduleName << ".");
81 } else {
82 ELOG(2, "Ignoring found " << PYMOLECUILDER_MODULE_NAME << " import.");
83 }
84 } else {
85 buffer_import << current_line << std::endl;
86 }
87 } else {
88 buffer_else << current_line << std::endl;
89 }
90 }
91 std::string pythonscript_import( std::istreambuf_iterator<char>(buffer_import),
92 (std::istreambuf_iterator<char>()) );
93 std::string pythonscript_else( std::istreambuf_iterator<char>(buffer_else),
94 (std::istreambuf_iterator<char>()) );
95
96 try {
97#ifdef HAVE_PYTHON2
98 PyImport_AppendInittab( PYMOLECUILDER_MODULE_NAME.c_str(), &initpyMoleCuilder );
99#else
100 PyImport_AppendInittab( PYMOLECUILDER_MODULE_NAME.c_str(), &PyInit_pyMoleCuilder );
101#endif
102
103 Py_Initialize();
104
105 boost::python::object main_module((
106 boost::python::handle<>(boost::python::borrowed(PyImport_AddModule("__main__")))));
107
108 boost::python::object main_namespace = main_module.attr("__dict__");
109
110 boost::python::handle<> imported(( PyRun_String( pythonscript_import.c_str(),
111 Py_file_input,
112 main_namespace.ptr(),
113 main_namespace.ptr() ) ));
114
115 boost::python::object molecuilder_module( (boost::python::handle<>(PyImport_ImportModule("pyMoleCuilder"))) );
116 main_namespace[PYMOLECUILDER_MODULE_NAME] = molecuilder_module;
117 if (moduleName.size() > 0)
118 main_namespace[moduleName] = molecuilder_module;
119
120 std::string enveloped_script("print(\"BEGIN of "+python_scripttitle+":\")\n");
121 enveloped_script += pythonscript_else+std::string("\n");
122 enveloped_script += std::string("print(\"END of "+python_scripttitle+":\")\n");
123
124 boost::python::handle<> ignored(( PyRun_String( enveloped_script.c_str(),
125 Py_file_input,
126 main_namespace.ptr(),
127 main_namespace.ptr() ) ));
128
129 } catch( boost::python::error_already_set ) {
130 PyErr_Print();
131 return false;
132 }
133 return true;
134}
Note: See TracBrowser for help on using the repository browser.