labnotes 0.2.33__tar.gz → 0.2.35__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.
- {labnotes-0.2.33 → labnotes-0.2.35}/PKG-INFO +1 -1
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/execute_run.py +5 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/read_experiment_config.py +7 -0
- labnotes-0.2.35/src/labnotes/runner/stop_containers.py +17 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/tests/conftest.py +33 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/.gitignore +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/CHANGELOG.md +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/MIGRATIONS.md +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/README.md +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/conftest.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/pyproject.toml +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/__init__.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/__main__.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/asset_url.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/check_counts.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/cli.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/command_line_group.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/compose_experiment.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/config_migration.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/context.md +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/context_guide.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/copy_experiment.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/count_groups.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/count_runs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/create_app.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/create_experiment.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/create_note.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/daemon/__init__.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/daemon/client.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/daemon/command.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/daemon/ensure.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/daemon/marker.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/daemon/server.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/daemon/socket_path.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/daemon_command.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/data_html.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/default_config_text.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/default_counts.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/drain_watch.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/experiment_definition.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/experiment_notes.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/experiment_runs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/experiments.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/file_changes.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/format_duration.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/format_started.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/format_value.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/get_state.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/grid_cell.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/group_runs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/init.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/invocation_started.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/is_non_negative_int.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/is_non_negative_number.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/is_positive_int.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/latest_log.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/list_experiments.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/list_runs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/load_config.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/load_experiment.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/load_run.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/log.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/log_path.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/memory_interval.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/models.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/nests_runs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/note_path.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/notebook_kernel.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/output_html.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/param_names.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/parse_param_value.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/parse_params.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/parse_run_view.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/parse_subset.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/pivot_runs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/print_rows.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/python_blocks.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/read_config.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/read_path.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/render_markdown.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/retries.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/run_columns.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/run_output.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/__init__.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/cgroup_memory.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/check_args.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/check_hook_placeholders.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/check_subset.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/claim_run.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/command_flags.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/container_cgroup.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/container_memory.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/continue_run.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/describe_event.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/docker_output.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/exit_signal.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/fill_dirs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/fill_experiment_env.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/finalize_lost_runs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/first_invocation.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/flag_name.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/group_args.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/hold_experiment.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/in_subset.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/invocation_hook.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/invocation_meta.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/mark_lost.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/new_run_id.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/new_stamped_run_id.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/override_flags.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/param_args.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/param_grid.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/placeholders.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/plan_runs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/prepare_experiment.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/project_snapshot.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/record_memory.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/run_experiment.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/run_folder.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/run_git.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/run_headless.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/run_locked.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/run_state.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/runs_parent.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/shell_command.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/signal_tree.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/start_experiment.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/stop_then_kill.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/untracked_diff.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/wait_for_tree.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runner/write_run_json.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/runs_view_command.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/save_conflict_copy.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/save_note.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/saved_outputs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/serve_app.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/server.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/set_state.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/shared_params.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/sort_href.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/sql_quote.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/state_path.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/elapsed.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/experiment.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/labnotes.css +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/local-time.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/new-note.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/note-edit.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/note-editor.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/row-link.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/run-cell.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/run-output.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/THIRD_PARTY_NOTICES +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/ansi_up.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/atomic-editor-editor-inline-preview.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-3VL5A6CI.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-DDFT2RE5.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-GRK3PUFM.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-HETKD2IB.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-JSBRDJBE.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-KGFOUVBD.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-LAFDP4SS.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-LFGFNL4F.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-LRGARZ6Y.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-LZVVMIXK.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-SVHN5VMN.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-YFJJZMCS.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-YONOI2RA.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/chunk-ZO3BUX3P.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/codemirror-autocomplete.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/codemirror-commands.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/codemirror-lang-python.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/codemirror-language.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/codemirror-state.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/codemirror-streamparser.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/codemirror-view.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/crelt.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/diff-match-patch.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/lezer-common.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/lezer-highlight.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/lezer-lr.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/lezer-markdown.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/lezer-python.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/marijn-find-cluster-break.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/style-mod.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/vendor/w3c-keyname.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/static/view-toggle.js +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/summarize_config.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/__init__.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/experiment_rows.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/experiment_run_ids.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/experiment_toml.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/experiments_ddl.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/file_prefix.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/file_text.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/iso_time.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/list_experiment_runs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/list_resumable_runs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/note_text.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/open_tables.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/path_glob.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/path_pattern.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/read_blocks.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/read_experiment.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/read_file.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/read_log.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/read_memory.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/read_run.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/read_run_file.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/runs_columns.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tables/summarize_experiments.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/templates/base.html +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/templates/editor_imports.html +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/templates/experiment.html +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/templates/index.html +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/templates/note.html +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/templates/run.html +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/__init__.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/browse_app.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/browse_tui.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/check_view_response.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/config.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/dim.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/experiment_screen.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/experiments_screen.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/fill_table.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/format_cell.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/format_elapsed.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/guard_view.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/leave_prompt.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/load_view.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/log_block.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/log_blocks.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/native_rows.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/reload_on_change.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/run_app.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/run_cells.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/run_output.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/run_panel.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/run_tui.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/runs_browser.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/runs_table.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/runs_view.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/stopped_title.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/table_columns.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/table_rows.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/view_column.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/view_pane.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/view_process.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/tui/view_switcher.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/utils/__init__.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/utils/format_bytes.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/utils/process_alive.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/utils/run_usage.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/utils/tree_rss.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/utils/tree_usage.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/view/__init__.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/view/answer.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/view/build.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/view/changed.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/view/experiment.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/view/respond.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/view/serve.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/view_specs.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/wait_for_note.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/src/labnotes/watch_rows.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/testing-conventions.toml +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/tests/e2e/conftest.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/tests/integration/conftest.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/tests/perf/conftest.py +0 -0
- {labnotes-0.2.33 → labnotes-0.2.35}/uv.lock +0 -0
|
@@ -16,6 +16,7 @@ from labnotes.runner.exit_signal import exit_signal
|
|
|
16
16
|
from labnotes.runner.record_memory import record_memory
|
|
17
17
|
from labnotes.runner.run_git import run_git
|
|
18
18
|
from labnotes.runner.shell_command import shell_command
|
|
19
|
+
from labnotes.runner.stop_containers import stop_containers
|
|
19
20
|
from labnotes.runner.stop_then_kill import GRACE_SECONDS
|
|
20
21
|
from labnotes.runner.wait_for_tree import wait_for_tree
|
|
21
22
|
from labnotes.runner.write_run_json import write_run_json
|
|
@@ -146,6 +147,8 @@ async def execute_run(
|
|
|
146
147
|
GRACE_SECONDS, stop
|
|
147
148
|
)
|
|
148
149
|
run["exit_code"] = code = await exited
|
|
150
|
+
if kill_later is not None:
|
|
151
|
+
kill_later.cancel()
|
|
149
152
|
run["signal"] = exit_signal(code)
|
|
150
153
|
if kill_later is not None:
|
|
151
154
|
run["ended_by"] = "timeout"
|
|
@@ -158,6 +161,8 @@ async def execute_run(
|
|
|
158
161
|
# is gone. A normal exit ends the run even if helpers linger.
|
|
159
162
|
if stopping.is_set() or kill_later is not None:
|
|
160
163
|
await wait_for_tree(tree)
|
|
164
|
+
if stopping.is_set() or kill_later is not None or stopped():
|
|
165
|
+
await asyncio.to_thread(stop_containers, str(folder.resolve()))
|
|
161
166
|
finally:
|
|
162
167
|
if kill_later is not None:
|
|
163
168
|
kill_later.cancel()
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import json
|
|
2
|
+
import re
|
|
2
3
|
import tomllib
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
from typing import Any
|
|
@@ -13,6 +14,7 @@ from labnotes.is_positive_int import is_positive_int
|
|
|
13
14
|
from labnotes.config_migration import MISSING_CONTINUES, REMOVED_MODE
|
|
14
15
|
from labnotes.retries import RETRY_SECONDS
|
|
15
16
|
|
|
17
|
+
SHELL_IDENTIFIER = re.compile(r"[A-Za-z_][A-Za-z0-9_]*\Z")
|
|
16
18
|
SETTINGS = {
|
|
17
19
|
"name",
|
|
18
20
|
"command",
|
|
@@ -103,6 +105,11 @@ def read_experiment_config(
|
|
|
103
105
|
for key, value in env.items():
|
|
104
106
|
if key.startswith("LABNOTES_"):
|
|
105
107
|
raise ValueError(f"{path}: env.{key} is reserved for labnotes")
|
|
108
|
+
if not SHELL_IDENTIFIER.match(key):
|
|
109
|
+
raise ValueError(
|
|
110
|
+
f"{path}: env.{key} must be a shell identifier"
|
|
111
|
+
" (letters, digits, underscore; not starting with a digit)"
|
|
112
|
+
)
|
|
106
113
|
if not isinstance(value, str):
|
|
107
114
|
raise ValueError(f"{path}: env.{key} must be a string")
|
|
108
115
|
if "continues" not in values:
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
|
|
3
|
+
from labnotes.runner.container_memory import LABEL
|
|
4
|
+
from labnotes.runner.docker_output import docker_output
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def stop_containers(run_id: str) -> None:
|
|
8
|
+
"""Stop Docker containers that outlive their run's host process tree."""
|
|
9
|
+
if shutil.which("docker") is None:
|
|
10
|
+
return
|
|
11
|
+
ids = docker_output(
|
|
12
|
+
"ps", "--quiet", "--no-trunc", "--filter", f"label={LABEL}={run_id}"
|
|
13
|
+
)
|
|
14
|
+
if ids is None:
|
|
15
|
+
return
|
|
16
|
+
for container_id in ids.splitlines():
|
|
17
|
+
docker_output("kill", container_id)
|
|
@@ -2,11 +2,44 @@ import shlex
|
|
|
2
2
|
import shutil
|
|
3
3
|
import subprocess
|
|
4
4
|
import sys
|
|
5
|
+
import os
|
|
5
6
|
from collections.abc import Iterator
|
|
6
7
|
from pathlib import Path
|
|
8
|
+
from unittest import mock
|
|
7
9
|
|
|
8
10
|
import pytest
|
|
9
11
|
|
|
12
|
+
|
|
13
|
+
@pytest.fixture
|
|
14
|
+
def fake_docker(tmp_path: Path) -> Iterator[dict[str, str]]:
|
|
15
|
+
"""A Docker CLI whose container survives when the client is signalled."""
|
|
16
|
+
binary = tmp_path / "fake-docker-bin"
|
|
17
|
+
binary.mkdir()
|
|
18
|
+
(binary / "docker").write_text(
|
|
19
|
+
"#!/usr/bin/env python3\n"
|
|
20
|
+
"import os, pathlib, sys, time\n"
|
|
21
|
+
"args = sys.argv[1:]\n"
|
|
22
|
+
"state = pathlib.Path(os.environ['FAKE_DOCKER_STATE'])\n"
|
|
23
|
+
"if args[0] == 'run':\n"
|
|
24
|
+
" label = args[args.index('--label') + 1]\n"
|
|
25
|
+
" state.write_text(label)\n"
|
|
26
|
+
" time.sleep(30)\n"
|
|
27
|
+
"elif args[0] == 'ps':\n"
|
|
28
|
+
" wanted = args[args.index('--filter') + 1][6:]\n"
|
|
29
|
+
" if state.exists() and state.read_text() == wanted: print('fake-container')\n"
|
|
30
|
+
"elif args[0] == 'kill':\n"
|
|
31
|
+
" if state.exists(): state.unlink()\n"
|
|
32
|
+
" print(args[1])\n"
|
|
33
|
+
)
|
|
34
|
+
(binary / "docker").chmod(0o755)
|
|
35
|
+
environment = {
|
|
36
|
+
"PATH": f"{binary}{os.pathsep}{os.environ['PATH']}",
|
|
37
|
+
"FAKE_DOCKER_STATE": str(tmp_path / "container.state"),
|
|
38
|
+
}
|
|
39
|
+
with mock.patch.dict(os.environ, environment):
|
|
40
|
+
yield environment
|
|
41
|
+
|
|
42
|
+
|
|
10
43
|
BOTBOX_CONTAINER = """
|
|
11
44
|
import os
|
|
12
45
|
import subprocess
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|