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

◆ pcbnewFinishPythonScripting()

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

References g_PythonMainTState.

◆ pcbnewGetScriptsSearchPaths()

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.

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

References pcbnewRunPythonMethodWithReturnedString().

◆ pcbnewGetUnloadableScriptNames()

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.

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

References pcbnewRunPythonMethodWithReturnedString().

◆ pcbnewGetWizardsBackTrace()

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.

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

References pcbnewRunPythonMethodWithReturnedString().

◆ pcbnewInitPythonScripting()

bool pcbnewInitPythonScripting ( const char *  aUserScriptingPath)

Function pcbnewInitPythonScripting Initializes the Python engine inside pcbnew.

Definition at line 154 of file python_scripting.cpp.

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

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

◆ PyArrayStringToWx()

wxArrayString PyArrayStringToWx ( PyObject *  arr)

Definition at line 456 of file python_scripting.cpp.

457 {
458  wxArrayString ret;
459 
460  if( !aArrayString )
461  return ret;
462 
463  int list_size = PyList_Size( aArrayString );
464 
465  for( int n = 0; n < list_size; n++ )
466  {
467  PyObject* element = PyList_GetItem( aArrayString, n );
468 
469  if( element )
470  {
471 #if PY_MAJOR_VERSION >= 3
472  const char* str_res = NULL;
473  PyObject* temp_bytes = PyUnicode_AsEncodedString( element, "UTF-8", "strict" );
474  if( temp_bytes != NULL )
475  {
476  str_res = PyBytes_AS_STRING( temp_bytes );
477  ret.Add( FROM_UTF8( str_res ), 1 );
478  Py_DECREF( temp_bytes );
479  }
480  else
481  {
482  wxLogMessage( "cannot encode unicode python string" );
483  }
484 #else
485  ret.Add( FROM_UTF8( PyString_AsString( element ) ), 1 );
486 #endif
487  }
488  }
489 
490  return ret;
491 }
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

References FROM_UTF8().

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

◆ PyErrStringWithTraceback()

wxString PyErrStringWithTraceback ( )

Definition at line 494 of file python_scripting.cpp.

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

References err, i, and PyArrayStringToWx().

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

◆ PyPluginsPath()

wxString PyPluginsPath ( )

Definition at line 574 of file python_scripting.cpp.

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

References PyScriptingPath().

◆ PyScriptingPath()

wxString PyScriptingPath ( )

Find the Python scripting path.

Definition at line 551 of file python_scripting.cpp.

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

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

Referenced by PyPluginsPath(), and PythonPluginsReloadBase().

◆ PyStringToWx()

wxString PyStringToWx ( PyObject *  str)

Definition at line 427 of file python_scripting.cpp.

428 {
429  wxString ret;
430 
431  if( !aString )
432  return ret;
433 
434 #if PY_MAJOR_VERSION >= 3
435  const char* str_res = NULL;
436  PyObject* temp_bytes = PyUnicode_AsEncodedString( aString, "UTF-8", "strict" );
437  if( temp_bytes != NULL )
438  {
439  str_res = PyBytes_AS_STRING( temp_bytes );
440  ret = FROM_UTF8( str_res );
441  Py_DECREF( temp_bytes );
442  }
443  else
444  {
445  wxLogMessage( "cannot encode unicode python string" );
446  }
447 #else
448  const char* str_res = PyString_AsString( aString );
449  ret = FROM_UTF8( str_res );
450 #endif
451 
452  return ret;
453 }
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

References FROM_UTF8().

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