Ideally this would return a openstudio::measure::OSMeasure* or a shared_ptr but this poses memory management issue for the underlying ScriptObject (and VALUE or PyObject), so just return the ScriptObject
| 354 | // Ideally this would return a openstudio::measure::OSMeasure* or a shared_ptr<openstudio::measure::OSMeasure> but this poses memory management |
| 355 | // issue for the underlying ScriptObject (and VALUE or PyObject), so just return the ScriptObject |
| 356 | ScriptObject PythonEngine::loadMeasure(const openstudio::path& measureScriptPath, std::string_view className) { |
| 357 | |
| 358 | ScriptObject result; |
| 359 | |
| 360 | auto importCmd = fmt::format(R"python( |
| 361 | import importlib.util |
| 362 | spec = importlib.util.spec_from_file_location('{}', r'{}') |
| 363 | module = importlib.util.module_from_spec(spec) |
| 364 | spec.loader.exec_module(module) |
| 365 | )python", |
| 366 | className, measureScriptPath.generic_string()); |
| 367 | |
| 368 | // fmt::print("\nimportCmd:\n{}\n", importCmd); |
| 369 | try { |
| 370 | exec(importCmd); |
| 371 | } catch (const std::runtime_error& e) { |
| 372 | auto msg = fmt::format("Failed to load measure '{}' from '{}': {}", className, measureScriptPath.generic_string(), e.what()); |
| 373 | fmt::print(stderr, "{}\n", msg); |
| 374 | } |
| 375 | |
| 376 | try { |
| 377 | result = eval(fmt::format("module.{}()", className)); |
| 378 | } catch (const std::runtime_error& e) { |
| 379 | auto msg = fmt::format("Failed to instantiate measure '{}' from '{}': {}", className, measureScriptPath.generic_string(), e.what()); |
| 380 | fmt::print(stderr, "{}\n", msg); |
| 381 | } |
| 382 | |
| 383 | return result; |
| 384 | } |
| 385 | |
| 386 | int PythonEngine::numberOfArguments(ScriptObject& methodObject, std::string_view methodName) { |
| 387 |