Use Python to test for modules (not CPython)

CPython call requires Python 3.8+, so we work around to keep the 3.6
users happy

Fixes https://gitlab.com/kicad/code/kicad/issues/8554
This commit is contained in:
Seth Hillbrand 2021-06-07 13:55:28 -07:00
parent d4edc70f65
commit 891e200fc8
3 changed files with 22 additions and 9 deletions

View File

@ -55,25 +55,19 @@ void SCRIPTING_TOOL::Reset( RESET_REASON aReason )
bool SCRIPTING_TOOL::Init()
{
PyLOCK lock;
PyObject* mod_name = PyUnicode_FromString( "_pcbnew" );
std::string pymodule( "_pcbnew" );
if( PyObject* existing_mod = PyImport_GetModule( mod_name ) )
{
Py_DecRef( existing_mod );
}
else
if( !SCRIPTING::IsModuleLoaded( pymodule ) )
{
KIFACE* kiface = frame()->Kiway().KiFACE( KIWAY::FACE_PCB );
initfunc pcbnew_init = reinterpret_cast<initfunc>( kiface->IfaceOrAddress( KIFACE_SCRIPTING_LEGACY ) );
PyImport_AddModule( "_pcbnew" );
PyImport_AddModule( pymodule.c_str() );
PyObject* mod = pcbnew_init();
PyObject* sys_mod = PyImport_GetModuleDict();
PyDict_SetItemString( sys_mod, "_pcbnew", mod );
Py_DECREF( mod );
}
Py_DecRef( mod_name );
// Load pcbnew inside Python and load all the user plugins and package-based plugins
{
using namespace pybind11::literals;

View File

@ -98,6 +98,23 @@ bool SCRIPTING::IsWxAvailable()
#endif
}
bool SCRIPTING::IsModuleLoaded( std::string& aModule )
{
PyLOCK lock;
using namespace pybind11::literals;
auto locals = pybind11::dict( "modulename"_a = aModule );
pybind11::exec( R"(
import sys
loaded = False
if modulename in sys.modules:
loaded = True
)", pybind11::globals(), locals );
return locals["loaded"].cast<bool>();
}
bool SCRIPTING::scriptingSetup()
{
#if defined( __WINDOWS__ )

View File

@ -57,6 +57,8 @@ public:
static bool IsWxAvailable();
static bool IsModuleLoaded( std::string& aModule );
static wxString PyScriptingPath( bool aUserPath = false );
static wxString PyPluginsPath( bool aUserPath = false );