From bd262ccc2a120b8b8adc26893f187020fb84965b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Andreatta?= Date: Tue, 2 Jun 2026 14:12:16 +0200 Subject: [PATCH 1/3] [IMP] common: warn if odev repository path is inside playground folder - Add warning if resolved odev path is in or matches the home playground directory. - Add test case verifying the playground warning logic. --- odev/common/odev.py | 11 +++++++++++ tests/tests/common/test_odev.py | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/odev/common/odev.py b/odev/common/odev.py index de9940e2..f8b24c94 100644 --- a/odev/common/odev.py +++ b/odev/common/odev.py @@ -279,6 +279,17 @@ def start(self, start_time: float | None = None) -> None: self.plugins_path.mkdir(parents=True, exist_ok=True) + try: + playground_dir = (self.home_path / "playground").resolve() + resolved_path = self.path.resolve() + if resolved_path == playground_dir or playground_dir in resolved_path.parents: + logger.warning( + f"Odev repository is located inside the playground folder: {resolved_path}. " + "This is not recommended and can cause conflicts." + ) + except Exception: + pass + if self._should_update_now(): self.check_release() self.update() diff --git a/tests/tests/common/test_odev.py b/tests/tests/common/test_odev.py index 668d63c6..5330338f 100644 --- a/tests/tests/common/test_odev.py +++ b/tests/tests/common/test_odev.py @@ -181,3 +181,20 @@ def test_16_plugins_dependency_tree_cycle_raises(self): self.odev._plugins_dependency_tree() finally: shutil.rmtree(cycle_root, ignore_errors=True) + + def test_17_warning_if_in_playground(self): + """Odev should display a warning if the repository path is inside the playground directory.""" + mock_path = self.odev.home_path / "playground" / "my-odev-repo" + with ( + self.patch_property(type(self.odev), "path", mock_path), + self.patch(logger, "warning") as mock_warning, + self.patch(self.odev, "load_plugins"), + self.patch(self.odev, "register_commands"), + self.patch(self.odev, "register_plugin_commands"), + self.patch(self.odev, "prune_databases"), + ): + self.odev._started = False + self.odev.start() + mock_warning.assert_called_once() + self.assertIn("located inside the playground folder", mock_warning.call_args[0][0]) + From ff146287e6ae8845ad924713d9a2127331708d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Andreatta?= Date: Tue, 2 Jun 2026 15:05:51 +0200 Subject: [PATCH 2/3] [FIX] common: make config parser instance-specific to prevent test pollution --- odev/common/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/odev/common/config.py b/odev/common/config.py index 5f7384cd..9655594a 100644 --- a/odev/common/config.py +++ b/odev/common/config.py @@ -304,7 +304,7 @@ class Config: Light wrapper around configparser to write and retrieve configuration values saved on disk. """ - parser: ConfigParser = ConfigParser() + parser: ConfigParser """Config parser implementation.""" paths: PathsSection @@ -329,6 +329,7 @@ class Config: """Configuration for security and secrets encryption.""" def __init__(self, name: str = "odev"): + self.parser: ConfigParser = ConfigParser() self.name: str = name """Name of this config manager, also serves as the name of the file to save configuration to. From 440217ac458e2c39c126b7b477e4543dc64205e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Andreatta?= Date: Tue, 2 Jun 2026 15:32:15 +0200 Subject: [PATCH 3/3] [REF] various: format code with ruff and bump version to 4.29.4 --- odev/_version.py | 2 +- odev/common/odev.py | 2 +- tests/tests/common/test_odev.py | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/odev/_version.py b/odev/_version.py index 3273ca43..62a0d420 100644 --- a/odev/_version.py +++ b/odev/_version.py @@ -22,4 +22,4 @@ # or merged change. # ------------------------------------------------------------------------------ -__version__ = "4.29.3" +__version__ = "4.29.4" diff --git a/odev/common/odev.py b/odev/common/odev.py index f8b24c94..d49919cf 100644 --- a/odev/common/odev.py +++ b/odev/common/odev.py @@ -287,7 +287,7 @@ def start(self, start_time: float | None = None) -> None: f"Odev repository is located inside the playground folder: {resolved_path}. " "This is not recommended and can cause conflicts." ) - except Exception: + except Exception: # noqa: BLE001, S110 pass if self._should_update_now(): diff --git a/tests/tests/common/test_odev.py b/tests/tests/common/test_odev.py index 5330338f..356e3522 100644 --- a/tests/tests/common/test_odev.py +++ b/tests/tests/common/test_odev.py @@ -197,4 +197,3 @@ def test_17_warning_if_in_playground(self): self.odev.start() mock_warning.assert_called_once() self.assertIn("located inside the playground folder", mock_warning.call_args[0][0]) -