Ensure the environment variables are synced between Pcbnew and Python

This ensures that when the project or an environment variable is changed
in pcbnew, the Python interpreter is updated to reflect that.
This is a backport version of the master-branch commit, and will not
synchronize any changes to the environment variables if they are made
from frames other tna Pcbnew.

Fixes https://gitlab.com/kicad/code/kicad/issues/5071
This commit is contained in:
Ian McInerney 2020-08-09 20:31:16 +01:00
parent 74adbbcc5d
commit 589951eaea
5 changed files with 78 additions and 1 deletions

View File

@ -315,6 +315,7 @@ bool PCB_EDIT_FRAME::Files_io_from_id( int id )
ProjectFileExtension ); ProjectFileExtension );
Prj().SetProjectFullName( fn.GetFullPath() ); Prj().SetProjectFullName( fn.GetFullPath() );
PythonSyncProjectName();
fn.SetExt( PcbFileExtension ); fn.SetExt( PcbFileExtension );
@ -461,6 +462,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
// it knows what consequences that will have on other KIFACEs running and using // it knows what consequences that will have on other KIFACEs running and using
// this same PROJECT. It can be very harmful if that calling code is stupid. // this same PROJECT. It can be very harmful if that calling code is stupid.
Prj().SetProjectFullName( pro.GetFullPath() ); Prj().SetProjectFullName( pro.GetFullPath() );
PythonSyncProjectName();
// load project settings before BOARD // load project settings before BOARD
LoadProjectSettings(); LoadProjectSettings();

View File

@ -454,6 +454,10 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
enableGALSpecificMenus(); enableGALSpecificMenus();
// Ensure the Python interpreter is up to date with its environment variables
PythonSyncEnvironmentVariables();
PythonSyncProjectName();
// disable Export STEP item if kicad2step does not exist // disable Export STEP item if kicad2step does not exist
wxString strK2S = Pgm().GetExecutablePath(); wxString strK2S = Pgm().GetExecutablePath();
@ -1138,6 +1142,10 @@ void PCB_EDIT_FRAME::OnConfigurePaths( wxCommandEvent& aEvent )
{ {
DIALOG_CONFIGURE_PATHS dlg( this, Prj().Get3DCacheManager()->GetResolver() ); DIALOG_CONFIGURE_PATHS dlg( this, Prj().Get3DCacheManager()->GetResolver() );
dlg.ShowModal(); dlg.ShowModal();
// Ensure the Python interpreter is up to date with its environment variables
PythonSyncEnvironmentVariables();
PythonSyncProjectName();
} }
@ -1270,6 +1278,29 @@ void PCB_EDIT_FRAME::PythonPluginsReload()
} }
void PCB_EDIT_FRAME::PythonSyncEnvironmentVariables()
{
#if defined( KICAD_SCRIPTING )
const ENV_VAR_MAP& varMap = Pgm().GetLocalEnvVariables();
for( ENV_VAR_MAP_CITER it = varMap.begin(); it != varMap.end(); ++it )
{
pcbnewUpdatePythonEnvVar( it->first, it->second.GetValue() );
}
#endif
}
void PCB_EDIT_FRAME::PythonSyncProjectName()
{
#if defined( KICAD_SCRIPTING )
wxString evValue;
wxGetEnv( PROJECT_VAR_NAME, &evValue );
pcbnewUpdatePythonEnvVar( wxString( PROJECT_VAR_NAME ).ToStdString(), evValue );
#endif
}
void PCB_EDIT_FRAME::InstallFootprintPropertiesDialog( MODULE* Module, wxDC* DC ) void PCB_EDIT_FRAME::InstallFootprintPropertiesDialog( MODULE* Module, wxDC* DC )
{ {
if( Module == NULL ) if( Module == NULL )

View File

@ -312,6 +312,18 @@ public:
*/ */
void PythonPluginsReload(); void PythonPluginsReload();
/**
* Synchronize the environment variables from KiCad's environment into the Python interpreter.
* Do nothing if KICAD_SCRIPTING is not defined.
*/
void PythonSyncEnvironmentVariables();
/**
* Synchronize the project name from KiCad's environment into the Python interpreter.
* Do nothing if KICAD_SCRIPTING is not defined.
*/
void PythonSyncProjectName();
/** /**
* Update the layer manager and other widgets from the board setup * Update the layer manager and other widgets from the board setup
* (layer and items visibility, colors ...) * (layer and items visibility, colors ...)

View File

@ -210,7 +210,8 @@ bool pcbnewInitPythonScripting( const char * aUserScriptingPath )
{ {
PyLOCK lock; PyLOCK lock;
snprintf( cmd, sizeof( cmd ), "import sys, traceback\n" // Load os so that we can modify the environment variables through python
snprintf( cmd, sizeof( cmd ), "import sys, os, traceback\n"
"sys.path.append(\".\")\n" "sys.path.append(\".\")\n"
"import pcbnew\n" "import pcbnew\n"
"pcbnew.LoadPlugins(\"%s\")", aUserScriptingPath ); "pcbnew.LoadPlugins(\"%s\")", aUserScriptingPath );
@ -318,6 +319,29 @@ void pcbnewFinishPythonScripting()
} }
void pcbnewUpdatePythonEnvVar( const wxString& aVar, const wxString& aValue )
{
char cmd[1024];
// Ensure the interpreter is initalized before we try to interact with it
if( !Py_IsInitialized() )
return;
snprintf( cmd, sizeof( cmd ),
"# coding=utf-8\n" // The values could potentially be UTF8
"os.environ[\"%s\"]=\"%s\"\n",
TO_UTF8( aVar ),
TO_UTF8( aValue ) );
PyLOCK lock;
int retv = PyRun_SimpleString( cmd );
if( retv != 0 )
wxLogError( "Python error %d occurred running command:\n\n`%s`", retv, cmd );
}
#if defined( KICAD_SCRIPTING_WXPYTHON ) #if defined( KICAD_SCRIPTING_WXPYTHON )
void RedirectStdio() void RedirectStdio()
{ {

View File

@ -78,6 +78,14 @@ void pcbnewGetScriptsSearchPaths( wxString& aNames );
*/ */
void pcbnewGetWizardsBackTrace( wxString& aNames ); void pcbnewGetWizardsBackTrace( wxString& aNames );
/**
* Set an environment variable in the current Python interpreter.
*
* @param aVar is the variable to set
* @param aValue is the value to give it
*/
void pcbnewUpdatePythonEnvVar( const wxString& aVar, const wxString& aValue );
#ifdef KICAD_SCRIPTING_WXPYTHON #ifdef KICAD_SCRIPTING_WXPYTHON
void RedirectStdio(); void RedirectStdio();
wxWindow* CreatePythonShellWindow( wxWindow* parent, const wxString& aFramenameId ); wxWindow* CreatePythonShellWindow( wxWindow* parent, const wxString& aFramenameId );