From c75c1ea27c7db5209db4626a72ae26f59db1b732 Mon Sep 17 00:00:00 2001 From: Dmitri Kuznetsov Date: Sun, 14 Jun 2026 18:37:04 +0300 Subject: [PATCH 1/9] fix(ci): small changes to workflow --- .github/workflows/deploy-docs.yml | 2 +- pyproject.toml | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 9480bbde..67ec73b4 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -41,7 +41,7 @@ jobs: - name: Install dependencies with Poetry run: | - poetry install --with dev + poetry install --with docs - name: Fetch gh-pages branch run: | diff --git a/pyproject.toml b/pyproject.toml index 5f7bea13..2077aa58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,14 @@ psycopg2 = "2.9.12" pysatl-criterion = { version = "*", source = "testpypi", allow-prereleases = true } psutil = "^7.1.1" +[tool.poetry.group.docs.dependencies] +markdown = "3.10.2" +mkdocs = "1.6.1" +mkdocs-material = "9.7.6" +mdx-truly-sane-lists = "1.3" +pymdown-extensions = "10.21.3" +mike = "2.2.0" + [tool.poetry.group.dev.dependencies] markdown = "3.10.2" mkdocs = "1.6.1" From 26161f10be66b11a046e55eb3cfca22ca59834e3 Mon Sep 17 00:00:00 2001 From: Dmitri Kuznetsov Date: Sun, 14 Jun 2026 18:41:13 +0300 Subject: [PATCH 2/9] style(ci): formatting --- .github/workflows/ci.yaml | 2 +- .github/workflows/deploy-docs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 2e0c0833..3c781f83 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,7 +7,7 @@ on: pull_request: branches: - main - types: [opened, synchronize, reopened, closed, review_requested] + types: [ opened, synchronize, reopened, closed, review_requested ] jobs: build-linux: diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 67ec73b4..ea926349 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -9,7 +9,7 @@ on: - main types: [ opened, synchronize, reopened, closed, review_requested ] release: - types: [published] + types: [ published ] # disable permissions for all of the available permissions From ad18796dcaeda8d3fb86bf8fbe285b6635a8f5bf Mon Sep 17 00:00:00 2001 From: Dmitri Kuznetsov Date: Sun, 14 Jun 2026 18:41:58 +0300 Subject: [PATCH 3/9] style(ci): formatting --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3c781f83..17a118c9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12"] + python-version: [ "3.10", "3.11", "3.12" ] steps: - name: Checkout repository From 75516caaa7b484ebc5f56595a91f117e82a637cd Mon Sep 17 00:00:00 2001 From: Dmitri Kuznetsov Date: Sun, 14 Jun 2026 18:44:32 +0300 Subject: [PATCH 4/9] chore: removed unused misc.py --- src/pysatl_experiment/misc.py | 40 ----------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 src/pysatl_experiment/misc.py diff --git a/src/pysatl_experiment/misc.py b/src/pysatl_experiment/misc.py deleted file mode 100644 index 05d6d5a0..00000000 --- a/src/pysatl_experiment/misc.py +++ /dev/null @@ -1,40 +0,0 @@ -"""Core utilities for PySatl experiment system.""" - - -def deep_merge_dicts(source, destination, allow_null_overrides: bool = True): - """ - Deep merge two dictionaries in-place. - - Parameters - ---------- - source : dict - Source dictionary whose values override destination. - destination : dict - Target dictionary modified in-place. - allow_null_overrides : bool, optional - If True, None values from source override destination values. - - Returns - ------- - dict - Merged destination dictionary. - - Sample - ------ - >>> a = { 'first' : { 'rows' : { 'pass' : 'dog', 'number' : '1' } } } - >>> b = { 'first' : { 'rows' : { 'fail' : 'cat', 'number' : '5' } } } - >>> merge(b, a) == { 'first' : { 'rows' : { 'pass' : 'dog', 'fail' : 'cat', 'number' : '5' } } } - - Notes - ----- - Values from Source override destination, destination is returned (and modified!!). - """ - for key, value in source.items(): - if isinstance(value, dict): - # get node or create one - node = destination.setdefault(key, {}) - deep_merge_dicts(value, node, allow_null_overrides) - elif value is not None or allow_null_overrides: - destination[key] = value - - return destination From e3b07655a60da45e8ff12e9ad4356e409ad55570 Mon Sep 17 00:00:00 2001 From: Dmitri Kuznetsov Date: Sun, 14 Jun 2026 18:58:33 +0300 Subject: [PATCH 5/9] fix(tests): added coverage configuration --- pyproject.toml | 11 ++++++++ tests/test_main.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 tests/test_main.py diff --git a/pyproject.toml b/pyproject.toml index 2077aa58..f8a694ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -115,6 +115,17 @@ enable = true vcs = "git" style = "pep440" +[tool.coverage.run] +source = ["pysatl_experiment"] +omit = [ + "*/__main__.py", +] + +[tool.coverage.report] +exclude_lines = [ + "if __name__ == .__main__.:", +] + # Format for NON tagged commits format-jinja = """ {%- if distance == 0 -%} diff --git a/tests/test_main.py b/tests/test_main.py new file mode 100644 index 00000000..33583216 --- /dev/null +++ b/tests/test_main.py @@ -0,0 +1,62 @@ +"""Tests for CLI entrypoint module.""" + +import subprocess +import sys + +import pytest +from click.testing import CliRunner + +from pysatl_experiment.cli.cli import cli + + +class TestCliEntrypoint: + """Basic tests for CLI entrypoint.""" + + @pytest.fixture + def runner(self): + """Create a Click CLI runner for testing.""" + return CliRunner() + + def test_cli_imports_successfully(self): + """Test that cli object can be imported.""" + from pysatl_experiment.cli.cli import cli + + assert cli is not None + assert callable(cli) + + def test_cli_help_works(self, runner): + """Test that main CLI shows help.""" + result = runner.invoke(cli, ["--help"]) + assert result.exit_code == 0 + assert "Usage:" in result.output + assert "Commands:" in result.output + + def test_python_m_execution(self): + """Test that `python -m pysatl_experiment.cli` works.""" + result = subprocess.run( + [sys.executable, "-m", "pysatl_experiment.cli", "--help"], + capture_output=True, + text=True, + timeout=10, + ) + assert result.returncode == 0 + assert "Usage:" in result.stdout or "Commands:" in result.stdout + + def test_entrypoint_docstring(self): + """Test that entrypoint module has documentation.""" + import pysatl_experiment.cli.__main__ as entrypoint + + assert entrypoint.__doc__ is not None + assert len(entrypoint.__doc__) > 0 + + def test_cli_handles_no_command(self, runner): + """Test CLI shows help when no command is given.""" + result = runner.invoke(cli, []) + assert result.exit_code == 0 + # Click should show help or available commands + assert len(result.output) > 0 + + def test_cli_handles_invalid_command(self, runner): + """Test CLI handles invalid commands gracefully.""" + result = runner.invoke(cli, ["nonexistent-command-xyz"]) + assert result.exit_code != 0 From 4bb7345b827afc25126d42cc60aa7b2591babb9f Mon Sep 17 00:00:00 2001 From: Dmitri Kuznetsov Date: Sun, 14 Jun 2026 19:07:57 +0300 Subject: [PATCH 6/9] chore(tests): removed unused --- pyproject.toml | 5 ---- tests/test_main.py | 62 ---------------------------------------------- 2 files changed, 67 deletions(-) delete mode 100644 tests/test_main.py diff --git a/pyproject.toml b/pyproject.toml index f8a694ec..7f1c57b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -121,11 +121,6 @@ omit = [ "*/__main__.py", ] -[tool.coverage.report] -exclude_lines = [ - "if __name__ == .__main__.:", -] - # Format for NON tagged commits format-jinja = """ {%- if distance == 0 -%} diff --git a/tests/test_main.py b/tests/test_main.py deleted file mode 100644 index 33583216..00000000 --- a/tests/test_main.py +++ /dev/null @@ -1,62 +0,0 @@ -"""Tests for CLI entrypoint module.""" - -import subprocess -import sys - -import pytest -from click.testing import CliRunner - -from pysatl_experiment.cli.cli import cli - - -class TestCliEntrypoint: - """Basic tests for CLI entrypoint.""" - - @pytest.fixture - def runner(self): - """Create a Click CLI runner for testing.""" - return CliRunner() - - def test_cli_imports_successfully(self): - """Test that cli object can be imported.""" - from pysatl_experiment.cli.cli import cli - - assert cli is not None - assert callable(cli) - - def test_cli_help_works(self, runner): - """Test that main CLI shows help.""" - result = runner.invoke(cli, ["--help"]) - assert result.exit_code == 0 - assert "Usage:" in result.output - assert "Commands:" in result.output - - def test_python_m_execution(self): - """Test that `python -m pysatl_experiment.cli` works.""" - result = subprocess.run( - [sys.executable, "-m", "pysatl_experiment.cli", "--help"], - capture_output=True, - text=True, - timeout=10, - ) - assert result.returncode == 0 - assert "Usage:" in result.stdout or "Commands:" in result.stdout - - def test_entrypoint_docstring(self): - """Test that entrypoint module has documentation.""" - import pysatl_experiment.cli.__main__ as entrypoint - - assert entrypoint.__doc__ is not None - assert len(entrypoint.__doc__) > 0 - - def test_cli_handles_no_command(self, runner): - """Test CLI shows help when no command is given.""" - result = runner.invoke(cli, []) - assert result.exit_code == 0 - # Click should show help or available commands - assert len(result.output) > 0 - - def test_cli_handles_invalid_command(self, runner): - """Test CLI handles invalid commands gracefully.""" - result = runner.invoke(cli, ["nonexistent-command-xyz"]) - assert result.exit_code != 0 From d63f0787e0651c21f4f76a570d337b3532b448f1 Mon Sep 17 00:00:00 2001 From: Dmitri Kuznetsov Date: Sun, 14 Jun 2026 19:14:24 +0300 Subject: [PATCH 7/9] fix(tests): .coveragerc --- .coveragerc | 1 + 1 file changed, 1 insertion(+) diff --git a/.coveragerc b/.coveragerc index a7cba45f..9d607ce9 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,3 +1,4 @@ [run] omit = tests/* + src/pysatl_experiment/__main__.py From 6ded9ab6be6a68a0ba23a09caa2c273d5a4cb7a3 Mon Sep 17 00:00:00 2001 From: Dmitri Kuznetsov Date: Sun, 14 Jun 2026 19:36:40 +0300 Subject: [PATCH 8/9] chore(docs): removed unused requirements-docs.txt --- docs/requirements-docs.txt | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 docs/requirements-docs.txt diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt deleted file mode 100644 index 9236e853..00000000 --- a/docs/requirements-docs.txt +++ /dev/null @@ -1,7 +0,0 @@ -markdown==3.10.2 -mkdocs==1.6.1 -mkdocs-material==9.7.6 -mdx_truly_sane_lists==1.3 -pymdown-extensions==10.21.3 -jinja2==3.1.6 -mike==2.2.0 From 00cb0594cbcddf0bd6d78c3b34e56750be6e6c9a Mon Sep 17 00:00:00 2001 From: Dmitri Kuznetsov Date: Sat, 27 Jun 2026 17:13:20 +0300 Subject: [PATCH 9/9] chore: added TODO for loggers --- src/pysatl_experiment/loggers/buffering_handler.py | 3 +++ src/pysatl_experiment/loggers/json_formatter.py | 1 + src/pysatl_experiment/loggers/rich_handler.py | 3 +++ src/pysatl_experiment/loggers/std_err_stream_handler.py | 1 + 4 files changed, 8 insertions(+) diff --git a/src/pysatl_experiment/loggers/buffering_handler.py b/src/pysatl_experiment/loggers/buffering_handler.py index 7fb20014..68a4a935 100644 --- a/src/pysatl_experiment/loggers/buffering_handler.py +++ b/src/pysatl_experiment/loggers/buffering_handler.py @@ -51,3 +51,6 @@ def flush(self): self.buffer = self.buffer[records_to_keep:] # TODO: replace with queue/circular buffer?? finally: self.release() + + +# TODO: currently not used anywhere diff --git a/src/pysatl_experiment/loggers/json_formatter.py b/src/pysatl_experiment/loggers/json_formatter.py index e4df8871..300438ee 100644 --- a/src/pysatl_experiment/loggers/json_formatter.py +++ b/src/pysatl_experiment/loggers/json_formatter.py @@ -19,6 +19,7 @@ # TODO: replace loosely typed dictionaries with a dedicated TypedDict schema for formatter configuration? +# TODO: currently not used anywhere class JsonFormatter(logging.Formatter): diff --git a/src/pysatl_experiment/loggers/rich_handler.py b/src/pysatl_experiment/loggers/rich_handler.py index 18e48467..2a62e2f3 100644 --- a/src/pysatl_experiment/loggers/rich_handler.py +++ b/src/pysatl_experiment/loggers/rich_handler.py @@ -24,6 +24,9 @@ from rich.text import Text +# TODO: currently not used anywhere + + class FtRichHandler(Handler): """ Custom Rich-based logging handler for colorized console output. diff --git a/src/pysatl_experiment/loggers/std_err_stream_handler.py b/src/pysatl_experiment/loggers/std_err_stream_handler.py index 6eff028e..152ac7ba 100644 --- a/src/pysatl_experiment/loggers/std_err_stream_handler.py +++ b/src/pysatl_experiment/loggers/std_err_stream_handler.py @@ -91,3 +91,4 @@ def emit(self, record): # TODO: is this handler needed at all instead of StreamHandler? if so, check for tests +# TODO: currently not used anywhere