labnotes 0.2.20__tar.gz → 0.2.22__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 (235) hide show
  1. {labnotes-0.2.20 → labnotes-0.2.22}/PKG-INFO +1 -1
  2. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/run_output.py +57 -15
  3. {labnotes-0.2.20 → labnotes-0.2.22}/testing-conventions.toml +8 -2
  4. {labnotes-0.2.20 → labnotes-0.2.22}/.gitignore +0 -0
  5. {labnotes-0.2.20 → labnotes-0.2.22}/CHANGELOG.md +0 -0
  6. {labnotes-0.2.20 → labnotes-0.2.22}/MIGRATIONS.md +0 -0
  7. {labnotes-0.2.20 → labnotes-0.2.22}/README.md +0 -0
  8. {labnotes-0.2.20 → labnotes-0.2.22}/conftest.py +0 -0
  9. {labnotes-0.2.20 → labnotes-0.2.22}/pyproject.toml +0 -0
  10. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/__init__.py +0 -0
  11. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/__main__.py +0 -0
  12. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/asset_url.py +0 -0
  13. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/check_counts.py +0 -0
  14. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/cli.py +0 -0
  15. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/command_line_group.py +0 -0
  16. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/compose_experiment.py +0 -0
  17. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/config_migration.py +0 -0
  18. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/context.md +0 -0
  19. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/context_guide.py +0 -0
  20. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/copy_experiment.py +0 -0
  21. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/count_groups.py +0 -0
  22. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/count_runs.py +0 -0
  23. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/create_app.py +0 -0
  24. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/create_experiment.py +0 -0
  25. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/create_note.py +0 -0
  26. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/daemon/__init__.py +0 -0
  27. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/daemon/client.py +0 -0
  28. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/daemon/command.py +0 -0
  29. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/daemon/ensure.py +0 -0
  30. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/daemon/marker.py +0 -0
  31. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/daemon/server.py +0 -0
  32. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/daemon/socket_path.py +0 -0
  33. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/daemon_command.py +0 -0
  34. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/data_html.py +0 -0
  35. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/default_config_text.py +0 -0
  36. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/default_counts.py +0 -0
  37. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/drain_watch.py +0 -0
  38. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/experiment_definition.py +0 -0
  39. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/experiment_notes.py +0 -0
  40. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/experiment_runs.py +0 -0
  41. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/experiments.py +0 -0
  42. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/file_changes.py +0 -0
  43. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/format_duration.py +0 -0
  44. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/format_started.py +0 -0
  45. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/format_value.py +0 -0
  46. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/get_state.py +0 -0
  47. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/grid_cell.py +0 -0
  48. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/group_runs.py +0 -0
  49. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/init.py +0 -0
  50. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/invocation_started.py +0 -0
  51. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/is_non_negative_int.py +0 -0
  52. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/is_non_negative_number.py +0 -0
  53. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/is_positive_int.py +0 -0
  54. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/latest_log.py +0 -0
  55. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/list_experiments.py +0 -0
  56. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/list_runs.py +0 -0
  57. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/load_config.py +0 -0
  58. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/load_experiment.py +0 -0
  59. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/load_run.py +0 -0
  60. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/log.py +0 -0
  61. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/log_path.py +0 -0
  62. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/memory_interval.py +0 -0
  63. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/models.py +0 -0
  64. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/nests_runs.py +0 -0
  65. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/note_path.py +0 -0
  66. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/notebook_kernel.py +0 -0
  67. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/output_html.py +0 -0
  68. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/param_names.py +0 -0
  69. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/parse_param_value.py +0 -0
  70. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/parse_params.py +0 -0
  71. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/parse_run_view.py +0 -0
  72. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/parse_subset.py +0 -0
  73. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/pivot_runs.py +0 -0
  74. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/print_rows.py +0 -0
  75. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/python_blocks.py +0 -0
  76. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/read_config.py +0 -0
  77. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/read_path.py +0 -0
  78. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/render_markdown.py +0 -0
  79. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/retries.py +0 -0
  80. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/run_columns.py +0 -0
  81. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/run_output.py +0 -0
  82. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/__init__.py +0 -0
  83. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/cgroup_memory.py +0 -0
  84. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/check_args.py +0 -0
  85. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/check_hook_placeholders.py +0 -0
  86. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/check_subset.py +0 -0
  87. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/claim_run.py +0 -0
  88. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/command_flags.py +0 -0
  89. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/container_cgroup.py +0 -0
  90. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/container_memory.py +0 -0
  91. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/continue_run.py +0 -0
  92. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/describe_event.py +0 -0
  93. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/docker_output.py +0 -0
  94. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/execute_run.py +0 -0
  95. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/exit_signal.py +0 -0
  96. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/fill_dirs.py +0 -0
  97. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/fill_experiment_env.py +0 -0
  98. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/finalize_lost_runs.py +0 -0
  99. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/first_invocation.py +0 -0
  100. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/flag_name.py +0 -0
  101. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/group_args.py +0 -0
  102. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/hold_experiment.py +0 -0
  103. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/in_subset.py +0 -0
  104. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/invocation_hook.py +0 -0
  105. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/invocation_meta.py +0 -0
  106. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/new_run_id.py +0 -0
  107. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/new_stamped_run_id.py +0 -0
  108. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/override_flags.py +0 -0
  109. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/param_args.py +0 -0
  110. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/param_grid.py +0 -0
  111. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/placeholders.py +0 -0
  112. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/plan_runs.py +0 -0
  113. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/prepare_experiment.py +0 -0
  114. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/project_snapshot.py +0 -0
  115. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/read_experiment_config.py +0 -0
  116. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/record_memory.py +0 -0
  117. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/run_experiment.py +0 -0
  118. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/run_folder.py +0 -0
  119. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/run_git.py +0 -0
  120. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/run_headless.py +0 -0
  121. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/run_locked.py +0 -0
  122. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/run_state.py +0 -0
  123. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/runs_parent.py +0 -0
  124. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/shell_command.py +0 -0
  125. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/signal_tree.py +0 -0
  126. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/start_experiment.py +0 -0
  127. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/stop_then_kill.py +0 -0
  128. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/untracked_diff.py +0 -0
  129. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/wait_for_tree.py +0 -0
  130. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runner/write_run_json.py +0 -0
  131. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/runs_view_command.py +0 -0
  132. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/save_conflict_copy.py +0 -0
  133. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/save_note.py +0 -0
  134. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/saved_outputs.py +0 -0
  135. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/serve_app.py +0 -0
  136. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/server.py +0 -0
  137. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/set_state.py +0 -0
  138. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/shared_params.py +0 -0
  139. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/sort_href.py +0 -0
  140. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/sql_quote.py +0 -0
  141. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/state_path.py +0 -0
  142. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/static/elapsed.js +0 -0
  143. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/static/experiment.js +0 -0
  144. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/static/labnotes.css +0 -0
  145. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/static/local-time.js +0 -0
  146. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/static/new-note.js +0 -0
  147. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/static/note-edit.js +0 -0
  148. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/static/note-editor.js +0 -0
  149. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/static/row-link.js +0 -0
  150. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/static/run-cell.js +0 -0
  151. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/static/run-output.js +0 -0
  152. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/static/view-toggle.js +0 -0
  153. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/summarize_config.py +0 -0
  154. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/__init__.py +0 -0
  155. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/experiment_rows.py +0 -0
  156. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/experiment_run_ids.py +0 -0
  157. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/experiment_toml.py +0 -0
  158. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/experiments_ddl.py +0 -0
  159. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/file_prefix.py +0 -0
  160. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/file_text.py +0 -0
  161. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/iso_time.py +0 -0
  162. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/list_experiment_runs.py +0 -0
  163. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/list_resumable_runs.py +0 -0
  164. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/note_text.py +0 -0
  165. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/open_tables.py +0 -0
  166. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/path_glob.py +0 -0
  167. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/path_pattern.py +0 -0
  168. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/read_blocks.py +0 -0
  169. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/read_experiment.py +0 -0
  170. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/read_file.py +0 -0
  171. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/read_log.py +0 -0
  172. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/read_memory.py +0 -0
  173. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/read_run.py +0 -0
  174. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/read_run_file.py +0 -0
  175. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/runs_columns.py +0 -0
  176. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tables/summarize_experiments.py +0 -0
  177. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/templates/base.html +0 -0
  178. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/templates/editor_imports.html +0 -0
  179. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/templates/experiment.html +0 -0
  180. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/templates/index.html +0 -0
  181. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/templates/note.html +0 -0
  182. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/templates/run.html +0 -0
  183. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/__init__.py +0 -0
  184. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/browse_app.py +0 -0
  185. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/browse_tui.py +0 -0
  186. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/check_view_response.py +0 -0
  187. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/config.py +0 -0
  188. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/dim.py +0 -0
  189. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/experiment_screen.py +0 -0
  190. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/experiments_screen.py +0 -0
  191. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/fill_table.py +0 -0
  192. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/format_cell.py +0 -0
  193. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/format_elapsed.py +0 -0
  194. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/guard_view.py +0 -0
  195. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/leave_prompt.py +0 -0
  196. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/load_view.py +0 -0
  197. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/log_block.py +0 -0
  198. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/log_blocks.py +0 -0
  199. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/native_rows.py +0 -0
  200. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/reload_on_change.py +0 -0
  201. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/run_app.py +0 -0
  202. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/run_cells.py +0 -0
  203. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/run_panel.py +0 -0
  204. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/run_tui.py +0 -0
  205. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/runs_browser.py +0 -0
  206. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/runs_table.py +0 -0
  207. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/runs_view.py +0 -0
  208. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/stopped_title.py +0 -0
  209. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/table_columns.py +0 -0
  210. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/table_rows.py +0 -0
  211. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/view_column.py +0 -0
  212. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/view_pane.py +0 -0
  213. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/view_process.py +0 -0
  214. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/tui/view_switcher.py +0 -0
  215. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/utils/__init__.py +0 -0
  216. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/utils/format_bytes.py +0 -0
  217. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/utils/process_alive.py +0 -0
  218. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/utils/run_usage.py +0 -0
  219. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/utils/tree_rss.py +0 -0
  220. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/utils/tree_usage.py +0 -0
  221. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/view/__init__.py +0 -0
  222. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/view/answer.py +0 -0
  223. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/view/build.py +0 -0
  224. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/view/changed.py +0 -0
  225. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/view/experiment.py +0 -0
  226. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/view/respond.py +0 -0
  227. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/view/serve.py +0 -0
  228. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/view_specs.py +0 -0
  229. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/wait_for_note.py +0 -0
  230. {labnotes-0.2.20 → labnotes-0.2.22}/src/labnotes/watch_rows.py +0 -0
  231. {labnotes-0.2.20 → labnotes-0.2.22}/tests/conftest.py +0 -0
  232. {labnotes-0.2.20 → labnotes-0.2.22}/tests/e2e/conftest.py +0 -0
  233. {labnotes-0.2.20 → labnotes-0.2.22}/tests/integration/conftest.py +0 -0
  234. {labnotes-0.2.20 → labnotes-0.2.22}/tests/perf/conftest.py +0 -0
  235. {labnotes-0.2.20 → labnotes-0.2.22}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: labnotes
3
- Version: 0.2.20
3
+ Version: 0.2.22
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>
@@ -3,23 +3,50 @@ from collections.abc import Iterable
3
3
  from pathlib import Path
4
4
  from typing import Self
5
5
 
6
- from rich.style import Style
6
+ from rich.ansi import re_ansi
7
7
  from rich.text import Text
8
8
  from rich.cells import cell_len
9
9
  from textual.geometry import Size
10
+ from textual.scroll_view import ScrollView
10
11
  from textual.strip import Strip
11
- from textual.widgets import Log
12
12
 
13
13
  from labnotes.latest_log import latest_log
14
14
 
15
15
  STREAMS = ("stdout", "stderr")
16
16
 
17
17
 
18
- class RunOutput(Log):
18
+ class RunOutput(ScrollView):
19
+ DEFAULT_CSS = """
20
+ RunOutput {
21
+ background: $surface;
22
+ color: $text;
23
+ overflow: scroll;
24
+ &:focus { background-tint: $foreground 5%; }
25
+ }
26
+ """
27
+
19
28
  def __init__(self, id: str | None = None) -> None:
20
29
  super().__init__(id=id)
30
+ self.auto_scroll = True
31
+ self._lines: list[str] = []
32
+ self._line_widths: list[int] = []
33
+ self._line_cache: dict[int, Strip] = {}
34
+ self._width = 0
21
35
  self.reset()
22
36
 
37
+ @property
38
+ def lines(self) -> list[str]:
39
+ return self._lines
40
+
41
+ def clear(self) -> Self:
42
+ self._lines.clear()
43
+ self._line_widths.clear()
44
+ self._line_cache.clear()
45
+ self._width = 0
46
+ self.virtual_size = Size(0, 0)
47
+ self.refresh()
48
+ return self
49
+
23
50
  def reset(self) -> None:
24
51
  self.offsets = dict.fromkeys(STREAMS, 0)
25
52
  self.paths: dict[str, Path] = {}
@@ -68,7 +95,11 @@ class RunOutput(Log):
68
95
  return self
69
96
  at_end = self.is_vertical_scroll_end
70
97
  self._lines.extend(new_lines)
71
- self._width = max(self._width, max(map(len, new_lines)))
98
+ widths = [
99
+ cell_len(re_ansi.sub("", line.rsplit("\r", 1)[-1])) for line in new_lines
100
+ ]
101
+ self._line_widths.extend(widths)
102
+ self._width = max(self._width, *widths)
72
103
  self.virtual_size = Size(self._width, len(self._lines))
73
104
  self.refresh()
74
105
  if (
@@ -81,17 +112,26 @@ class RunOutput(Log):
81
112
 
82
113
  def drop_unfinished(self) -> None:
83
114
  self._lines.pop()
84
- self._render_line_cache.discard(len(self._lines))
115
+ removed_width = self._line_widths.pop()
116
+ if removed_width == self._width:
117
+ self._width = max(self._line_widths, default=0)
118
+ self._line_cache.pop(len(self._lines), None)
85
119
  self.virtual_size = Size(self._width, len(self._lines))
86
120
  self.refresh()
87
121
 
88
- def _render_line_strip(self, y: int, rich_style: Style) -> Strip:
122
+ def render_line(self, y: int) -> Strip:
123
+ """Render only the visible line, keeping the uncropped result cached."""
124
+ scroll_x, scroll_y = self.scroll_offset
125
+ row = scroll_y + y
126
+ rich_style = self.rich_style
127
+ if row >= len(self._lines):
128
+ return Strip.blank(self.size.width, rich_style)
89
129
  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:
130
+ if selection is None and row in self._line_cache:
131
+ line = self._line_cache[row]
132
+ else:
133
+ line_text = Text.from_ansi(self._lines[row], style=rich_style)
134
+ if selection is not None and (span := selection.get_span(row)) is not None:
95
135
  start, end = span
96
136
  if end == -1:
97
137
  end = len(line_text)
@@ -100,7 +140,9 @@ class RunOutput(Log):
100
140
  start,
101
141
  end,
102
142
  )
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
143
+ line = Strip(line_text.render(self.app.console), cell_len(line_text.plain))
144
+ if selection is None:
145
+ self._line_cache[row] = line
146
+ return line.crop_extend(
147
+ scroll_x, scroll_x + self.size.width, rich_style
148
+ ).apply_offsets(scroll_x, row)
@@ -1,7 +1,7 @@
1
1
  [[python.exempt]]
2
2
  path = "src/labnotes/tui/run_output.py"
3
3
  rules = ["mutation"]
4
- lines = [44]
4
+ lines = [82]
5
5
  reason = "last_stream is always the same str object taken from STREAMS, so is equals =="
6
6
 
7
7
  [[python.exempt]]
@@ -55,9 +55,15 @@ reason = "LOCK_EX and LOCK_NB are disjoint bits, so | equals + and ^"
55
55
  [[python.exempt]]
56
56
  path = "src/labnotes/tui/run_output.py"
57
57
  rules = ["mutation"]
58
- lines = [96]
58
+ lines = [136]
59
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 =="
60
60
 
61
+ [[python.exempt]]
62
+ path = "src/labnotes/tui/run_output.py"
63
+ rules = ["mutation"]
64
+ lines = [34, 99, 116]
65
+ reason = "reset() clears _width right after __init__ sets it; rsplit()[-1] is the text after the last \\r for any maxsplit of 1 or more; no line is wider than _width, so >= equals == and <= only adds rescans that find the same max; when is fails, another line holds the same max"
66
+
61
67
  [[python.exempt]]
62
68
  path = "src/labnotes/daemon/client.py"
63
69
  rules = ["mutation"]
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
File without changes