labnotes 0.2.10__tar.gz → 0.2.12__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 (225) hide show
  1. {labnotes-0.2.10 → labnotes-0.2.12}/PKG-INFO +1 -1
  2. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/run_experiment.py +1 -1
  3. labnotes-0.2.12/src/labnotes/tui/run_output.py +106 -0
  4. {labnotes-0.2.10 → labnotes-0.2.12}/testing-conventions.toml +6 -0
  5. labnotes-0.2.10/src/labnotes/tui/run_output.py +0 -80
  6. {labnotes-0.2.10 → labnotes-0.2.12}/.gitignore +0 -0
  7. {labnotes-0.2.10 → labnotes-0.2.12}/CHANGELOG.md +0 -0
  8. {labnotes-0.2.10 → labnotes-0.2.12}/MIGRATIONS.md +0 -0
  9. {labnotes-0.2.10 → labnotes-0.2.12}/README.md +0 -0
  10. {labnotes-0.2.10 → labnotes-0.2.12}/pyproject.toml +0 -0
  11. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/__init__.py +0 -0
  12. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/__main__.py +0 -0
  13. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/asset_url.py +0 -0
  14. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/check_counts.py +0 -0
  15. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/cli.py +0 -0
  16. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/command_line_group.py +0 -0
  17. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/compose_experiment.py +0 -0
  18. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/config_migration.py +0 -0
  19. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/context.md +0 -0
  20. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/context_guide.py +0 -0
  21. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/copy_experiment.py +0 -0
  22. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/count_groups.py +0 -0
  23. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/count_runs.py +0 -0
  24. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/create_app.py +0 -0
  25. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/create_experiment.py +0 -0
  26. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/create_note.py +0 -0
  27. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/data_html.py +0 -0
  28. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/default_config_text.py +0 -0
  29. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/default_counts.py +0 -0
  30. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/drain_watch.py +0 -0
  31. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/experiment_definition.py +0 -0
  32. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/experiment_notes.py +0 -0
  33. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/experiment_runs.py +0 -0
  34. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/experiments.py +0 -0
  35. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/file_changes.py +0 -0
  36. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/format_duration.py +0 -0
  37. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/format_started.py +0 -0
  38. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/format_value.py +0 -0
  39. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/get_state.py +0 -0
  40. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/grid_cell.py +0 -0
  41. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/group_runs.py +0 -0
  42. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/init.py +0 -0
  43. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/invocation_started.py +0 -0
  44. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/is_non_negative_int.py +0 -0
  45. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/is_non_negative_number.py +0 -0
  46. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/is_positive_int.py +0 -0
  47. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/latest_log.py +0 -0
  48. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/list_experiments.py +0 -0
  49. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/list_runs.py +0 -0
  50. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/load_config.py +0 -0
  51. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/load_experiment.py +0 -0
  52. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/load_run.py +0 -0
  53. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/log.py +0 -0
  54. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/log_path.py +0 -0
  55. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/memory_interval.py +0 -0
  56. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/models.py +0 -0
  57. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/nests_runs.py +0 -0
  58. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/note_path.py +0 -0
  59. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/notebook_kernel.py +0 -0
  60. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/output_html.py +0 -0
  61. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/param_names.py +0 -0
  62. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/parse_param_value.py +0 -0
  63. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/parse_params.py +0 -0
  64. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/parse_run_view.py +0 -0
  65. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/parse_subset.py +0 -0
  66. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/pivot_runs.py +0 -0
  67. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/print_rows.py +0 -0
  68. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/python_blocks.py +0 -0
  69. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/read_config.py +0 -0
  70. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/read_path.py +0 -0
  71. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/render_markdown.py +0 -0
  72. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/retries.py +0 -0
  73. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/run_columns.py +0 -0
  74. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/run_output.py +0 -0
  75. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/__init__.py +0 -0
  76. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/cgroup_memory.py +0 -0
  77. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/check_args.py +0 -0
  78. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/check_hook_placeholders.py +0 -0
  79. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/check_subset.py +0 -0
  80. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/claim_run.py +0 -0
  81. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/command_flags.py +0 -0
  82. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/container_cgroup.py +0 -0
  83. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/container_memory.py +0 -0
  84. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/continue_run.py +0 -0
  85. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/describe_event.py +0 -0
  86. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/docker_output.py +0 -0
  87. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/execute_run.py +0 -0
  88. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/exit_signal.py +0 -0
  89. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/fill_dirs.py +0 -0
  90. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/fill_experiment_env.py +0 -0
  91. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/finalize_lost_runs.py +0 -0
  92. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/first_invocation.py +0 -0
  93. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/flag_name.py +0 -0
  94. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/group_args.py +0 -0
  95. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/hold_experiment.py +0 -0
  96. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/in_subset.py +0 -0
  97. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/invocation_hook.py +0 -0
  98. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/invocation_meta.py +0 -0
  99. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/new_run_id.py +0 -0
  100. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/new_stamped_run_id.py +0 -0
  101. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/override_flags.py +0 -0
  102. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/param_args.py +0 -0
  103. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/param_grid.py +0 -0
  104. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/placeholders.py +0 -0
  105. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/plan_runs.py +0 -0
  106. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/prepare_experiment.py +0 -0
  107. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/project_snapshot.py +0 -0
  108. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/read_experiment_config.py +0 -0
  109. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/record_memory.py +0 -0
  110. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/run_folder.py +0 -0
  111. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/run_git.py +0 -0
  112. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/run_headless.py +0 -0
  113. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/run_locked.py +0 -0
  114. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/runs_parent.py +0 -0
  115. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/shell_command.py +0 -0
  116. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/signal_tree.py +0 -0
  117. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/start_experiment.py +0 -0
  118. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/stop_then_kill.py +0 -0
  119. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/untracked_diff.py +0 -0
  120. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/wait_for_tree.py +0 -0
  121. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runner/write_run_json.py +0 -0
  122. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/runs_view_command.py +0 -0
  123. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/save_conflict_copy.py +0 -0
  124. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/save_note.py +0 -0
  125. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/saved_outputs.py +0 -0
  126. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/serve_app.py +0 -0
  127. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/server.py +0 -0
  128. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/set_state.py +0 -0
  129. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/shared_params.py +0 -0
  130. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/sort_href.py +0 -0
  131. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/sql_quote.py +0 -0
  132. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/state_path.py +0 -0
  133. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/static/elapsed.js +0 -0
  134. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/static/experiment.js +0 -0
  135. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/static/labnotes.css +0 -0
  136. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/static/local-time.js +0 -0
  137. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/static/new-note.js +0 -0
  138. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/static/note-edit.js +0 -0
  139. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/static/note-editor.js +0 -0
  140. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/static/row-link.js +0 -0
  141. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/static/run-cell.js +0 -0
  142. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/static/run-output.js +0 -0
  143. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/static/view-toggle.js +0 -0
  144. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/summarize_config.py +0 -0
  145. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/__init__.py +0 -0
  146. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/experiment_rows.py +0 -0
  147. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/experiment_run_ids.py +0 -0
  148. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/experiment_toml.py +0 -0
  149. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/experiments_ddl.py +0 -0
  150. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/file_prefix.py +0 -0
  151. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/file_text.py +0 -0
  152. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/iso_time.py +0 -0
  153. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/list_experiment_runs.py +0 -0
  154. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/list_resumable_runs.py +0 -0
  155. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/note_text.py +0 -0
  156. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/open_tables.py +0 -0
  157. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/path_glob.py +0 -0
  158. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/path_pattern.py +0 -0
  159. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/read_blocks.py +0 -0
  160. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/read_experiment.py +0 -0
  161. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/read_file.py +0 -0
  162. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/read_log.py +0 -0
  163. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/read_memory.py +0 -0
  164. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/read_run.py +0 -0
  165. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/read_run_file.py +0 -0
  166. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/runs_columns.py +0 -0
  167. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tables/summarize_experiments.py +0 -0
  168. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/templates/base.html +0 -0
  169. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/templates/editor_imports.html +0 -0
  170. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/templates/experiment.html +0 -0
  171. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/templates/index.html +0 -0
  172. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/templates/note.html +0 -0
  173. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/templates/run.html +0 -0
  174. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/__init__.py +0 -0
  175. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/browse_app.py +0 -0
  176. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/browse_tui.py +0 -0
  177. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/check_view_response.py +0 -0
  178. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/config.py +0 -0
  179. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/dim.py +0 -0
  180. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/experiment_screen.py +0 -0
  181. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/experiments_screen.py +0 -0
  182. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/fill_table.py +0 -0
  183. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/format_cell.py +0 -0
  184. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/format_elapsed.py +0 -0
  185. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/guard_view.py +0 -0
  186. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/leave_prompt.py +0 -0
  187. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/load_view.py +0 -0
  188. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/log_block.py +0 -0
  189. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/log_blocks.py +0 -0
  190. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/native_rows.py +0 -0
  191. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/reload_on_change.py +0 -0
  192. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/run_app.py +0 -0
  193. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/run_cells.py +0 -0
  194. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/run_panel.py +0 -0
  195. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/run_tui.py +0 -0
  196. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/runs_browser.py +0 -0
  197. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/runs_table.py +0 -0
  198. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/runs_view.py +0 -0
  199. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/stopped_title.py +0 -0
  200. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/table_columns.py +0 -0
  201. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/table_rows.py +0 -0
  202. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/view_column.py +0 -0
  203. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/view_pane.py +0 -0
  204. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/view_process.py +0 -0
  205. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/tui/view_switcher.py +0 -0
  206. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/utils/__init__.py +0 -0
  207. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/utils/format_bytes.py +0 -0
  208. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/utils/process_alive.py +0 -0
  209. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/utils/run_usage.py +0 -0
  210. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/utils/tree_rss.py +0 -0
  211. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/utils/tree_usage.py +0 -0
  212. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/view/__init__.py +0 -0
  213. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/view/answer.py +0 -0
  214. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/view/build.py +0 -0
  215. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/view/changed.py +0 -0
  216. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/view/experiment.py +0 -0
  217. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/view/respond.py +0 -0
  218. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/view/serve.py +0 -0
  219. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/view_specs.py +0 -0
  220. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/wait_for_note.py +0 -0
  221. {labnotes-0.2.10 → labnotes-0.2.12}/src/labnotes/watch_rows.py +0 -0
  222. {labnotes-0.2.10 → labnotes-0.2.12}/tests/conftest.py +0 -0
  223. {labnotes-0.2.10 → labnotes-0.2.12}/tests/e2e/conftest.py +0 -0
  224. {labnotes-0.2.10 → labnotes-0.2.12}/tests/integration/conftest.py +0 -0
  225. {labnotes-0.2.10 → labnotes-0.2.12}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: labnotes
3
- Version: 0.2.10
3
+ Version: 0.2.12
4
4
  Summary: Browse experiment designs, notes, and run data from a folder.
5
5
  Project-URL: Repository, https://github.com/thekevinscott/labnotes
6
6
  Author-email: Kevin Scott <me@thekevinscott.com>
@@ -293,7 +293,7 @@ async def run_experiment(
293
293
  del running[run], trees[run]
294
294
  report({"event": "ended", "run": run, **result})
295
295
  ended[run] = params
296
- results[run] = result
296
+ results[run] = {"run": run, **result}
297
297
  if result["exit_code"] == RETRY_EXIT_CODE and not (
298
298
  stopping.is_set() or run in stopped
299
299
  ):
@@ -0,0 +1,106 @@
1
+ import codecs
2
+ from collections.abc import Iterable
3
+ from pathlib import Path
4
+ from typing import Self
5
+
6
+ from rich.style import Style
7
+ from rich.text import Text
8
+ from rich.cells import cell_len
9
+ from textual.geometry import Size
10
+ from textual.strip import Strip
11
+ from textual.widgets import Log
12
+
13
+ from labnotes.latest_log import latest_log
14
+
15
+ STREAMS = ("stdout", "stderr")
16
+
17
+
18
+ class RunOutput(Log):
19
+ def __init__(self, id: str | None = None) -> None:
20
+ super().__init__(id=id)
21
+ self.reset()
22
+
23
+ def reset(self) -> None:
24
+ self.offsets = dict.fromkeys(STREAMS, 0)
25
+ self.paths: dict[str, Path] = {}
26
+ self.decoders = {
27
+ stream: codecs.getincrementaldecoder("utf-8")(errors="replace")
28
+ for stream in STREAMS
29
+ }
30
+ self.last_stream: str | None = None
31
+ self.unfinished = ""
32
+ self.clear()
33
+
34
+ @property
35
+ def mid_line(self) -> bool:
36
+ return bool(self.unfinished)
37
+
38
+ def follow(self, folder: Path) -> None:
39
+ for stream in STREAMS:
40
+ path = latest_log(folder, stream)
41
+ if not path.exists():
42
+ continue
43
+ if self.paths.setdefault(stream, path) != path:
44
+ self.paths[stream] = path
45
+ self.offsets[stream] = 0
46
+ with path.open("rb") as log:
47
+ log.seek(self.offsets[stream])
48
+ data = log.read()
49
+ self.offsets[stream] += len(data)
50
+ text = self.decoders[stream].decode(data)
51
+ if not text:
52
+ continue
53
+ # A stream's unfinished line is redrawn as it grows, but the
54
+ # other stream's output starts below it.
55
+ if self.mid_line and stream == self.last_stream:
56
+ self.drop_unfinished()
57
+ text = self.unfinished + text
58
+ *complete, self.unfinished = text.split("\n")
59
+ if complete:
60
+ self.write_lines(complete)
61
+ if self.unfinished:
62
+ self.write_lines([self.unfinished])
63
+ self.last_stream = stream
64
+
65
+ def write_lines(self, lines: Iterable[str], scroll_end: bool | None = None) -> Self:
66
+ new_lines = list(lines)
67
+ if not new_lines:
68
+ return self
69
+ at_end = self.is_vertical_scroll_end
70
+ self._lines.extend(new_lines)
71
+ self._width = max(self._width, max(map(len, new_lines)))
72
+ self.virtual_size = Size(self._width, len(self._lines))
73
+ self.refresh()
74
+ if (
75
+ self.is_mounted
76
+ and (self.auto_scroll if scroll_end is None else scroll_end)
77
+ and at_end
78
+ ):
79
+ self.scroll_end(animate=False, immediate=True, x_axis=False)
80
+ return self
81
+
82
+ def drop_unfinished(self) -> None:
83
+ self._lines.pop()
84
+ self._render_line_cache.discard(len(self._lines))
85
+ self.virtual_size = Size(self._width, len(self._lines))
86
+ self.refresh()
87
+
88
+ def _render_line_strip(self, y: int, rich_style: Style) -> Strip:
89
+ selection = self.text_selection
90
+ if selection is None and y in self._render_line_cache:
91
+ return self._render_line_cache[y]
92
+ line_text = Text.from_ansi(self._lines[y], style=rich_style)
93
+ if selection is not None:
94
+ if (span := selection.get_span(y)) is not None:
95
+ start, end = span
96
+ if end == -1:
97
+ end = len(line_text)
98
+ line_text.stylize(
99
+ self.screen.get_component_rich_style("screen--selection"),
100
+ start,
101
+ end,
102
+ )
103
+ line = Strip(line_text.render(self.app.console), cell_len(line_text.plain))
104
+ if selection is None:
105
+ self._render_line_cache[y] = line
106
+ return line
@@ -51,3 +51,9 @@ path = "src/labnotes/runner/hold_experiment.py"
51
51
  rules = ["mutation"]
52
52
  lines = [18]
53
53
  reason = "LOCK_EX and LOCK_NB are disjoint bits, so | equals + and ^"
54
+
55
+ [[python.exempt]]
56
+ path = "src/labnotes/tui/run_output.py"
57
+ rules = ["mutation"]
58
+ lines = [96]
59
+ reason = "a selection span ends at -1 or a non-negative offset, so <= equals ==; -1 is a CPython cached small int, so is equals =="
@@ -1,80 +0,0 @@
1
- import codecs
2
- from pathlib import Path
3
- from typing import Any, Self
4
-
5
- from rich.text import Text
6
- from textual.geometry import Size
7
- from textual.widgets import RichLog
8
-
9
- from labnotes.latest_log import latest_log
10
-
11
- STREAMS = ("stdout", "stderr")
12
-
13
-
14
- class RunOutput(RichLog):
15
- def __init__(self, id: str | None = None) -> None:
16
- super().__init__(id=id, wrap=True, min_width=1)
17
- self.reset()
18
-
19
- def reset(self) -> None:
20
- self.offsets = dict.fromkeys(STREAMS, 0)
21
- self.paths: dict[str, Path] = {}
22
- self.decoders = {
23
- stream: codecs.getincrementaldecoder("utf-8")(errors="replace")
24
- for stream in STREAMS
25
- }
26
- self.last_stream: str | None = None
27
- self.unfinished = ""
28
- self.written_rows = 0
29
- self.clear()
30
- # A hidden log has no width; writing now would wrap every line to one
31
- # cell. Hold writes until it's shown and resized.
32
- self._size_known = bool(self.scrollable_content_region.width)
33
-
34
- @property
35
- def mid_line(self) -> bool:
36
- return bool(self.unfinished)
37
-
38
- def follow(self, folder: Path) -> None:
39
- for stream in STREAMS:
40
- path = latest_log(folder, stream)
41
- if not path.exists():
42
- continue
43
- if self.paths.setdefault(stream, path) != path:
44
- self.paths[stream] = path
45
- self.offsets[stream] = 0
46
- with path.open("rb") as log:
47
- log.seek(self.offsets[stream])
48
- data = log.read()
49
- self.offsets[stream] += len(data)
50
- text = self.decoders[stream].decode(data)
51
- if not text:
52
- continue
53
- # A stream's unfinished line is redrawn as it grows, but the
54
- # other stream's output starts below it.
55
- if self.mid_line and stream == self.last_stream:
56
- self.drop_unfinished()
57
- text = self.unfinished + text
58
- *complete, self.unfinished = text.split("\n")
59
- if complete:
60
- self.write(Text.from_ansi("\n".join(complete)))
61
- if self.unfinished:
62
- self.write(Text.from_ansi(self.unfinished))
63
- self.last_stream = stream
64
-
65
- # Counted here, not in follow: writes made before the size is known
66
- # render later, from on_resize.
67
- def write(self, content: object, *args: Any, **kwargs: Any) -> Self:
68
- rows = len(self.lines)
69
- super().write(content, *args, **kwargs)
70
- self.written_rows = len(self.lines) - rows
71
- return self
72
-
73
- def drop_unfinished(self) -> None:
74
- if not self._size_known:
75
- self._deferred_renders.pop()
76
- return
77
- del self.lines[-self.written_rows :]
78
- self._line_cache.clear()
79
- self.virtual_size = Size(self.virtual_size.width, len(self.lines))
80
- self.refresh()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes