flextool 4.0.4__tar.gz → 4.0.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. {flextool-4.0.4 → flextool-4.0.5}/PKG-INFO +1 -1
  2. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_open_results_db.py +4 -9
  3. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_pdt_join.py +25 -6
  4. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_warm.py +15 -4
  5. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/db_editor_integration.py +30 -17
  6. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/main_window.py +14 -11
  7. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/platform_utils.py +40 -12
  8. {flextool-4.0.4 → flextool-4.0.5}/flextool.egg-info/PKG-INFO +1 -1
  9. {flextool-4.0.4 → flextool-4.0.5}/pyproject.toml +1 -1
  10. {flextool-4.0.4 → flextool-4.0.5}/LICENSE.txt +0 -0
  11. {flextool-4.0.4 → flextool-4.0.5}/README.md +0 -0
  12. {flextool-4.0.4 → flextool-4.0.5}/flextool/__init__.py +0 -0
  13. {flextool-4.0.4 → flextool-4.0.5}/flextool/_mem_sampler.py +0 -0
  14. {flextool-4.0.4 → flextool-4.0.5}/flextool/_resources.py +0 -0
  15. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/__init__.py +0 -0
  16. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/__main__.py +0 -0
  17. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/_cli.py +0 -0
  18. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/_db_alt.py +0 -0
  19. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/_final_outputs.py +0 -0
  20. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/_guard.py +0 -0
  21. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/_loop.py +0 -0
  22. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/_readers.py +0 -0
  23. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/_report.py +0 -0
  24. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/_sizing.py +0 -0
  25. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/_solve.py +0 -0
  26. {flextool-4.0.4 → flextool-4.0.5}/flextool/calibrate/_solve_status.py +0 -0
  27. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/__init__.py +0 -0
  28. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/_console.py +0 -0
  29. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/_timing.py +0 -0
  30. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_execute_flextool_workflow.py +0 -0
  31. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_export_to_tabular.py +0 -0
  32. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_import_sensitivities.py +0 -0
  33. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_migrate_database.py +0 -0
  34. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_read_matpower.py +0 -0
  35. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_read_old_flextool.py +0 -0
  36. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_read_self_describing_tabular_input.py +0 -0
  37. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_read_tabular_input.py +0 -0
  38. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_run_flextool.py +0 -0
  39. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_scenario_results.py +0 -0
  40. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_solve_mps.py +0 -0
  41. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_update_flextool.py +0 -0
  42. {flextool-4.0.4 → flextool-4.0.5}/flextool/cli/cmd_write_outputs.py +0 -0
  43. {flextool-4.0.4 → flextool-4.0.5}/flextool/common_utils/__init__.py +0 -0
  44. {flextool-4.0.4 → flextool-4.0.5}/flextool/common_utils/plot_mem_shape.py +0 -0
  45. {flextool-4.0.4 → flextool-4.0.5}/flextool/common_utils/precision.py +0 -0
  46. {flextool-4.0.4 → flextool-4.0.5}/flextool/decomposition/__init__.py +0 -0
  47. {flextool-4.0.4 → flextool-4.0.5}/flextool/decomposition/region_decomposition.py +0 -0
  48. {flextool-4.0.4 → flextool-4.0.5}/flextool/decomposition/region_filter.py +0 -0
  49. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/__init__.py +0 -0
  50. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_axis_enums.py +0 -0
  51. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_benders.py +0 -0
  52. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_block_layout.py +0 -0
  53. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_blocks.py +0 -0
  54. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_commodity_ladder.py +0 -0
  55. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_cumulative_invest.py +0 -0
  56. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_db_loader.py +0 -0
  57. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_db_reader.py +0 -0
  58. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_dc_power_flow.py +0 -0
  59. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_delay.py +0 -0
  60. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_derived_arithmetic.py +0 -0
  61. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_derived_block.py +0 -0
  62. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_derived_branch.py +0 -0
  63. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_derived_existing.py +0 -0
  64. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_derived_npv.py +0 -0
  65. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_derived_params.py +0 -0
  66. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_derived_profile.py +0 -0
  67. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_derived_walks.py +0 -0
  68. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_determinism.py +0 -0
  69. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_direct_params.py +0 -0
  70. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_dump_csvs.py +0 -0
  71. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_arc_unions.py +0 -0
  72. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_calc_params.py +0 -0
  73. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_chain_params.py +0 -0
  74. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_co2_accumulators.py +0 -0
  75. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_dispatchers.py +0 -0
  76. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_energy_margin.py +0 -0
  77. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_energy_margin_adder.py +0 -0
  78. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_entity_annual.py +0 -0
  79. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_inflow_scaling.py +0 -0
  80. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_leaf_sets.py +0 -0
  81. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_lp_scaling.py +0 -0
  82. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_mid_sets.py +0 -0
  83. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_pdt_params.py +0 -0
  84. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_per_solve.py +0 -0
  85. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_period_calc.py +0 -0
  86. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_period_params.py +0 -0
  87. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_provider_io.py +0 -0
  88. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_reserve.py +0 -0
  89. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_solve_time.py +0 -0
  90. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_emit_solve_writers.py +0 -0
  91. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_flex_data_accumulator.py +0 -0
  92. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_flex_data_provider.py +0 -0
  93. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_group_slack.py +0 -0
  94. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_inmemory_reader.py +0 -0
  95. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_input_source.py +0 -0
  96. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_invest_seeds.py +0 -0
  97. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_native_input_writer.py +0 -0
  98. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_native_run_model.py +0 -0
  99. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_orchestration.py +0 -0
  100. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_output_writer.py +0 -0
  101. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_param_shapes.py +0 -0
  102. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_parquet_bundle.py +0 -0
  103. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_pdt_lookup.py +0 -0
  104. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_per_solve_sets.py +0 -0
  105. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_projection_params.py +0 -0
  106. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_provider_keys.py +0 -0
  107. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_provider_translators.py +0 -0
  108. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_recursive_solve.py +0 -0
  109. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_region_filter.py +0 -0
  110. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_reserve.py +0 -0
  111. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_solve_acceptance.py +0 -0
  112. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_solve_config.py +0 -0
  113. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_solve_context.py +0 -0
  114. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_solve_handoff.py +0 -0
  115. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_solve_state.py +0 -0
  116. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_solver_base.py +0 -0
  117. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_solver_dispatch.py +0 -0
  118. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_spinedb_reader.py +0 -0
  119. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_stochastic.py +0 -0
  120. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_subprocess_solve.py +0 -0
  121. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_timeline.py +0 -0
  122. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/_vectorize.py +0 -0
  123. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/autoscale/__init__.py +0 -0
  124. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/autoscale/_config.py +0 -0
  125. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/autoscale/_layer2.py +0 -0
  126. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/autoscale/_layer2_types.py +0 -0
  127. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/autoscale/_quantity_types.py +0 -0
  128. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/autoscale/_report.py +0 -0
  129. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/chain.py +0 -0
  130. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/input.py +0 -0
  131. {flextool-4.0.4 → flextool-4.0.5}/flextool/engine_polars/model.py +0 -0
  132. {flextool-4.0.4 → flextool-4.0.5}/flextool/env_check.py +0 -0
  133. {flextool-4.0.4 → flextool-4.0.5}/flextool/export_to_tabular/__init__.py +0 -0
  134. {flextool-4.0.4 → flextool-4.0.5}/flextool/export_to_tabular/db_reader.py +0 -0
  135. {flextool-4.0.4 → flextool-4.0.5}/flextool/export_to_tabular/excel_writer.py +0 -0
  136. {flextool-4.0.4 → flextool-4.0.5}/flextool/export_to_tabular/export_settings.yaml +0 -0
  137. {flextool-4.0.4 → flextool-4.0.5}/flextool/export_to_tabular/export_to_excel.py +0 -0
  138. {flextool-4.0.4 → flextool-4.0.5}/flextool/export_to_tabular/formatting.py +0 -0
  139. {flextool-4.0.4 → flextool-4.0.5}/flextool/export_to_tabular/sheet_config.py +0 -0
  140. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/__init__.py +0 -0
  141. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/__main__.py +0 -0
  142. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/calibrate_commands.py +0 -0
  143. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/calibrate_jobs.py +0 -0
  144. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/check_tree.py +0 -0
  145. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/cli_format.py +0 -0
  146. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/config_parser.py +0 -0
  147. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/data_models.py +0 -0
  148. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/db_version_check.py +0 -0
  149. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/dialogs/__init__.py +0 -0
  150. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/dialogs/add_dialog.py +0 -0
  151. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/dialogs/calibrate_dialog.py +0 -0
  152. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/dialogs/file_picker.py +0 -0
  153. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/dialogs/group_picker.py +0 -0
  154. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/dialogs/migration_consent_dialog.py +0 -0
  155. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/dialogs/migration_progress_dialog.py +0 -0
  156. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/dialogs/plot_dialog.py +0 -0
  157. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/dialogs/plot_settings_picker.py +0 -0
  158. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/dialogs/project_dialog.py +0 -0
  159. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/dialogs/update_dialog.py +0 -0
  160. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/downsampling.py +0 -0
  161. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/error_handling.py +0 -0
  162. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/execution_manager.py +0 -0
  163. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/execution_window.py +0 -0
  164. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/hover_tooltip.py +0 -0
  165. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/input_sources.py +0 -0
  166. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/network_graph.py +0 -0
  167. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/output_actions.py +0 -0
  168. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/output_log_window.py +0 -0
  169. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/plot_cache.py +0 -0
  170. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/plot_canvas.py +0 -0
  171. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/plot_config_reader.py +0 -0
  172. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/project_utils.py +0 -0
  173. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/result_viewer.py +0 -0
  174. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/scenario_key.py +0 -0
  175. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/scenario_lists.py +0 -0
  176. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/settings_io.py +0 -0
  177. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/solve_reader.py +0 -0
  178. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/tree_reorder.py +0 -0
  179. {flextool-4.0.4 → flextool-4.0.5}/flextool/gui/ui_metrics.py +0 -0
  180. {flextool-4.0.4 → flextool-4.0.5}/flextool/input_derivation/__init__.py +0 -0
  181. {flextool-4.0.4 → flextool-4.0.5}/flextool/input_derivation/_commodity_ladder.py +0 -0
  182. {flextool-4.0.4 → flextool-4.0.5}/flextool/input_derivation/_commodity_ladder_sets.py +0 -0
  183. {flextool-4.0.4 → flextool-4.0.5}/flextool/input_derivation/_dc_power_flow.py +0 -0
  184. {flextool-4.0.4 → flextool-4.0.5}/flextool/input_derivation/_method_constants.py +0 -0
  185. {flextool-4.0.4 → flextool-4.0.5}/flextool/input_derivation/_process_method.py +0 -0
  186. {flextool-4.0.4 → flextool-4.0.5}/flextool/input_derivation/_specs.py +0 -0
  187. {flextool-4.0.4 → flextool-4.0.5}/flextool/input_derivation/_validators.py +0 -0
  188. {flextool-4.0.4 → flextool-4.0.5}/flextool/lean_parquet.py +0 -0
  189. {flextool-4.0.4 → flextool-4.0.5}/flextool/model_builder/__init__.py +0 -0
  190. {flextool-4.0.4 → flextool-4.0.5}/flextool/model_builder/build_model.py +0 -0
  191. {flextool-4.0.4 → flextool-4.0.5}/flextool/model_builder/encoding.py +0 -0
  192. {flextool-4.0.4 → flextool-4.0.5}/flextool/model_builder/names.py +0 -0
  193. {flextool-4.0.4 → flextool-4.0.5}/flextool/model_builder/profiles.py +0 -0
  194. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/__init__.py +0 -0
  195. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/axis_helpers.py +0 -0
  196. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/color_template.py +0 -0
  197. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/config.py +0 -0
  198. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/format_helpers.py +0 -0
  199. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/legend_helpers.py +0 -0
  200. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/orchestrator.py +0 -0
  201. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/perf.py +0 -0
  202. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/plan.py +0 -0
  203. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/plot_bars.py +0 -0
  204. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/plot_bars_detail.py +0 -0
  205. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/plot_lines.py +0 -0
  206. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/shared_manifest.py +0 -0
  207. {flextool-4.0.4 → flextool-4.0.5}/flextool/plot_outputs/subplot_helpers.py +0 -0
  208. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_inputs/__init__.py +0 -0
  209. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_inputs/import_old_excel_input.json +0 -0
  210. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_inputs/read_matpower.py +0 -0
  211. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_inputs/read_old_flextool.py +0 -0
  212. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_inputs/read_self_describing_excel.py +0 -0
  213. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_inputs/read_tabular_with_specification.py +0 -0
  214. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_inputs/write_old_flextool_to_db.py +0 -0
  215. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_inputs/write_self_describing_to_db.py +0 -0
  216. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_inputs/write_to_input_db.py +0 -0
  217. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/__init__.py +0 -0
  218. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/_annualize.py +0 -0
  219. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/_inmemory_helpers.py +0 -0
  220. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/_output_meta.py +0 -0
  221. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/calc_capacity_flows.py +0 -0
  222. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/calc_connections.py +0 -0
  223. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/calc_costs.py +0 -0
  224. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/calc_group_flows.py +0 -0
  225. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/calc_slacks.py +0 -0
  226. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/calc_storage_vre.py +0 -0
  227. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/drop_levels.py +0 -0
  228. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/handoff_writers.py +0 -0
  229. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/out_ancillary.py +0 -0
  230. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/out_capacity.py +0 -0
  231. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/out_costs.py +0 -0
  232. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/out_flowgroup.py +0 -0
  233. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/out_flows.py +0 -0
  234. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/out_group.py +0 -0
  235. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/out_node.py +0 -0
  236. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/persist_realized_slice.py +0 -0
  237. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/process_results.py +0 -0
  238. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/read_highs_solution.py +0 -0
  239. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/read_parameters.py +0 -0
  240. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/read_sets.py +0 -0
  241. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/read_variables.py +0 -0
  242. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/solve_order.py +0 -0
  243. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/spinedb_replay.py +0 -0
  244. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/union_realized_slice.py +0 -0
  245. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/write_outputs.py +0 -0
  246. {flextool-4.0.4 → flextool-4.0.5}/flextool/process_outputs/write_spinedb.py +0 -0
  247. {flextool-4.0.4 → flextool-4.0.5}/flextool/representative_periods/__init__.py +0 -0
  248. {flextool-4.0.4 → flextool-4.0.5}/flextool/representative_periods/clustering.py +0 -0
  249. {flextool-4.0.4 → flextool-4.0.5}/flextool/representative_periods/force_include.py +0 -0
  250. {flextool-4.0.4 → flextool-4.0.5}/flextool/representative_periods/netload.py +0 -0
  251. {flextool-4.0.4 → flextool-4.0.5}/flextool/representative_periods/netload_inputs.py +0 -0
  252. {flextool-4.0.4 → flextool-4.0.5}/flextool/representative_periods/netload_iterate.py +0 -0
  253. {flextool-4.0.4 → flextool-4.0.5}/flextool/representative_periods/preprocess.py +0 -0
  254. {flextool-4.0.4 → flextool-4.0.5}/flextool/representative_periods/scenario_stack.py +0 -0
  255. {flextool-4.0.4 → flextool-4.0.5}/flextool/representative_periods/weights.py +0 -0
  256. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/__init__.py +0 -0
  257. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/config_builder.py +0 -0
  258. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/constants.py +0 -0
  259. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/data_models.py +0 -0
  260. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/db_reader.py +0 -0
  261. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/dispatch_data.py +0 -0
  262. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/dispatch_mappings.py +0 -0
  263. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/dispatch_plots.py +0 -0
  264. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/input_entity_colors.py +0 -0
  265. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/orchestrator.py +0 -0
  266. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/plan_union.py +0 -0
  267. {flextool-4.0.4 → flextool-4.0.5}/flextool/scenario_comparison/plot_settings_seed.py +0 -0
  268. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/AXIS_CONTRACT.md +0 -0
  269. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/canonical_databases/howto_aggregate_output.json +0 -0
  270. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/canonical_databases/howto_connections.json +0 -0
  271. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/canonical_databases/howto_demand.json +0 -0
  272. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/canonical_databases/howto_hydro_reservoir.json +0 -0
  273. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/canonical_databases/howto_hydro_reservoir_with_pump.json +0 -0
  274. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/canonical_databases/howto_non_sync_and_curtailment.json +0 -0
  275. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/canonical_databases/howto_ramp_and_start_up.json +0 -0
  276. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/canonical_databases/howto_stochastics.json +0 -0
  277. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/canonical_databases/templates_examples.json +0 -0
  278. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/canonical_databases/templates_time_settings_only.json +0 -0
  279. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/comparison_settings_template.json +0 -0
  280. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/default_plot_settings.yaml +0 -0
  281. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/default_plots.yaml +0 -0
  282. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/flextool_axis_contract.json +0 -0
  283. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/flextool_axis_contract.schema.json +0 -0
  284. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/old_flextool_import_template.json +0 -0
  285. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/output_info_template.json +0 -0
  286. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/output_settings_template.json +0 -0
  287. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_constant_default.json +0 -0
  288. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_default_optional_output.json +0 -0
  289. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_default_value.json +0 -0
  290. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_drop_down.json +0 -0
  291. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_lifetime_method.json +0 -0
  292. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_optional_outputs.json +0 -0
  293. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_output_node_flows.json +0 -0
  294. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_results_master.json +0 -0
  295. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_rolling_start_remove.json +0 -0
  296. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_rolling_window.json +0 -0
  297. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_storage_binding_defaults.json +0 -0
  298. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_v2.json +0 -0
  299. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/pre_v26/flextool_template_v25.json +0 -0
  300. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/spinedb_results_schema.json +0 -0
  301. {flextool-4.0.4 → flextool-4.0.5}/flextool/schemas/spinedb_schema.json +0 -0
  302. {flextool-4.0.4 → flextool-4.0.5}/flextool/solver_config/copt.opt.template +0 -0
  303. {flextool-4.0.4 → flextool-4.0.5}/flextool/solver_config/cplex.opt.template +0 -0
  304. {flextool-4.0.4 → flextool-4.0.5}/flextool/solver_config/gurobi.opt.template +0 -0
  305. {flextool-4.0.4 → flextool-4.0.5}/flextool/solver_config/highs.opt.template +0 -0
  306. {flextool-4.0.4 → flextool-4.0.5}/flextool/solver_config/xpress.opt.template +0 -0
  307. {flextool-4.0.4 → flextool-4.0.5}/flextool/spinedb_backend/__init__.py +0 -0
  308. {flextool-4.0.4 → flextool-4.0.5}/flextool/spinedb_backend/_axis_enums.py +0 -0
  309. {flextool-4.0.4 → flextool-4.0.5}/flextool/spinedb_backend/_backend.py +0 -0
  310. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/__init__.py +0 -0
  311. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/canonical_databases.py +0 -0
  312. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/db_migration.py +0 -0
  313. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/ensure_settings_db.py +0 -0
  314. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/export_database.py +0 -0
  315. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/extend_tests_fixture.py +0 -0
  316. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/generate_canonical.py +0 -0
  317. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/initialize_database.py +0 -0
  318. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/install_info.py +0 -0
  319. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/self_update.py +0 -0
  320. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/sync_master_json_template.py +0 -0
  321. {flextool-4.0.4 → flextool-4.0.5}/flextool/update_flextool/test_fixtures.py +0 -0
  322. {flextool-4.0.4 → flextool-4.0.5}/flextool.egg-info/SOURCES.txt +0 -0
  323. {flextool-4.0.4 → flextool-4.0.5}/flextool.egg-info/dependency_links.txt +0 -0
  324. {flextool-4.0.4 → flextool-4.0.5}/flextool.egg-info/entry_points.txt +0 -0
  325. {flextool-4.0.4 → flextool-4.0.5}/flextool.egg-info/requires.txt +0 -0
  326. {flextool-4.0.4 → flextool-4.0.5}/flextool.egg-info/top_level.txt +0 -0
  327. {flextool-4.0.4 → flextool-4.0.5}/setup.cfg +0 -0
  328. {flextool-4.0.4 → flextool-4.0.5}/tests/test_bar_layout.py +0 -0
  329. {flextool-4.0.4 → flextool-4.0.5}/tests/test_bar_sub_pixel_labels.py +0 -0
  330. {flextool-4.0.4 → flextool-4.0.5}/tests/test_blocks.py +0 -0
  331. {flextool-4.0.4 → flextool-4.0.5}/tests/test_branch_weights.py +0 -0
  332. {flextool-4.0.4 → flextool-4.0.5}/tests/test_color_template.py +0 -0
  333. {flextool-4.0.4 → flextool-4.0.5}/tests/test_commodity_ladder_rolling.py +0 -0
  334. {flextool-4.0.4 → flextool-4.0.5}/tests/test_comparison_excel.py +0 -0
  335. {flextool-4.0.4 → flextool-4.0.5}/tests/test_comparison_project_root.py +0 -0
  336. {flextool-4.0.4 → flextool-4.0.5}/tests/test_complete_period_share_reduction.py +0 -0
  337. {flextool-4.0.4 → flextool-4.0.5}/tests/test_connection_node_warnings.py +0 -0
  338. {flextool-4.0.4 → flextool-4.0.5}/tests/test_console_run_tool.py +0 -0
  339. {flextool-4.0.4 → flextool-4.0.5}/tests/test_cost_aggregation_semantics.py +0 -0
  340. {flextool-4.0.4 → flextool-4.0.5}/tests/test_cost_breakdown_by_entity.py +0 -0
  341. {flextool-4.0.4 → flextool-4.0.5}/tests/test_csv_dump_roundtrip.py +0 -0
  342. {flextool-4.0.4 → flextool-4.0.5}/tests/test_dc_power_flow.py +0 -0
  343. {flextool-4.0.4 → flextool-4.0.5}/tests/test_dispatch_consumer_and_connection_signs.py +0 -0
  344. {flextool-4.0.4 → flextool-4.0.5}/tests/test_dispatch_node_debug_and_tree.py +0 -0
  345. {flextool-4.0.4 → flextool-4.0.5}/tests/test_dispatch_order_specials.py +0 -0
  346. {flextool-4.0.4 → flextool-4.0.5}/tests/test_dispatch_scenario_tag.py +0 -0
  347. {flextool-4.0.4 → flextool-4.0.5}/tests/test_ensure_settings_db.py +0 -0
  348. {flextool-4.0.4 → flextool-4.0.5}/tests/test_entity_unitsize_invariant.py +0 -0
  349. {flextool-4.0.4 → flextool-4.0.5}/tests/test_entity_universe_carrier.py +0 -0
  350. {flextool-4.0.4 → flextool-4.0.5}/tests/test_env_check.py +0 -0
  351. {flextool-4.0.4 → flextool-4.0.5}/tests/test_export_to_tabular.py +0 -0
  352. {flextool-4.0.4 → flextool-4.0.5}/tests/test_extend_tests_fixture.py +0 -0
  353. {flextool-4.0.4 → flextool-4.0.5}/tests/test_flowgroup_indicators.py +0 -0
  354. {flextool-4.0.4 → flextool-4.0.5}/tests/test_force_include.py +0 -0
  355. {flextool-4.0.4 → flextool-4.0.5}/tests/test_group_output_warnings.py +0 -0
  356. {flextool-4.0.4 → flextool-4.0.5}/tests/test_handoff_writers.py +0 -0
  357. {flextool-4.0.4 → flextool-4.0.5}/tests/test_input_entity_colors.py +0 -0
  358. {flextool-4.0.4 → flextool-4.0.5}/tests/test_lh2_three_region.py +0 -0
  359. {flextool-4.0.4 → flextool-4.0.5}/tests/test_min_load_rolling.py +0 -0
  360. {flextool-4.0.4 → flextool-4.0.5}/tests/test_non_anticipativity.py +0 -0
  361. {flextool-4.0.4 → flextool-4.0.5}/tests/test_old_flextool_importer_schema_drift.py +0 -0
  362. {flextool-4.0.4 → flextool-4.0.5}/tests/test_open_results_db.py +0 -0
  363. {flextool-4.0.4 → flextool-4.0.5}/tests/test_output_column_metadata.py +0 -0
  364. {flextool-4.0.4 → flextool-4.0.5}/tests/test_output_metadata_renderers.py +0 -0
  365. {flextool-4.0.4 → flextool-4.0.5}/tests/test_parameter_group_coverage.py +0 -0
  366. {flextool-4.0.4 → flextool-4.0.5}/tests/test_plan_union.py +0 -0
  367. {flextool-4.0.4 → flextool-4.0.5}/tests/test_plot_draw_order.py +0 -0
  368. {flextool-4.0.4 → flextool-4.0.5}/tests/test_plot_pipeline.py +0 -0
  369. {flextool-4.0.4 → flextool-4.0.5}/tests/test_plot_plan_chunk_reconstruction.py +0 -0
  370. {flextool-4.0.4 → flextool-4.0.5}/tests/test_plot_plan_time_labels_roundtrip.py +0 -0
  371. {flextool-4.0.4 → flextool-4.0.5}/tests/test_plot_settings_seed.py +0 -0
  372. {flextool-4.0.4 → flextool-4.0.5}/tests/test_precision.py +0 -0
  373. {flextool-4.0.4 → flextool-4.0.5}/tests/test_read_highs_solution.py +0 -0
  374. {flextool-4.0.4 → flextool-4.0.5}/tests/test_regional_filter.py +0 -0
  375. {flextool-4.0.4 → flextool-4.0.5}/tests/test_representative_periods.py +0 -0
  376. {flextool-4.0.4 → flextool-4.0.5}/tests/test_rp_alternative_name.py +0 -0
  377. {flextool-4.0.4 → flextool-4.0.5}/tests/test_rp_force_include_wiring.py +0 -0
  378. {flextool-4.0.4 → flextool-4.0.5}/tests/test_rp_solves_filter.py +0 -0
  379. {flextool-4.0.4 → flextool-4.0.5}/tests/test_scenario_colors.py +0 -0
  380. {flextool-4.0.4 → flextool-4.0.5}/tests/test_scenario_stack.py +0 -0
  381. {flextool-4.0.4 → flextool-4.0.5}/tests/test_scenarios.py +0 -0
  382. {flextool-4.0.4 → flextool-4.0.5}/tests/test_self_describing_reader.py +0 -0
  383. {flextool-4.0.4 → flextool-4.0.5}/tests/test_shared_axis_manifest.py +0 -0
  384. {flextool-4.0.4 → flextool-4.0.5}/tests/test_simple_bar_entity_color.py +0 -0
  385. {flextool-4.0.4 → flextool-4.0.5}/tests/test_solve_config.py +0 -0
  386. {flextool-4.0.4 → flextool-4.0.5}/tests/test_solve_reader.py +0 -0
  387. {flextool-4.0.4 → flextool-4.0.5}/tests/test_synthesize_invest_dual.py +0 -0
  388. {flextool-4.0.4 → flextool-4.0.5}/tests/test_timings_csv.py +0 -0
  389. {flextool-4.0.4 → flextool-4.0.5}/tests/test_unidirectional_connection.py +0 -0
  390. {flextool-4.0.4 → flextool-4.0.5}/tests/test_unit_online_dt_columns.py +0 -0
  391. {flextool-4.0.4 → flextool-4.0.5}/tests/test_v52_migration.py +0 -0
  392. {flextool-4.0.4 → flextool-4.0.5}/tests/test_v63_migration.py +0 -0
  393. {flextool-4.0.4 → flextool-4.0.5}/tests/test_v64_migration.py +0 -0
  394. {flextool-4.0.4 → flextool-4.0.5}/tests/test_v65_migration.py +0 -0
  395. {flextool-4.0.4 → flextool-4.0.5}/tests/test_v66_migration.py +0 -0
  396. {flextool-4.0.4 → flextool-4.0.5}/tests/test_v67_migration.py +0 -0
  397. {flextool-4.0.4 → flextool-4.0.5}/tests/test_v68_migration.py +0 -0
  398. {flextool-4.0.4 → flextool-4.0.5}/tests/test_v69_migration.py +0 -0
  399. {flextool-4.0.4 → flextool-4.0.5}/tests/test_workdir_empty_default.py +0 -0
  400. {flextool-4.0.4 → flextool-4.0.5}/tests/test_xlsx_workflow.py +0 -0
  401. {flextool-4.0.4 → flextool-4.0.5}/tests/test_years_represented.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flextool
3
- Version: 4.0.4
3
+ Version: 4.0.5
4
4
  Summary: IRENA FlexTool is an energy and power systems model for understanding the role of variable power generation in future energy systems.
5
5
  Author: IRENA FlexTool contributors
6
6
  License: © International Renewable Energy Agency 2018-2022
@@ -33,6 +33,7 @@ from pathlib import Path
33
33
 
34
34
  from flextool.cli._console import run_tool
35
35
  from flextool.cli.cmd_run_flextool import resolve_output_path
36
+ from flextool.gui.platform_utils import spine_db_editor_argv
36
37
 
37
38
 
38
39
  def resolve_results_db_path(project_folder_file, output_location=None):
@@ -100,16 +101,10 @@ def _build_launch_argv(db_urls):
100
101
  ``db_urls`` may be a single URL string or a list of URLs (each becomes a
101
102
  tab). The supported standalone entry point is
102
103
  ``spinetoolbox.spine_db_editor.main:main``, whose ``main()`` reads
103
- positional ``url`` args.
104
+ positional ``url`` args. Shared with the GUI launchers
105
+ (:func:`flextool.gui.platform_utils.spine_db_editor_argv`).
104
106
  """
105
- if isinstance(db_urls, str):
106
- db_urls = [db_urls]
107
- return [
108
- sys.executable,
109
- "-m",
110
- "spinetoolbox.spine_db_editor.main",
111
- *db_urls,
112
- ]
107
+ return spine_db_editor_argv(db_urls)
113
108
 
114
109
 
115
110
  def launch_db_editor(db_urls, _popen=subprocess.Popen):
@@ -43,6 +43,25 @@ __all__ = (
43
43
  )
44
44
 
45
45
 
46
+ def _cross(left: pl.DataFrame, right: pl.DataFrame) -> pl.DataFrame:
47
+ """``left × right`` in left-major order (each left row, then every
48
+ right row in order).
49
+
50
+ The order is part of the contract: with sorted inputs the product
51
+ is sorted by ``(*left.columns, *right.columns)`` — the canonical
52
+ order that ``add_var`` / ``add_cstr`` assign ids in (the
53
+ determinism wrapper skips its sort when the frame is already
54
+ sorted) and that :mod:`._warm` relies on to align a rolled
55
+ sub-solve's RHS vector with the warm problem's rows by position.
56
+ ``maintain_order`` must be explicit: polars 2 no longer keeps
57
+ left-major order by default for a lazy cross join (it may swap the
58
+ sides and emit right-major order).
59
+ """
60
+ return (left.lazy()
61
+ .join(right.lazy(), how="cross", maintain_order="left_right")
62
+ .collect())
63
+
64
+
46
65
  def compute_pss_dt(flex_data: "FlexData") -> pl.DataFrame | None:
47
66
  """Lazy-build the ``(p, source, sink, d, t)`` cross-product from
48
67
  ``flex_data.process_source_sink`` × ``flex_data.dt``.
@@ -53,7 +72,7 @@ def compute_pss_dt(flex_data: "FlexData") -> pl.DataFrame | None:
53
72
  dt = getattr(flex_data, "dt", None)
54
73
  if pss is None or dt is None or pss.height == 0 or dt.height == 0:
55
74
  return None
56
- return pss.lazy().join(dt.lazy(), how="cross").collect()
75
+ return _cross(pss, dt)
57
76
 
58
77
 
59
78
  def compute_nodeBalance_dt(flex_data: "FlexData") -> pl.DataFrame | None:
@@ -66,7 +85,7 @@ def compute_nodeBalance_dt(flex_data: "FlexData") -> pl.DataFrame | None:
66
85
  dt = getattr(flex_data, "dt", None)
67
86
  if nb is None or dt is None or nb.height == 0 or dt.height == 0:
68
87
  return None
69
- return nb.lazy().join(dt.lazy(), how="cross").collect()
88
+ return _cross(nb, dt)
70
89
 
71
90
 
72
91
  def compute_nodeState_dt(flex_data: "FlexData") -> pl.DataFrame | None:
@@ -79,7 +98,7 @@ def compute_nodeState_dt(flex_data: "FlexData") -> pl.DataFrame | None:
79
98
  dt = getattr(flex_data, "dt", None)
80
99
  if ns is None or dt is None or ns.height == 0 or dt.height == 0:
81
100
  return None
82
- return ns.lazy().join(dt.lazy(), how="cross").collect()
101
+ return _cross(ns, dt)
83
102
 
84
103
 
85
104
  def compute_nodeState_first_dt(flex_data: "FlexData") -> pl.DataFrame | None:
@@ -128,7 +147,7 @@ def compute_nodeState_rp_dt(flex_data: "FlexData") -> pl.DataFrame | None:
128
147
  dt = getattr(flex_data, "dt", None)
129
148
  if nsrp is None or dt is None or nsrp.height == 0 or dt.height == 0:
130
149
  return None
131
- return nsrp.lazy().join(dt.lazy(), how="cross").collect()
150
+ return _cross(nsrp, dt)
132
151
 
133
152
 
134
153
  def compute_nodeState_rp_block_first_dt(
@@ -151,7 +170,7 @@ def compute_nodeState_rp_block_first_dt(
151
170
  if (nsrp is None or rpbf is None
152
171
  or nsrp.height == 0 or rpbf.height == 0):
153
172
  return None
154
- return nsrp.lazy().join(rpbf.lazy(), how="cross").collect()
173
+ return _cross(nsrp, rpbf)
155
174
 
156
175
 
157
176
  def compute_process_indirect_dt(flex_data: "FlexData") -> pl.DataFrame | None:
@@ -164,4 +183,4 @@ def compute_process_indirect_dt(flex_data: "FlexData") -> pl.DataFrame | None:
164
183
  dt = getattr(flex_data, "dt", None)
165
184
  if pi is None or dt is None or pi.height == 0 or dt.height == 0:
166
185
  return None
167
- return pi.lazy().join(dt.lazy(), how="cross").collect()
186
+ return _cross(pi, dt)
@@ -743,17 +743,28 @@ def _apply_warm_updates(warm: WarmProblem,
743
743
  raise _IncompatibleUpdate(
744
744
  f"warm-update needs FlexData.{over_field}, but it "
745
745
  f"is None on the new sub-solve")
746
+ # The cstr's rows are in ``over`` sorted by its columns
747
+ # (the add_cstr determinism wrapper,
748
+ # ``engine_polars/__init__.py``), so sort ``new_over``
749
+ # the same way: position i then names the same row in
750
+ # both sub-solves (labels shift, order does not). Do
751
+ # not trust the producer's row order — a polars 2 lazy
752
+ # cross join emits right-major order unless told
753
+ # otherwise, which pushed every other (n, t) inflow onto
754
+ # the wrong row.
755
+ new_over = new_over.sort(new_over.columns)
746
756
  # Left-join new_over with next_p on shared dims; values
747
- # come out aligned to new_over's row order, which by
748
- # fingerprint match has the same row count as the
749
- # original LP cstr over.
757
+ # come out aligned to new_over's row order (kept by
758
+ # ``maintain_order="left"``), which by fingerprint match
759
+ # has the same row count as the original LP cstr over.
750
760
  shared = [c for c in next_p.dims if c in new_over.columns]
751
761
  if not shared:
752
762
  rhs_vec = np.full(new_over.height,
753
763
  float(next_p.frame["value"][0]),
754
764
  dtype=np.float64)
755
765
  else:
756
- j = new_over.join(next_p.frame, on=shared, how="left")
766
+ j = new_over.join(next_p.frame, on=shared, how="left",
767
+ maintain_order="left")
757
768
  rhs_vec = (j["value"].fill_null(0.0)
758
769
  .to_numpy()
759
770
  .astype(np.float64, copy=False))
@@ -4,11 +4,14 @@ from __future__ import annotations
4
4
 
5
5
  import logging
6
6
  import os
7
- import shutil
8
7
  import subprocess
8
+ import sys
9
9
  import tempfile
10
+ from collections.abc import Sequence
10
11
  from pathlib import Path
11
12
 
13
+ from flextool.gui.platform_utils import spine_db_editor_argv, spine_toolbox_available
14
+
12
15
  logger = logging.getLogger(__name__)
13
16
 
14
17
 
@@ -20,11 +23,14 @@ class DbEditorManager:
20
23
  is still open in an editor.
21
24
  - Open additional databases by launching new editor instances.
22
25
 
23
- Spine DB Editor (``spine-db-editor``) accepts multiple database URLs
24
- on the command line and opens them as tabs (use ``-s`` for separate
25
- tabs). However, there is no IPC mechanism to add a tab to an
26
- already-running instance, so each call to :meth:`open_database`
27
- launches a new process.
26
+ The editor is started with the interpreter running FlexTool
27
+ (``<sys.executable> -m spinetoolbox.spine_db_editor.main <url>...``,
28
+ see :func:`~flextool.gui.platform_utils.spine_db_editor_argv`), never
29
+ via a ``spine-db-editor`` looked up on PATH: a ``flextool-gui`` started
30
+ from a venv that is not activated has no venv ``bin`` on PATH. It
31
+ accepts multiple database URLs and opens them as tabs. However, there
32
+ is no IPC mechanism to add a tab to an already-running instance, so
33
+ each call to :meth:`open_database` launches a new process.
28
34
  """
29
35
 
30
36
  def __init__(self) -> None:
@@ -37,26 +43,33 @@ class DbEditorManager:
37
43
 
38
44
  # ── Opening databases ─────────────────────────────────────────
39
45
 
40
- def open_database(self, db_url: str, source_name: str) -> subprocess.Popen | None:
41
- """Launch ``spine-db-editor`` for *db_url* and track the process.
46
+ def open_database(
47
+ self, db_url: str | Sequence[str], source_name: str
48
+ ) -> subprocess.Popen | None:
49
+ """Launch the Spine DB editor for *db_url* and track the process.
42
50
 
43
51
  The editor's own stdout/stderr is redirected to a temporary log file
44
52
  so that, if it exits immediately, the caller can read the failure via
45
53
  :meth:`read_launch_output` and surface it to the user.
46
54
 
47
55
  Args:
48
- db_url: SQLAlchemy-style database URL (e.g. ``sqlite:///path``).
56
+ db_url: SQLAlchemy-style database URL (e.g. ``sqlite:///path``),
57
+ or several URLs to open as tabs of one editor.
49
58
  source_name: Logical name used to track which input source is
50
59
  being edited.
51
60
 
52
61
  Returns:
53
- The :class:`subprocess.Popen` object, or ``None`` if the
54
- editor executable is not found on ``PATH``.
62
+ The :class:`subprocess.Popen` object, or ``None`` if Spine
63
+ Toolbox is not importable by the interpreter running FlexTool
64
+ (or the launch itself fails).
55
65
  """
56
- exe = shutil.which("spine-db-editor")
57
- if exe is None:
58
- logger.warning("spine-db-editor not found on PATH")
66
+ if not spine_toolbox_available():
67
+ logger.warning(
68
+ "Spine Toolbox (spinetoolbox) is not installed in this Python "
69
+ "environment (%s); cannot open the Spine DB editor",
70
+ sys.executable)
59
71
  return None
72
+ argv = spine_db_editor_argv(db_url)
60
73
 
61
74
  log_path: Path | None = None
62
75
  log_handle = None
@@ -71,12 +84,12 @@ class DbEditorManager:
71
84
  try:
72
85
  if log_handle is not None:
73
86
  proc = subprocess.Popen(
74
- [exe, db_url], stdout=log_handle, stderr=subprocess.STDOUT
87
+ argv, stdout=log_handle, stderr=subprocess.STDOUT
75
88
  )
76
89
  else:
77
- proc = subprocess.Popen([exe, db_url])
90
+ proc = subprocess.Popen(argv)
78
91
  except OSError:
79
- logger.warning("Failed to launch spine-db-editor", exc_info=True)
92
+ logger.warning("Failed to launch the Spine DB editor", exc_info=True)
80
93
  if log_path is not None:
81
94
  try:
82
95
  log_path.unlink(missing_ok=True)
@@ -3123,14 +3123,16 @@ class MainWindow(tk.Tk):
3123
3123
  db_url = f"sqlite:///{filepath}"
3124
3124
  proc = self.db_editor_mgr.open_database(db_url, source_name)
3125
3125
  if proc is None:
3126
- # spine-db-editor not found: point at 'Update FlexTool' and
3126
+ # Spine Toolbox not installed in this environment: point at
3127
+ # 'Update FlexTool' and
3127
3128
  # offer the system default .sqlite app as a fallback.
3128
3129
  # askyesnocancel: Yes=Update, No=default app, Cancel=nothing.
3129
3130
  from flextool.update_flextool import install_info
3130
3131
  choice = messagebox.askyesnocancel(
3131
3132
  "Spine DB Editor not available",
3132
- "The 'spine-db-editor' command was not found, so .sqlite "
3133
- "input sources cannot be opened in the Spine DB Editor.\n\n"
3133
+ "Spine Toolbox is not installed in the Python environment "
3134
+ "running FlexTool, so .sqlite input sources cannot be "
3135
+ "opened in the Spine DB Editor.\n\n"
3134
3136
  "It is part of Spine Toolbox. You can install it via "
3135
3137
  "'Update FlexTool' (tick 'Install Spine Toolbox'), or "
3136
3138
  "manually:\n\n"
@@ -3150,7 +3152,7 @@ class MainWindow(tk.Tk):
3150
3152
  "Error", f"Could not open file:\n{exc}"
3151
3153
  )
3152
3154
  return
3153
- # spine-db-editor was found and launched, but an incomplete Spine
3155
+ # The Spine DB editor was launched, but an incomplete Spine
3154
3156
  # Toolbox install can still crash it on startup. Check shortly after
3155
3157
  # launch and explain the failure instead of leaving the user with a
3156
3158
  # silent no-op (the crash otherwise only shows in the terminal).
@@ -5999,8 +6001,9 @@ class MainWindow(tk.Tk):
5999
6001
  def _on_show_comp_spinedb(self) -> None:
6000
6002
  """Open the project-wide results.sqlite SpineDB.
6001
6003
 
6002
- Prefer the Spine DB Editor when ``spine-db-editor`` is available on
6003
- PATH (i.e. Spine Toolbox is installed in the venv). If it is not,
6004
+ Prefer the Spine DB Editor when Spine Toolbox is installed in the
6005
+ environment running FlexTool (launched as
6006
+ ``python -m spinetoolbox.spine_db_editor.main``). If it is not,
6004
6007
  explain that Spine Toolbox can be added via 'Update FlexTool' and
6005
6008
  offer to open the file with the system's default .sqlite application
6006
6009
  instead.
@@ -6029,15 +6032,15 @@ class MainWindow(tk.Tk):
6029
6032
  db_url = f"sqlite:///{results_db}"
6030
6033
  proc = self.db_editor_mgr.open_database(db_url, source_name)
6031
6034
  if proc is None:
6032
- # spine-db-editor not found: inform the user, point at
6035
+ # Spine Toolbox not installed here: inform the user, point at
6033
6036
  # 'Update FlexTool', and offer the system default .sqlite app
6034
6037
  # as a fallback. askyesnocancel: Yes=Update, No=default app,
6035
6038
  # Cancel=do nothing.
6036
6039
  choice = messagebox.askyesnocancel(
6037
6040
  "Spine DB Editor not available",
6038
- "The 'spine-db-editor' command was not found, so the "
6039
- "comparison results.sqlite cannot be opened in the Spine DB "
6040
- "Editor.\n\n"
6041
+ "Spine Toolbox is not installed in the Python environment "
6042
+ "running FlexTool, so the comparison results.sqlite cannot be "
6043
+ "opened in the Spine DB Editor.\n\n"
6041
6044
  "It is part of Spine Toolbox, which can be added via "
6042
6045
  "'Update FlexTool' (tick 'Install Spine Toolbox').\n\n"
6043
6046
  "Open 'Update FlexTool' now?\n\n"
@@ -6053,7 +6056,7 @@ class MainWindow(tk.Tk):
6053
6056
  except OSError as exc:
6054
6057
  logger.warning("Could not open results SpineDB: %s", exc)
6055
6058
  return
6056
- # spine-db-editor was found and launched, but an incomplete Spine
6059
+ # The Spine DB editor was launched, but an incomplete Spine
6057
6060
  # Toolbox install can still crash it on startup. Check shortly after
6058
6061
  # launch and explain the failure instead of leaving a silent no-op.
6059
6062
  self.after(2000, self._check_db_editor_launch, proc, source_name)
@@ -6,6 +6,7 @@ import logging
6
6
  import os
7
7
  import subprocess
8
8
  import sys
9
+ from collections.abc import Sequence
9
10
  from pathlib import Path
10
11
  from typing import TYPE_CHECKING
11
12
 
@@ -93,26 +94,53 @@ def open_folder(dirpath: Path) -> None:
93
94
  )
94
95
 
95
96
 
96
- def open_spine_db_editor(db_url: str) -> subprocess.Popen | None:
97
- """Launch the Spine DB editor on *db_url* as a subprocess, using the current
98
- environment's Spine Toolbox (``python -m spinetoolbox.spine_db_editor.main``,
99
- matching the CLI launcher) rather than a ``spine-db-editor`` found anywhere
100
- on PATH.
97
+ #: Module run (``python -m``) to start the standalone Spine DB editor — the
98
+ #: target of Spine Toolbox's ``spine-db-editor`` console script.
99
+ SPINE_DB_EDITOR_MODULE = "spinetoolbox.spine_db_editor.main"
100
+
101
+
102
+ def spine_toolbox_available() -> bool:
103
+ """Whether Spine Toolbox is importable by the interpreter running FlexTool.
104
+
105
+ Deliberately not a PATH lookup: ``flextool-gui`` started from a venv that
106
+ is not activated (``.venv/bin/flextool-gui``) does not have the venv's
107
+ ``bin`` on PATH, and a ``spine-db-editor`` found on PATH may belong to a
108
+ different environment.
109
+ """
110
+ import importlib.util
111
+
112
+ return importlib.util.find_spec("spinetoolbox") is not None
113
+
114
+
115
+ def spine_db_editor_argv(db_urls: str | Sequence[str]) -> list[str]:
116
+ """argv that opens *db_urls* (one URL or several, each a tab) in the
117
+ Spine DB editor of the current environment
118
+ (``<sys.executable> -m spinetoolbox.spine_db_editor.main <url>...``).
119
+
120
+ The single source for every FlexTool launcher of the editor (GUI and
121
+ CLI), so they cannot drift back to a PATH lookup.
122
+ """
123
+ urls = [db_urls] if isinstance(db_urls, str) else list(db_urls)
124
+ return [sys.executable, "-m", SPINE_DB_EDITOR_MODULE, *urls]
125
+
126
+
127
+ def open_spine_db_editor(db_urls: str | Sequence[str]) -> subprocess.Popen | None:
128
+ """Launch the Spine DB editor on *db_urls* as a subprocess, using the
129
+ current environment's Spine Toolbox (:func:`spine_db_editor_argv`)
130
+ rather than a ``spine-db-editor`` found anywhere on PATH.
101
131
 
102
132
  Returns:
103
133
  The :class:`subprocess.Popen` object, or ``None`` if Spine Toolbox is
104
134
  not installed in this environment.
105
135
  """
106
- import importlib.util
107
-
108
- if importlib.util.find_spec("spinetoolbox") is None:
109
- logger.warning("spinetoolbox is not installed in this environment")
136
+ if not spine_toolbox_available():
137
+ logger.warning(
138
+ "Spine Toolbox (spinetoolbox) is not installed in this Python "
139
+ "environment (%s); cannot open the Spine DB editor", sys.executable)
110
140
  return None
111
141
 
112
142
  try:
113
- proc = subprocess.Popen(
114
- [sys.executable, "-m", "spinetoolbox.spine_db_editor.main", db_url]
115
- )
143
+ proc = subprocess.Popen(spine_db_editor_argv(db_urls))
116
144
  return proc
117
145
  except OSError:
118
146
  logger.warning("Failed to launch the Spine DB editor", exc_info=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flextool
3
- Version: 4.0.4
3
+ Version: 4.0.5
4
4
  Summary: IRENA FlexTool is an energy and power systems model for understanding the role of variable power generation in future energy systems.
5
5
  Author: IRENA FlexTool contributors
6
6
  License: © International Renewable Energy Agency 2018-2022
@@ -3,7 +3,7 @@ build-backend = "setuptools.build_meta"
3
3
 
4
4
  [project]
5
5
  name = "flextool"
6
- version = "4.0.4"
6
+ version = "4.0.5"
7
7
  description = "IRENA FlexTool is an energy and power systems model for understanding the role of variable power generation in future energy systems."
8
8
  readme = "README.md"
9
9
  license = { file = "LICENSE.txt" }
File without changes
File without changes
File without changes