From baafc678e1c3303e857ee7d52c2471b4eec1c964 Mon Sep 17 00:00:00 2001 From: Alex Wolf Date: Fri, 16 Oct 2026 21:40:26 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Do=20not=20create=20a?= =?UTF-8?q?=20type=20for=20notes=20that=20are=20part=20of=20a=20frame?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lamin_cli/_notes.py | 4 +++- tests/core/test_save_notes.py | 24 +++++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/lamin_cli/_notes.py b/lamin_cli/_notes.py index 49cf608..915d4b9 100644 --- a/lamin_cli/_notes.py +++ b/lamin_cli/_notes.py @@ -250,10 +250,12 @@ def resolve_note_record( parent_type = resolve_note_type_parent(ln, type_chain) note_record = ln.Record.filter(name=note_name, type=parent_type).one_or_none() if note_record is None and create_if_missing: + # Pages keep notes in the type hierarchy. A record frame only accepts + # data records as rows (`record_type_is_valid_fk`). note_record = ln.Record( name=note_name, type=parent_type, - is_type=True, # notes should appear in the type hierarchy + is_type=not parent_type.is_frame, ).save() return note_record diff --git a/tests/core/test_save_notes.py b/tests/core/test_save_notes.py index b52f923..5873459 100644 --- a/tests/core/test_save_notes.py +++ b/tests/core/test_save_notes.py @@ -5,6 +5,7 @@ from pathlib import Path import lamindb as ln +import pytest def run_lamin(*args: str, cwd: Path | None = None) -> subprocess.CompletedProcess: @@ -16,13 +17,20 @@ def run_lamin(*args: str, cwd: Path | None = None) -> subprocess.CompletedProces ) -def test_save_markdown_note_creates_record_and_recordblock(): - topic = "cli-note-topic" - note_name = "cli-note" - branch = ln.Branch(name="cli_notes_branch").save() - type_record = ln.Record(name=topic, is_type=True).save() +@pytest.mark.parametrize("is_frame", [False, True]) +def test_save_markdown_note_creates_record_and_recordblock(is_frame: bool): + suffix = "_frame" if is_frame else "" + topic = f"cli-note-topic{suffix}" + note_name = f"cli-note{suffix}" + branch = ln.Branch(name=f"cli_notes_branch{suffix}").save() + schema = ( + ln.Schema(name=f"cli-note-schema{suffix}", itype=ln.Feature).save() + if is_frame + else None + ) + type_record = ln.Record(name=topic, is_type=True, schema=schema).save() - notes_root = Path(__file__).parent / "notes" + notes_root = Path(__file__).parent / f"notes{suffix}" note_dir = notes_root / topic note_dir.mkdir(parents=True, exist_ok=True) note_path = note_dir / f"{note_name}.md" @@ -45,7 +53,7 @@ def test_save_markdown_note_creates_record_and_recordblock(): .first() ) assert note_record is not None - assert note_record.is_type is True + assert note_record.is_type is not is_frame assert note_record.branch == branch readmes = note_record.ablocks.filter(kind="readme").order_by("created_at") assert readmes.count() == 1 @@ -83,6 +91,8 @@ def test_save_markdown_note_creates_record_and_recordblock(): if ln.Record.filter(uid=type_record.uid).one_or_none() is not None: type_record.refresh_from_db() type_record.delete(permanent=True) + if schema is not None and ln.Schema.filter(uid=schema.uid).one_or_none(): + schema.delete(permanent=True) branch.delete(permanent=True) From 5c90d814ecfd746bae05b717285e9b31d2163c62 Mon Sep 17 00:00:00 2001 From: Alex Wolf Date: Fri, 16 Oct 2026 21:50:44 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=92=9A=20Fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lamin_cli/_notes.py | 6 +++--- tests/core/test_save_notes.py | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lamin_cli/_notes.py b/lamin_cli/_notes.py index 915d4b9..70b7374 100644 --- a/lamin_cli/_notes.py +++ b/lamin_cli/_notes.py @@ -250,12 +250,12 @@ def resolve_note_record( parent_type = resolve_note_type_parent(ln, type_chain) note_record = ln.Record.filter(name=note_name, type=parent_type).one_or_none() if note_record is None and create_if_missing: - # Pages keep notes in the type hierarchy. A record frame only accepts - # data records as rows (`record_type_is_valid_fk`). + # Root notes and notes under a page stay in the type hierarchy. + # A record frame only accepts data records as rows. note_record = ln.Record( name=note_name, type=parent_type, - is_type=not parent_type.is_frame, + is_type=parent_type is None or not parent_type.is_frame, ).save() return note_record diff --git a/tests/core/test_save_notes.py b/tests/core/test_save_notes.py index 5873459..651b81d 100644 --- a/tests/core/test_save_notes.py +++ b/tests/core/test_save_notes.py @@ -298,6 +298,7 @@ def test_save_markdown_note_at_dev_dir_root_creates_record_and_recordblock(): ) note_record = ln.Record.filter(name=note_name, type=None, branch=branch).first() assert note_record is not None + assert note_record.is_type is True readmes = note_record.ablocks.filter(kind="readme").order_by("created_at") assert readmes.count() == 1 assert "Root note" in readmes.first().content