Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d48834b
feat(runtime): preserve explicit null values for collections and scal…
kervel Sep 10, 2025
eaf609d
chore: rustfmt and clippy fixes; avoid get(0) in tests
kervel Sep 10, 2025
d51ee4b
feat(diff): null/missing semantics; add treat_missing_as_null flag; t…
kervel Sep 10, 2025
a99c1e8
feat(diff): single flag treat_missing_as_null; explicit nulls as upda…
kervel Sep 10, 2025
7381afd
docs: testing guideline to extend existing tests instead of adding re…
kervel Sep 10, 2025
d317729
feat(runtime): add NodeIds to LinkMLValue and return PatchTrace from …
kervel Sep 10, 2025
3744161
refactor(runtime): implement LinkMLValue-native patch with incrementa…
kervel Sep 10, 2025
2c99faf
Refactor LinkMLValue builders and reuse in patch; fix fmt/clippy; res…
kervel Sep 10, 2025
6d9f753
fmt: apply rustfmt after refactor; clippy clean excluding linkml_meta
kervel Sep 10, 2025
be5dacc
diff: inline LinkMLValue builder calls; remove thin wrappers and unus…
kervel Sep 10, 2025
8746af6
diff: make patch panic-safe; return LResult and propagate errors inst…
kervel Sep 10, 2025
8af38c6
Merge pull request #4 from Kapernikov/feat/null-collections
kervel Sep 10, 2025
4e2b77e
Merge origin/main into feat/node-ids-patch-trace-clean: integrate Lin…
kervel Sep 10, 2025
3d99bd4
tests: update for Null variant; use JSON roundtrip instead of constru…
kervel Sep 10, 2025
91ec1de
diff: treat identifier/key changes as object replacement; add tests f…
kervel Sep 11, 2025
e078ce9
docs(runtime): clarify semantics of internal NodeId and PatchTrace fi…
kervel Sep 11, 2025
5c31a7b
runtime: add LinkMLValue::equals per Instances spec; tests: add equal…
Sep 11, 2025
661e9ad
python: expose LinkMLValue.equals(); tests: add python_equals coverage
Sep 11, 2025
7c58d56
runtime: equals(treat_missing_as_null) and patch no-op skipping; patc…
Sep 11, 2025
4b34691
runtime: introduce PatchOptions {ignore_no_ops, treat_missing_as_null…
Sep 11, 2025
d5337fc
dummy commit to reopen PR
kervel Sep 12, 2025
7923100
Rename LinkMLValue to LinkMLInstance across runtime, tools, Python bi…
kervel Sep 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Project Structure & Module Organization
- `src/metamodel` (`linkml_meta`): Autogenerated metamodel types; optional Serde/PyO3.
- `src/schemaview` (`schemaview`/`linkml_schemaview`): Schema loading/resolution and views (SchemaView, ClassView, SlotView, EnumView).
- `src/runtime` (`linkml_runtime`): Core runtime (LinkMLValue parse/validate, diff/patch, turtle). Pure Rust lib.
- `src/runtime` (`linkml_runtime`): Core runtime (LinkMLInstance parse/validate, diff/patch, turtle). Pure Rust lib.
- `src/tools` (`linkml_tools`): CLI binaries: `linkml-validate`, `linkml-convert`, `linkml-diff`, `linkml-patch`, `linkml-schema-validate`.
- `src/python` (`linkml_runtime_python`): PyO3 bindings and Python package `linkml_runtime_rust._native` plus helpers.
- `src/wasm` (`linkml_wasm`): WASM build target.
Expand All @@ -25,12 +25,14 @@
- Python (bindings helpers): follow PEP 8; prefer type hints where feasible.

## Testing Guidelines
- When testing locally, always provide network access. never try to run the tests offline
- Add integration tests under `src/runtime/tests/` when changing CLI/runtime behavior.
- Prefer `assert_cmd` for CLI and `predicates` for output checks. Keep fixtures in `src/runtime/tests/data/`.
- Run `cargo test --workspace` locally; ensure tests don’t rely on network input.
- Prefer modifying existing tests over adding new ones for new code paths. Extend current scenarios with extra assertions/fixtures to avoid redundant tests proliferating. For example, if adding null-handling in diff/patch, enhance the existing diff tests rather than introducing separate "basic diff works" tests that become redundant.

## Commit & Pull Request Guidelines
- Commits: short, imperative summary (e.g., “Add __repr__ for LinkMLValue”); group related changes.
- Commits: short, imperative summary (e.g., “Add __repr__ for LinkMLInstance”); group related changes.
- PRs: include clear description, rationale, and usage examples; link issues; update docs/tests; ensure CI passes: fmt, clippy (no warnings), and tests.

### Pre-commit checklist
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# linkml-core

core linkml schema operations written in rust :)
core linkml schema operations written in rust

## Crates

- linkml_meta (`src/metamodel`): Autogenerated LinkML metamodel types and helpers. Optional Serde/PyO3 features for serialization and Python interop.
- schemaview (`src/schemaview`): Schema loading, CURIE/URI conversion, resolution (feature-gated), and view utilities: `SchemaView`, `ClassView`, `SlotView`, `EnumView`.
- linkml_runtime (`src/runtime`): Core runtime: `LinkMLValue` parsing (YAML/JSON), basic validation, diff/patch, and Turtle serialization. Pure Rust library.
- linkml_runtime (`src/runtime`): Core runtime: `LinkMLInstance` parsing (YAML/JSON), basic validation, diff/patch, and Turtle serialization. Pure Rust library.
- linkml_tools (`src/tools`): CLI tools wrapping the runtime and schemaview:
- `linkml-validate`, `linkml-convert`, `linkml-diff`, `linkml-patch`, `linkml-schema-validate`.
- linkml_runtime_python (`src/python`): PyO3 bindings and Python package (`linkml_runtime_rust._native`) exposing SchemaView and LinkMLValue to Python; includes small Python helpers.
- linkml_runtime_python (`src/python`): PyO3 bindings and Python package (`linkml_runtime_rust._native`) exposing SchemaView and LinkMLInstance to Python; includes small Python helpers.
- linkml_wasm (`src/wasm`): WASM build target (experimental).

## Regenerating the metamodel
Expand Down
3 changes: 1 addition & 2 deletions src/python/python/linkml_runtime_rust/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
from ._native import * # noqa: F401,F403
from ._resolver import resolve_schemas
from .schemaview import SchemaView
from .debug_utils import pretty_linkml_value
from .debug_utils import pretty_linkml_instance
__all__ = [name for name in globals() if not name.startswith("_")]

20 changes: 10 additions & 10 deletions src/python/python/linkml_runtime_rust/debug_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Utilities for pretty-printing LinkMLValue trees.
"""Utilities for pretty-printing LinkMLInstance trees.

This module provides a pure Python helper to render a :class:`LinkMLValue`
This module provides a pure Python helper to render a :class:`LinkMLInstance`
as a human readable tree. It is intended for debugging and diagnostic use.
"""

Expand All @@ -9,19 +9,19 @@
from typing import Any, List

try: # pragma: no cover - runtime optional during type checking
from . import LinkMLValue
from . import LinkMLInstance
except Exception: # pragma: no cover - fallback when extension missing
LinkMLValue = Any # type: ignore[misc]
LinkMLInstance = Any # type: ignore[misc]

__all__ = ["pretty_linkml_value"]
__all__ = ["pretty_linkml_instance"]


def pretty_linkml_value(value: "LinkMLValue", prefix: str = '', nofirstline: bool = False) -> str:
def pretty_linkml_instance(value: "LinkMLInstance", prefix: str = '', nofirstline: bool = False) -> str:
"""Return a tree-style string representation of ``value``.

Parameters
----------
value: LinkMLValue
value: LinkMLInstance
The value to render.
indent: int, optional
Starting indentation (number of spaces).
Expand All @@ -35,18 +35,18 @@ def pretty_linkml_value(value: "LinkMLValue", prefix: str = '', nofirstline: boo
if rval.kind == "scalar":
txt += f"{prefix} | {key}={rval.as_python()}\n"
elif rval.kind == "list":
txt += f"{prefix} | {key}:\n{pretty_linkml_value(rval, prefix + ' | ')}"
txt += f"{prefix} | {key}:\n{pretty_linkml_instance(rval, prefix + ' | ')}"
else:
pfx = f"{prefix} | " + ' ' * len(key)
txt += f"{prefix} | {key}: {pretty_linkml_value(rval, pfx, nofirstline=True)}"
txt += f"{prefix} | {key}: {pretty_linkml_instance(rval, pfx, nofirstline=True)}"
txt += f"{prefix} |\n"
elif value.kind == "list":
for idx in range(len(value)):
rval = value[idx]
if rval.kind == "scalar":
txt = f"{prefix} - {rval.as_python()}\n"
else:
txt = f"{prefix} - {pretty_linkml_value(rval, prefix + ' ', nofirstline=True)}"
txt = f"{prefix} - {pretty_linkml_instance(rval, prefix + ' ', nofirstline=True)}"
elif value.kind == "scalar":
txt = f"{prefix}{value.as_python()}\n"
else:
Expand Down
Loading
Loading