KiCad PCB EDA Suite
python_scripting.h File Reference
#include <Python.h>
#include <wx/string.h>
#include <wx/arrstr.h>

Go to the source code of this file.

Classes

class  PyLOCK
 

Functions

bool pcbnewInitPythonScripting (const char *aUserScriptingPath)
 Function pcbnewInitPythonScripting Initializes the Python engine inside pcbnew. More...
 
void pcbnewFinishPythonScripting ()
 
void pcbnewGetUnloadableScriptNames (wxString &aNames)
 Function pcbnewGetUnloadableScriptNames collects the list of python scripts which could not be loaded because some error (synthax error) happened. More...
 
void pcbnewGetScriptsSearchPaths (wxString &aNames)
 Function pcbnewGetScriptsSearchPaths collects the list of paths where python scripts are searched. More...
 
void pcbnewGetWizardsBackTrace (wxString &aNames)
 Function pcbnewGetWizardsBackTrace returns the backtrace of errors (if any) when wizard python scripts are loaded. More...
 
wxString PyStringToWx (PyObject *str)
 
wxArrayString PyArrayStringToWx (PyObject *arr)
 
wxString PyErrStringWithTraceback ()
 
wxString PyScriptingPath ()
 Find the Python scripting path. More...
 
wxString PyPluginsPath ()
 

Function Documentation

void pcbnewFinishPythonScripting ( )

Definition at line 301 of file python_scripting.cpp.

302 {
303 #ifdef KICAD_SCRIPTING_WXPYTHON
304  PyEval_RestoreThread( g_PythonMainTState );
305 #endif
306  Py_Finalize();
307 }
PyThreadState * g_PythonMainTState
void pcbnewGetScriptsSearchPaths ( wxString &  aNames)

Function pcbnewGetScriptsSearchPaths collects the list of paths where python scripts are searched.

Parameters
aNamesis a wxString which will contain the paths (separated by '
')

Definition at line 290 of file python_scripting.cpp.

References pcbnewRunPythonMethodWithReturnedString().

291 {
292  pcbnewRunPythonMethodWithReturnedString( "pcbnew.GetWizardsSearchPaths", aNames );
293 }
static void pcbnewRunPythonMethodWithReturnedString(const char *aMethodName, wxString &aNames)
this function runs a python method from pcbnew module, which returns a string
void pcbnewGetUnloadableScriptNames ( wxString &  aNames)

Function pcbnewGetUnloadableScriptNames collects the list of python scripts which could not be loaded because some error (synthax error) happened.

Parameters
aNamesis a wxString which will contain the filenames (separated by '
')

Definition at line 284 of file python_scripting.cpp.

References pcbnewRunPythonMethodWithReturnedString().

285 {
286  pcbnewRunPythonMethodWithReturnedString( "pcbnew.GetUnLoadableWizards", aNames );
287 }
static void pcbnewRunPythonMethodWithReturnedString(const char *aMethodName, wxString &aNames)
this function runs a python method from pcbnew module, which returns a string
void pcbnewGetWizardsBackTrace ( wxString &  aNames)

Function pcbnewGetWizardsBackTrace returns the backtrace of errors (if any) when wizard python scripts are loaded.

Parameters
aNamesis a wxString which will contain the trace

Definition at line 295 of file python_scripting.cpp.

References pcbnewRunPythonMethodWithReturnedString().

296 {
297  pcbnewRunPythonMethodWithReturnedString( "pcbnew.GetWizardsBackTrace", aNames );
298 }
static void pcbnewRunPythonMethodWithReturnedString(const char *aMethodName, wxString &aNames)
this function runs a python method from pcbnew module, which returns a string
bool pcbnewInitPythonScripting ( const char *  aUserScriptingPath)

Function pcbnewInitPythonScripting Initializes the Python engine inside pcbnew.

Definition at line 154 of file python_scripting.cpp.

References Pgm(), swigAddBuiltin(), swigAddModules(), swigSwitchPythonBuiltin(), and wxPythonLoaded.

155 {
156  swigAddBuiltin(); // add builtin functions
157  swigAddModules(); // add our own modules
158  swigSwitchPythonBuiltin(); // switch the python builtin modules to our new list
159 
160  Py_Initialize();
161  PySys_SetArgv( Pgm().App().argc, Pgm().App().argv );
162 
163 #ifdef KICAD_SCRIPTING_WXPYTHON
164  PyEval_InitThreads();
165 
166 #ifndef KICAD_SCRIPTING_WXPYTHON_PHOENIX
167 #ifndef __WINDOWS__ // import wxversion.py currently not working under winbuilder, and not useful.
168  char cmd[1024];
169  // Make sure that that the correct version of wxPython is loaded. In systems where there
170  // are different versions of wxPython installed this can lead to select wrong wxPython
171  // version being selected.
172  snprintf( cmd, sizeof( cmd ), "import wxversion; wxversion.select( '%s' )", WXPYTHON_VERSION );
173 
174  int retv = PyRun_SimpleString( cmd );
175 
176  if( retv != 0 )
177  {
178  wxLogError( wxT( "Python error %d occurred running string `%s`" ), retv, cmd );
179  PyErr_Print();
180  Py_Finalize();
181  return false;
182  }
183 #endif // ifndef __WINDOWS__
184 
185  // Load the wxPython core API. Imports the wx._core_ module and sets a
186  // local pointer to a function table located there. The pointer is used
187  // internally by the rest of the API functions.
188  if( !wxPyCoreAPI_IMPORT() )
189  {
190  wxLogError( wxT( "***** Error importing the wxPython API! *****" ) );
191  PyErr_Print();
192  Py_Finalize();
193  return false;
194  }
195 #endif
196 
197  wxPythonLoaded = true;
198 
199  // Save the current Python thread state and release the
200  // Global Interpreter Lock.
201  g_PythonMainTState = PyEval_SaveThread();
202 
203 #endif // ifdef KICAD_SCRIPTING_WXPYTHON
204 
205  // load pcbnew inside python, and load all the user plugins, TODO: add system wide plugins
206  {
207  char loadCmd[1024];
208  PyLOCK lock;
209  snprintf( loadCmd, sizeof(loadCmd), "import sys, traceback\n"
210  "sys.path.append(\".\")\n"
211  "import pcbnew\n"
212  "pcbnew.LoadPlugins(\"%s\")", aUserScriptingPath );
213  PyRun_SimpleString( loadCmd );
214  }
215 
216  return true;
217 }
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:66
static void swigAddBuiltin()
static void swigAddModules()
static void swigSwitchPythonBuiltin()
static bool wxPythonLoaded
PyThreadState * g_PythonMainTState
wxArrayString PyArrayStringToWx ( PyObject *  arr)

Definition at line 447 of file python_scripting.cpp.

References FROM_UTF8().

Referenced by PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod(), PyErrStringWithTraceback(), and PyLOCK::~PyLOCK().

448 {
449  wxArrayString ret;
450 
451  if( !aArrayString )
452  return ret;
453 
454  int list_size = PyList_Size( aArrayString );
455 
456  for( int n = 0; n < list_size; n++ )
457  {
458  PyObject* element = PyList_GetItem( aArrayString, n );
459 
460  if( element )
461  {
462 #if PY_MAJOR_VERSION >= 3
463  const char* str_res = NULL;
464  PyObject* temp_bytes = PyUnicode_AsEncodedString( element, "UTF-8", "strict" );
465  if( temp_bytes != NULL )
466  {
467  str_res = PyBytes_AS_STRING( temp_bytes );
468  ret.Add( FROM_UTF8( str_res ), 1 );
469  Py_DECREF( temp_bytes );
470  }
471  else
472  {
473  wxLogMessage( "cannot encode unicode python string" );
474  }
475 #else
476  ret.Add( FROM_UTF8( PyString_AsString( element ) ), 1 );
477 #endif
478  }
479  }
480 
481  return ret;
482 }
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
wxString PyErrStringWithTraceback ( )

Definition at line 485 of file python_scripting.cpp.

References err, i, and PyArrayStringToWx().

Referenced by PYTHON_ACTION_PLUGIN::CallMethod(), PYTHON_FOOTPRINT_WIZARD::CallMethod(), pcbnewRunPythonMethodWithReturnedString(), and PyLOCK::~PyLOCK().

486 {
487  wxString err;
488 
489  if( !PyErr_Occurred() )
490  return err;
491 
492  PyObject* type;
493  PyObject* value;
494  PyObject* traceback;
495 
496  PyErr_Fetch( &type, &value, &traceback );
497 
498  PyErr_NormalizeException( &type, &value, &traceback );
499  if( traceback == NULL )
500  {
501  traceback = Py_None;
502  Py_INCREF( traceback );
503  }
504 
505 #if PY_MAJOR_VERSION >= 3
506  PyException_SetTraceback( value, traceback );
507 
508  PyObject* tracebackModuleString = PyUnicode_FromString( "traceback" );
509 #else
510  PyObject* tracebackModuleString = PyString_FromString( "traceback" );
511 #endif
512  PyObject* tracebackModule = PyImport_Import( tracebackModuleString );
513  Py_DECREF( tracebackModuleString );
514 
515  PyObject* formatException = PyObject_GetAttrString( tracebackModule,
516  "format_exception" );
517  Py_DECREF( tracebackModule );
518 
519  PyObject* args = Py_BuildValue( "(O,O,O)", type, value, traceback );
520  PyObject* result = PyObject_CallObject( formatException, args );
521  Py_XDECREF( formatException );
522  Py_XDECREF( args );
523  Py_XDECREF( type );
524  Py_XDECREF( value );
525  Py_XDECREF( traceback );
526 
527  wxArrayString res = PyArrayStringToWx( result );
528 
529  for( unsigned i = 0; i<res.Count(); i++ )
530  {
531  err += res[i] + wxT( "\n" );
532  }
533 
534  PyErr_Clear();
535 
536  return err;
537 }
wxArrayString PyArrayStringToWx(PyObject *aArrayString)
string & err
Definition: json11.cpp:598
size_t i
Definition: json11.cpp:597
wxString PyPluginsPath ( )

Definition at line 565 of file python_scripting.cpp.

References PyScriptingPath().

Referenced by PyLOCK::~PyLOCK().

566 {
567  // Note we are using unix path separator, because window separator sometimes
568  // creates issues when passing a command string to a python method by PyRun_SimpleString
569  return PyScriptingPath() + '/' + "plugins";
570 }
wxString PyScriptingPath()
Find the Python scripting path.
wxString PyScriptingPath ( )

Find the Python scripting path.

Definition at line 542 of file python_scripting.cpp.

References PGM_BASE::GetExecutablePath(), and Pgm().

Referenced by PyPluginsPath(), PythonPluginsReloadBase(), and PyLOCK::~PyLOCK().

543 {
544  wxString path;
545 
546  //TODO should this be a user configurable variable eg KISCRIPT ?
547 #if defined( __WXMAC__ )
548  path = GetOSXKicadDataDir() + wxT( "/scripting" );
549 #else
550  path = Pgm().GetExecutablePath() + wxT( "../share/kicad/scripting" );
551 #endif
552 
553  wxFileName scriptPath( path );
554  scriptPath.MakeAbsolute();
555 
556  // Convert '\' to '/' in path, because later python script read \n or \r
557  // as escaped sequence, and create issues, when calling it by PyRun_SimpleString() method.
558  // It can happen on Windows.
559  path = scriptPath.GetFullPath();
560  path.Replace( '\\', '/' );
561 
562  return path;
563 }
VTBL_ENTRY const wxString & GetExecutablePath() const
Definition: pgm_base.h:215
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:66
wxString PyStringToWx ( PyObject *  str)

Definition at line 418 of file python_scripting.cpp.

References FROM_UTF8().

Referenced by PYTHON_ACTION_PLUGIN::CallRetStrMethod(), PYTHON_FOOTPRINT_WIZARD::CallRetStrMethod(), PYTHON_FOOTPRINT_WIZARD::GetParameterPageName(), and PyLOCK::~PyLOCK().

419 {
420  wxString ret;
421 
422  if( !aString )
423  return ret;
424 
425 #if PY_MAJOR_VERSION >= 3
426  const char* str_res = NULL;
427  PyObject* temp_bytes = PyUnicode_AsEncodedString( aString, "UTF-8", "strict" );
428  if( temp_bytes != NULL )
429  {
430  str_res = PyBytes_AS_STRING( temp_bytes );
431  ret = FROM_UTF8( str_res );
432  Py_DECREF( temp_bytes );
433  }
434  else
435  {
436  wxLogMessage( "cannot encode unicode python string" );
437  }
438 #else
439  const char* str_res = PyString_AsString( aString );
440  ret = FROM_UTF8( str_res );
441 #endif
442 
443  return ret;
444 }
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53