From 1f48faaf1275f2deb78bbf2867cfbc02c260d799 Mon Sep 17 00:00:00 2001 From: David Brochart Date: Tue, 13 Oct 2026 09:49:31 +0200 Subject: [PATCH] Support local imports --- src/akernel/kernel.py | 5 +++++ tests/test_startup.py | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/akernel/kernel.py b/src/akernel/kernel.py index 0b8161d..d3627ac 100644 --- a/src/akernel/kernel.py +++ b/src/akernel/kernel.py @@ -146,6 +146,11 @@ def __init__( def init_kernel(self): if self.kernel_initialized: return + # Console-script launchers put their bin directory on sys.path. + # Resolve local imports against the current working directory, including + # after user code changes it. + if "" not in sys.path: + sys.path.insert(0, "") self.globals = {"print": self.print, "_": None} if self.execute_in_thread: self.globals["input"] = self.input diff --git a/tests/test_startup.py b/tests/test_startup.py index ab98c0e..336ff19 100644 --- a/tests/test_startup.py +++ b/tests/test_startup.py @@ -1,14 +1,37 @@ +import sys from types import SimpleNamespace import pytest from anyio import create_memory_object_stream, create_task_group, fail_after +from akernel.execution import compile_cell, execute_cell from akernel.kernel import Kernel from akernel.message import create_message, deserialize, feed_identities, serialize pytestmark = pytest.mark.anyio +async def test_local_imports_follow_working_directory(tmp_path, monkeypatch): + # Reproduce a console-script launch without the working directory on sys.path. + monkeypatch.setattr(sys, "path", [path for path in sys.path if path != ""]) + kernel = Kernel(*([None] * 7)) + kernel.init_kernel() + for index in range(2): + directory = tmp_path / str(index) + package = directory / f"local_package_{index}" + package.mkdir(parents=True) + (package / "foo.py").write_text(f"bar = {index}\n") + monkeypatch.chdir(directory) + try: + result = await execute_cell( + compile_cell(f"from local_package_{index}.foo import bar\nbar"), kernel.globals + ) + assert result == index + finally: + sys.modules.pop(f"local_package_{index}.foo", None) + sys.modules.pop(f"local_package_{index}", None) + + class TestStartup: @pytest.fixture(autouse=True) async def kernel_fixture(self, anyio_backend):