1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Adrien Bruneton (CEA/DEN)
20 // Created on: 4 avr. 2013
23 #include "PyConsole.h"
25 #include "PyConsole_EnhInterp.h"
27 #include <pythonrun.h>
31 static const char * tmp_k[] = {"and", "as", "assert", "break", "class",
32 "continue", "def", "del",
33 "elif", "else", "except", "exec", "finally", "for", "from", "global", "if",
34 "import", "in", "is", "lambda", "not", "or", "pass", "print", "raise",
35 "return", "try", "while", "with", "yield"};
37 const std::vector<QString> PyConsole_EnhInterp::PYTHON_KEYWORDS = \
38 std::vector<QString>(tmp_k, tmp_k+sizeof(tmp_k)/sizeof(tmp_k[0]));
43 PyConsole_EnhInterp::PyConsole_EnhInterp()
51 PyConsole_EnhInterp::~PyConsole_EnhInterp()
55 QStringList PyConsole_EnhInterp::getLastMatches() const
60 QString PyConsole_EnhInterp::getDocStr() const
66 \brief Run Python dir() command and saves the result internally in _lastPy
67 \param dirArgument Python expression to pass to the dir command. The parsing of what the
68 user actually started typing is dedicated to the caller
69 \param startMatch string representing the begining of the patter to be completed. For example when
70 the user types "a_string_variable.rsp <TAB>", this is "rsp".
71 \return command exit status - 0 = success
73 int PyConsole_EnhInterp::runDirCommand(const QString& dirArgument, const QString& startMatch)
76 std::vector<QString> v;
79 if ( (ret = runDirAndExtract(dirArgument, startMatch, _last_matches)) )
82 // If dirArgument is empty, we append the __builtins__
83 if (dirArgument.isEmpty())
85 if ( (ret = runDirAndExtract(QString("__builtins__"), startMatch, _last_matches, false)) )
88 // ... and we match on Python's keywords as well:
89 for (std::vector<QString>::const_iterator it = PYTHON_KEYWORDS.begin(); it != PYTHON_KEYWORDS.end(); it++)
90 if ((*it).startsWith(startMatch))
91 _last_matches.push_back(*it);
94 // Try to get doc string of the first match
95 if (_last_matches.size() > 0)
98 if (dirArgument.trimmed() != "")
99 cmd = dirArgument + ".";
100 cmd += _last_matches[0] + ".__doc__";
101 PyObject * str = PyRun_String(cmd.toStdString().c_str(), Py_eval_input, _global_context, _local_context);
102 if (!str || str == Py_None || !PyString_Check(str))
109 _doc_str = QString(PyString_AsString(str));
113 // The command has been successfully executed
118 * See runDirCommand().
119 * @param dirArgument see runDirCommand()
120 * @param startMatch see runDirCommand()
121 * @param[out] result the list of matches
122 * @param discardSwig if true a regular expression is used to discard all static method generated
123 * by SWIG. typically: MEDCouplingUMesh_Blabla
124 * @return -1 if the call to dir() or the parsing of the result failed, 0 otherwise.
126 int PyConsole_EnhInterp::runDirAndExtract(const QString& dirArgument,
127 const QString& startMatch,
129 bool discardSwig) const
131 QRegExp re("^[A-Z].+_[A-Z]+[a-z]+.+$"); // discard SWIG static method, e.g. MEDCouplingUMesh_Blabla
132 QString command("dir(" + dirArgument + ")");
133 PyObject * plst = PyRun_String(command.toStdString().c_str(), Py_eval_input, _global_context, _local_context);
134 if(!plst || plst == Py_None) {
142 // Extract the returned list and convert it to a vector<>
143 if (!PySequence_Check(plst))
145 // Should never happen ...
146 //std::cerr << "not a list!" << std::endl;
151 // Convert plst to a vector of QString
152 int n = PySequence_Length(plst);
153 for (int i = 0; i < n; i++)
156 it = PySequence_GetItem(plst, i);
157 QString s(PyString_AsString(it));
158 // if the method is not from swig, not static (guessed from the reg exp) and matches
159 // what is already there
160 if (s.startsWith(startMatch))
161 if(!discardSwig || (!re.exactMatch(s) && !s.contains("swig")))
171 * Clear internal members containing the last completion results.
173 void PyConsole_EnhInterp::clearCompletion()
175 _last_matches.clear();