Skip to content

fix(codegen-python): generate pydantic-friendly type aliases#3478

Merged
sxlijin merged 6 commits into
canaryfrom
sam/type-shapes-rig
May 7, 2026
Merged

fix(codegen-python): generate pydantic-friendly type aliases#3478
sxlijin merged 6 commits into
canaryfrom
sam/type-shapes-rig

Conversation

@sxlijin

@sxlijin sxlijin commented May 6, 2026

Copy link
Copy Markdown
Contributor

Also add a new rig_tests crate that exercises every type variant and routing rule from bridge-python/18a-type-exhaustiveness.md. Generated baml_sdk/ is checked into VCS so reviewers can diff codegen output directly.

Failures discovered while authoring the BAML source are recorded in 18b-type-exhaustiveness-failures.md (cross-namespace user-package refs, $rust_type gating, pure-expression functions not emitting Python, recursive-alias-before-class pydantic recursion, generic-class stream companion losing type params, and others).

Summary by CodeRabbit

  • Bug Fixes

    • Recursive type aliases now render via typing_extensions.TypeAliasType with quoted forward-refs; cross-leaf and root imports are emitted under typing.TYPE_CHECKING.
  • New Features

    • Added generation step and test harness to produce and validate a Python SDK from BAML sources.
  • Tests

    • Added end-to-end generation + runtime/import smoke tests for the generated SDK.
  • New Fixtures

    • Large suite of type-shape fixtures covering primitives, enums, lists, maps, generics, recursion, unions, streams, media, literals, and passthrough helpers.
  • Documentation

    • Expanded inline routing/type-shape guidance and clarified generated/ outputs are ignored and regenerated on build.

@vercel

vercel Bot commented May 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
beps Ready Ready Preview, Comment May 7, 2026 10:19am
promptfiddle Ready Ready Preview, Comment May 7, 2026 10:19am

Request Review

@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Emits recursive type aliases as typing_extensions.TypeAliasType with same-leaf forward-ref quoting; updates TranslateCtx/name rendering, leaf emission and imports, unit tests, and adds a type_shapes rig crate with build.rs, many BAML fixtures, and Python smoke tests.

Changes

Recursive Type Alias Implementation & Testing

Layer / File(s) Summary
Type Shape Fixtures
baml_language/rig_tests/crates/type_shapes/baml_src/*
Adds 20+ BAML fixture files covering primitives, lists, maps, optionals, unions, enums, generics, recursion (self/mutual/SCC), forward refs, recursive & non-recursive aliases, literals, media/streams, class refs, and namespace routing with passthrough functions.
Rig Crate & Build/Test Scaffolding
baml_language/rig_tests/crates/type_shapes/Cargo.toml, baml_language/rig_tests/crates/type_shapes/build.rs, baml_language/rig_tests/crates/type_shapes/src/lib.rs, baml_language/rig_tests/crates/.gitignore, baml_language/rig_tests/crates/type_shapes/customizable/test_main.py
Adds rig_type_shapes manifest and a build.rs that generates generated/baml_sdk from baml_src via codegen_python, writes pyproject/test scripts, symlinks customizable/ when present, emits cargo rerun hints, and provides Rust and Python smoke tests; documents generated/ in .gitignore.
Type Alias & Translation Core
baml_language/languages/python/rust/codegen_python/src/emit/type_alias.rs, baml_language/languages/python/rust/codegen_python/src/translate_ty.rs
PyTypeAlias docs rewritten to describe non-recursive -> typing.TypeAlias and recursive -> typing_extensions.TypeAliasType; TranslateCtx adds defer_name_refs to control forward-ref quoting and name emission updated to conditionally quote same-leaf recursive refs; removed #[allow(dead_code)] on source.
Leaf Rendering & Imports
baml_language/languages/python/rust/codegen_python/src/leaf.rs
LeafBody detects recursive aliases (has_recursive_alias()), hoists recursive aliases to front, uses shared render_type_alias(...), adds TypeAliasTypePy template, and reorganizes root-import collection into guarded import emission; .py/.pyi import blocks include typing_extensions when needed and .pyi sets deferred quoting off.
Unit Tests
baml_language/languages/python/rust/codegen_python/src/lib.rs
Unit tests updated to assert recursive aliases render via typing_extensions.TypeAliasType(...) with forward-quoted self-references and import typing_extensions; added tests for quoted cross-leaf/root references and guarded relative imports for non-root leaves referencing root types; added root init non-self-import assertion.
Python Smoke Tests
baml_language/rig_tests/crates/type_shapes/customizable/test_main.py
Pytest smoke tests that import the generated baml_sdk, assert expected sub-namespaces exist, and confirm selected symbols (Foo, Resume, Thing) are reachable from root and nested modules.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • BoundaryML/baml#3213: Both PRs touch recursive type-alias handling and output-format rendering—introducing quoted forward-refs/defer-name logic and plumbing for recursive alias metadata—so they are related.
  • BoundaryML/baml#3471: Both PRs modify baml_language/languages/python/rust/codegen_python/src/leaf.rs to expand .pyi emission parity — adding pyi-specific traversal/import helpers and richer class/field handling — so they touch the same functions/areas and are related.
  • BoundaryML/baml#3480: Both PRs modify codegen_python/src/leaf.rs’s leaf rendering/import logic (including render_leaf_body and stdlib import handling), so the changes are related at the code level.

🐰 With TypeAliasType now in tow,

Forward-refs find room to grow,
Fixtures bloom in many leaves,
The generated SDK softly weaves,
A rabbit cheers the code's new flow.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: improving Python type-alias generation for Pydantic compatibility by using typing_extensions.TypeAliasType for recursive aliases.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sam/type-shapes-rig

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 906fe5396a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

let _ = fs::remove_file(&dst);
}
#[cfg(unix)]
std::os::unix::fs::symlink(&src, &dst).unwrap_or_else(|_| {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Write generated test files portably

In a fresh checkout, this symlinks generated/test_main.py to the absolute CARGO_MANIFEST_DIR path from the machine that ran codegen; the committed tree already records /Users/sam/baml2/..., so anyone running type_shapes/generated/test.sh directly gets a broken test_main.py and pytest exits with no tests. Copy the customizable file or create a relative symlink before committing generated output.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (3)
baml_language/rig_tests/crates/type_shapes/baml_src/ns_optional/types.baml (1)

10-14: 💤 Low value

OptionalContainer has no corresponding Pass… function — intentional gap or omission?

Every other ns_* module in the suite appears to pair container classes with a Pass… function to exercise round-trip codegen. OptionalContainer is defined but has no PassOptionalContainer counterpart. If this is deliberate (testing the class shape in isolation), a brief comment noting that would prevent confusion for future contributors.

💡 Suggested addition (if a pass-through is desired)
 function PassOptionalUnion(u: (int | string)?) -> (int | string)? {
   u
 }
+
+function PassOptionalContainer(c: OptionalContainer?) -> OptionalContainer? {
+  c
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/rig_tests/crates/type_shapes/baml_src/ns_optional/types.baml`
around lines 10 - 14, The file defines OptionalContainer but lacks the
corresponding pass-through function; either add a PassOptionalContainer function
to the ns_optional test module to exercise round-trip codegen for the
OptionalContainer class (match the naming/pattern used by other ns_* modules) or
add a brief comment above OptionalContainer stating the omission is intentional
and this class is tested in isolation; reference the OptionalContainer class and
the expected PassOptionalContainer function in your change so future reviewers
can see the intent.
baml_language/rig_tests/crates/type_shapes/src/lib.rs (1)

11-29: 💤 Low value

Consider Option<&str> instead of an empty-string sentinel for the optional argument.

Using "" as a sentinel and guarding it with !arg.is_empty() works but is less explicit than an Option. This is a purely stylistic nit in a test module; no functional impact.

♻️ Proposed refactor
-        #[cfg(windows)]
-        let (script_name, command, arg) = ("test.ps1", "powershell", "-File");
-
-        #[cfg(not(windows))]
-        let (script_name, command, arg) = ("test.sh", "bash", "");
-
-        let test_script = dir.join(script_name);
-
-        assert!(
-            test_script.exists(),
-            "{} not found in generated directory",
-            script_name
-        );
-
-        // Run the test script
-        let mut cmd = Command::new(command);
-        if !arg.is_empty() {
-            cmd.arg(arg);
-        }
+        #[cfg(windows)]
+        let (script_name, command, flag) = ("test.ps1", "powershell", Some("-File"));
+
+        #[cfg(not(windows))]
+        let (script_name, command, flag): (&str, &str, Option<&str>) = ("test.sh", "bash", None);
+
+        let test_script = dir.join(script_name);
+
+        assert!(
+            test_script.exists(),
+            "{} not found in generated directory",
+            script_name
+        );
+
+        // Run the test script
+        let mut cmd = Command::new(command);
+        if let Some(f) = flag {
+            cmd.arg(f);
+        }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/rig_tests/crates/type_shapes/src/lib.rs` around lines 11 - 29,
The test uses an empty-string sentinel for the optional shell argument; change
the tuple to use Option<&str> for arg (e.g. let (script_name, command, arg):
(&str, &str, Option<&str>) = ("test.ps1","powershell", Some("-File")) and
("test.sh","bash", None)), then update the Command builder (variable cmd) to add
the argument with if let Some(a) = arg { cmd.arg(a); } so the presence/absence
is explicit; keep script_name, command and test_script logic unchanged.
baml_language/rig_tests/crates/type_shapes/build.rs (1)

205-208: ⚡ Quick win

Keep the Windows test script aligned with the Unix checks.

test.sh runs pyright, but test.ps1 skips it. That leaves a Windows-only gap in the rig's main type-validation signal.

Proposed fix
 Write-Host "==> Running ruff lint..."
 uv run ruff check --config pyproject.toml baml_sdk
+Write-Host "==> Running pyright..."
+uv run pyright baml_sdk
 Write-Host "==> Running pytest..."
 uv run pytest -v
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/rig_tests/crates/type_shapes/build.rs` around lines 205 - 208,
The Windows test script currently runs ruff and pytest but omits the pyright
type check present in the Unix test.sh; update the PowerShell block (the lines
with Write-Host and the uv run commands) to add the pyright invocation (e.g.,
add a line like "uv run pyright --project pyrightconfig.json" or the project's
equivalent) between the ruff and pytest commands so Windows runs the same
pyright type validation as Unix.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@baml_language/rig_tests/crates/type_shapes/baml_src/ns_generics/types.baml`:
- Around line 7-9: The header comment incorrectly says the "instantiation
differs from declaration" case occurs inside GenericLinkedList<T>; update the
comment to instead reference the actual case exercised by
DifferingInstantiation.list (which contains next:
GenericLinkedList<Wrapper<int>> differing from GenericLinkedList<T>), or reword
the header to point to DifferingInstantiation.list and describe the rendered
output (Union["GenericLinkedList[Wrapper[int]]", None]); ensure the symbols
GenericLinkedList and DifferingInstantiation.list are mentioned so the comment
aligns with the codegen surface.

In `@baml_language/rig_tests/crates/type_shapes/build.rs`:
- Around line 93-108: The Windows symlink branch using
std::os::windows::fs::symlink_file may fail on CI; change the unwrap_or_else
panic to attempt a fallback copy using std::fs::copy(src, &dst) when
symlink_file returns Err, and only panic if the copy also fails; do the same for
the unix branch if you want parity, and include src, dst and
file_name.to_string_lossy() in the final panic message so failures show both
operations and the file path.
- Around line 215-226: The build script only registers individual files but not
the directories themselves, so adding new files won't trigger Cargo; update
watch_dir to first emit println!("cargo:rerun-if-changed={}", dir.display()) for
the directory (so Cargo watches the directory itself) and then iterate
walk_files(dir) to emit entries for each file; change calls that use watch_dir
(e.g., where baml_src and customizable_dir are passed) remain the same but now
both the directory and its current contents are registered for rebuilds.

In `@baml_language/rig_tests/crates/type_shapes/src/lib.rs`:
- Line 34: The panic on spawn failure discards the std::io::Error via the
closure |_|; update the unwrap_or_else call (the closure attached to spawn
result where script_name is used) to capture the error (e) and include it in the
panic message so the OS error is shown (e.g., panic!("Failed to run {}: {}",
script_name, e)). Locate the unwrap_or_else(...) call near the spawn/command
invocation and replace the |_| closure with a closure that takes the error and
includes it in the panic.

---

Nitpick comments:
In `@baml_language/rig_tests/crates/type_shapes/baml_src/ns_optional/types.baml`:
- Around line 10-14: The file defines OptionalContainer but lacks the
corresponding pass-through function; either add a PassOptionalContainer function
to the ns_optional test module to exercise round-trip codegen for the
OptionalContainer class (match the naming/pattern used by other ns_* modules) or
add a brief comment above OptionalContainer stating the omission is intentional
and this class is tested in isolation; reference the OptionalContainer class and
the expected PassOptionalContainer function in your change so future reviewers
can see the intent.

In `@baml_language/rig_tests/crates/type_shapes/build.rs`:
- Around line 205-208: The Windows test script currently runs ruff and pytest
but omits the pyright type check present in the Unix test.sh; update the
PowerShell block (the lines with Write-Host and the uv run commands) to add the
pyright invocation (e.g., add a line like "uv run pyright --project
pyrightconfig.json" or the project's equivalent) between the ruff and pytest
commands so Windows runs the same pyright type validation as Unix.

In `@baml_language/rig_tests/crates/type_shapes/src/lib.rs`:
- Around line 11-29: The test uses an empty-string sentinel for the optional
shell argument; change the tuple to use Option<&str> for arg (e.g. let
(script_name, command, arg): (&str, &str, Option<&str>) =
("test.ps1","powershell", Some("-File")) and ("test.sh","bash", None)), then
update the Command builder (variable cmd) to add the argument with if let
Some(a) = arg { cmd.arg(a); } so the presence/absence is explicit; keep
script_name, command and test_script logic unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e8d224be-d490-4e0f-9ea9-193327e9692a

📥 Commits

Reviewing files that changed from the base of the PR and between f60772c and 906fe53.

⛔ Files ignored due to path filters (127)
  • baml_language/Cargo.lock is excluded by !**/*.lock
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/b/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/b/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/_inlinedbaml.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/errors/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/errors/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/fs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/fs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/glob/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/glob/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/http/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/http/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/llm/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/llm/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/net/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/net/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/panics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/panics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/stream/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/stream/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/sys/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/sys/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/class_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/class_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/enums/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/enums/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/forward_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/forward_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/generics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/generics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lists/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lists/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/literals/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/literals/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lorem/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lorem/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/maps/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/maps/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/optional/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/optional/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/primitives/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/primitives/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/py.typed is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/recursion/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/recursion/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/b/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/b/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/errors/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/errors/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/fs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/fs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/glob/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/glob/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/http/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/http/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/llm/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/llm/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/net/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/net/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/panics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/panics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/stream/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/stream/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/sys/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/sys/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/class_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/class_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/enums/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/enums/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/forward_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/forward_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/generics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/generics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lists/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lists/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/literals/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/literals/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lorem/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lorem/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/maps/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/maps/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/optional/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/optional/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/primitives/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/primitives/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/recursion/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/recursion/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/unions/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/unions/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/testing/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/testing/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/unions/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/unions/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/testing/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/testing/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/pyproject.toml is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/test.ps1 is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/test.sh is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/test_main.py is excluded by !**/generated/**
📒 Files selected for processing (25)
  • baml_language/rig_tests/crates/.gitignore
  • baml_language/rig_tests/crates/type_shapes/Cargo.toml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_class_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_enums/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_forward_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_generics/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lists/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_literals/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/streams.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_maps/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_media/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_optional/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_primitives/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_recursion/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_unions/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_void/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/root.baml
  • baml_language/rig_tests/crates/type_shapes/build.rs
  • baml_language/rig_tests/crates/type_shapes/customizable/test_main.py
  • baml_language/rig_tests/crates/type_shapes/src/lib.rs

Comment on lines +7 to +9
// - "instantiation differs from declaration" — inside GenericLinkedList<T>,
// `next: GenericLinkedList<Wrapper<int>>` (different T arg) → rendered
// as `Union["GenericLinkedList[Wrapper[int]]", None]`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Header comment doesn't match the code it points at.

The bullet describes next: GenericLinkedList<Wrapper<int>> inside GenericLinkedList<T>, but the actual class at lines 15-18 has next GenericLinkedList<T>? (same T). The "differing instantiation" case is exercised by DifferingInstantiation.list at lines 45-47, not on GenericLinkedList itself. Worth fixing so the header accurately maps to where the codegen surface actually appears, since this file is meant to be diffed against generated Python.

📝 Suggested doc fix
-//   - "instantiation differs from declaration" — inside GenericLinkedList<T>,
-//     `next: GenericLinkedList<Wrapper<int>>` (different T arg) → rendered
-//     as `Union["GenericLinkedList[Wrapper[int]]", None]`.
+//   - "instantiation differs from declaration" — `DifferingInstantiation.list`
+//     of type `GenericLinkedList<Wrapper<int>>` instantiates the recursive
+//     generic with a non-TypeVar arg at a non-declaration site → rendered
+//     as `"GenericLinkedList[Wrapper[int]]"`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// - "instantiation differs from declaration" — inside GenericLinkedList<T>,
// `next: GenericLinkedList<Wrapper<int>>` (different T arg) → rendered
// as `Union["GenericLinkedList[Wrapper[int]]", None]`.
// - "instantiation differs from declaration" — `DifferingInstantiation.list`
// of type `GenericLinkedList<Wrapper<int>>` instantiates the recursive
// generic with a non-TypeVar arg at a non-declaration site → rendered
// as `"GenericLinkedList[Wrapper[int]]"`.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/rig_tests/crates/type_shapes/baml_src/ns_generics/types.baml`
around lines 7 - 9, The header comment incorrectly says the "instantiation
differs from declaration" case occurs inside GenericLinkedList<T>; update the
comment to instead reference the actual case exercised by
DifferingInstantiation.list (which contains next:
GenericLinkedList<Wrapper<int>> differing from GenericLinkedList<T>), or reword
the header to point to DifferingInstantiation.list and describe the rendered
output (Union["GenericLinkedList[Wrapper[int]]", None]); ensure the symbols
GenericLinkedList and DifferingInstantiation.list are mentioned so the comment
aligns with the codegen surface.

Comment on lines +93 to +108
#[cfg(unix)]
std::os::unix::fs::symlink(&src, &dst).unwrap_or_else(|_| {
panic!(
"Failed to symlink {} from {}",
file_name.to_string_lossy(),
src.display()
)
});
#[cfg(windows)]
std::os::windows::fs::symlink_file(&src, &dst).unwrap_or_else(|_| {
panic!(
"Failed to symlink {} from {}",
file_name.to_string_lossy(),
src.display()
)
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

# First, locate and examine the build.rs file
find . -name "build.rs" -path "*/type_shapes/*" | head -5

Repository: BoundaryML/baml

Length of output: 113


🏁 Script executed:

# Read the file around the specified lines
cat -n baml_language/rig_tests/crates/type_shapes/build.rs | sed -n '80,115p'

Repository: BoundaryML/baml

Length of output: 1654


🏁 Script executed:

# Check imports at the top of the file
head -30 baml_language/rig_tests/crates/type_shapes/build.rs | cat -n

Repository: BoundaryML/baml

Length of output: 1401


🏁 Script executed:

# Search for how the symlinked/copied files are used
grep -r "generated/" baml_language/rig_tests/crates/type_shapes/ -A 2 -B 2 | head -40

Repository: BoundaryML/baml

Length of output: 478


🏁 Script executed:

# Check the actual structure and see if there are tests
ls -la baml_language/rig_tests/crates/type_shapes/

Repository: BoundaryML/baml

Length of output: 529


🏁 Script executed:

# Look for test files in the crate
find baml_language/rig_tests/crates/type_shapes/ -name "*.rs" -type f

Repository: BoundaryML/baml

Length of output: 165


🏁 Script executed:

# Check the Cargo.toml to understand the crate purpose
cat baml_language/rig_tests/crates/type_shapes/Cargo.toml

Repository: BoundaryML/baml

Length of output: 802


🏁 Script executed:

# Verify if fs::copy is already in use elsewhere or if there are any issues with the proposed fallback
grep -n "fs::copy\|fs::symlink" baml_language/rig_tests/crates/type_shapes/build.rs

Repository: BoundaryML/baml

Length of output: 218


🏁 Script executed:

# Check the lib.rs to understand the crate structure and tests
cat baml_language/rig_tests/crates/type_shapes/src/lib.rs

Repository: BoundaryML/baml

Length of output: 1340


🏁 Script executed:

# Look at the entire build.rs to understand context - especially how the generated files are used
wc -l baml_language/rig_tests/crates/type_shapes/build.rs

Repository: BoundaryML/baml

Length of output: 115


🏁 Script executed:

# Read the full build.rs
cat baml_language/rig_tests/crates/type_shapes/build.rs

Repository: BoundaryML/baml

Length of output: 8034


Fall back to copying customizable files when symlinks are unavailable on Windows.

symlink_file requires Developer Mode or elevated privileges on Windows and commonly fails on standard runners. This can block builds on those platforms even though the test runner only needs to read the file contents from generated/. Since fs is already imported, the fallback is straightforward and widely used for this pattern.

Proposed fix
             #[cfg(windows)]
-            std::os::windows::fs::symlink_file(&src, &dst).unwrap_or_else(|_| {
-                panic!(
-                    "Failed to symlink {} from {}",
-                    file_name.to_string_lossy(),
-                    src.display()
-                )
-            });
+            if let Err(err) = std::os::windows::fs::symlink_file(&src, &dst) {
+                fs::copy(&src, &dst).unwrap_or_else(|copy_err| {
+                    panic!(
+                        "Failed to materialize {} from {}: symlink failed with {err}; copy failed with {copy_err}",
+                        file_name.to_string_lossy(),
+                        src.display()
+                    )
+                });
+            }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#[cfg(unix)]
std::os::unix::fs::symlink(&src, &dst).unwrap_or_else(|_| {
panic!(
"Failed to symlink {} from {}",
file_name.to_string_lossy(),
src.display()
)
});
#[cfg(windows)]
std::os::windows::fs::symlink_file(&src, &dst).unwrap_or_else(|_| {
panic!(
"Failed to symlink {} from {}",
file_name.to_string_lossy(),
src.display()
)
});
#[cfg(unix)]
std::os::unix::fs::symlink(&src, &dst).unwrap_or_else(|_| {
panic!(
"Failed to symlink {} from {}",
file_name.to_string_lossy(),
src.display()
)
});
#[cfg(windows)]
if let Err(err) = std::os::windows::fs::symlink_file(&src, &dst) {
fs::copy(&src, &dst).unwrap_or_else(|copy_err| {
panic!(
"Failed to materialize {} from {}: symlink failed with {err}; copy failed with {copy_err}",
file_name.to_string_lossy(),
src.display()
)
});
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/rig_tests/crates/type_shapes/build.rs` around lines 93 - 108,
The Windows symlink branch using std::os::windows::fs::symlink_file may fail on
CI; change the unwrap_or_else panic to attempt a fallback copy using
std::fs::copy(src, &dst) when symlink_file returns Err, and only panic if the
copy also fails; do the same for the unix branch if you want parity, and include
src, dst and file_name.to_string_lossy() in the final panic message so failures
show both operations and the file path.

Comment on lines +215 to +226
println!("cargo:rerun-if-changed=build.rs");
watch_dir(&baml_src);
if customizable_dir.exists() {
watch_dir(&customizable_dir);
}
}

fn watch_dir(dir: &Path) {
let walker = walk_files(dir);
for path in walker {
println!("cargo:rerun-if-changed={}", path.display());
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

find . -name "build.rs" -path "*/type_shapes/*" -type f

Repository: BoundaryML/baml

Length of output: 113


🏁 Script executed:

sed -n '210,230p' ./baml_language/rig_tests/crates/type_shapes/build.rs

Repository: BoundaryML/baml

Length of output: 605


🏁 Script executed:

sed -n '233,260p' ./baml_language/rig_tests/crates/type_shapes/build.rs

Repository: BoundaryML/baml

Length of output: 285


🏁 Script executed:

sed -n '227,245p' ./baml_language/rig_tests/crates/type_shapes/build.rs

Repository: BoundaryML/baml

Length of output: 448


🌐 Web query:

Cargo rerun-if-changed directory behavior new files

💡 Result:

Cargo build-script change detection via cargo:rerun-if-changed=PATH: 1) If PATH is a directory, Cargo does NOT reliably treat “new/changed files inside that directory” as a reason to rerun. - Historically/according to Cargo issue discussions, Cargo does not traverse the directory to find changes inside; instead it uses directory mtime semantics (which correspond to some changes depending on platform) rather than recursively watching all contents. This means edits/new files may not trigger the build script the way you might expect. [1][2] 2) How to get the behavior you want (rerun when new/changed files appear inside a directory): - Emit cargo:rerun-if-changed for the directory itself and also for the files inside it recursively (i.e., list them explicitly, or generate that list in build.rs/a helper). The Cargo docs state that to request a re-run on any changes within an entire directory, you must print a line for the directory and separate lines for everything inside it, recursively. [3][2] 3) If you see behavior that differs (e.g., “directory scanning”): - There have been implementation work items/PRs around scanning directories for changes when rerun-if-changed points to a directory (as opposed to only directory mtime), but the safe, documented way is still to emit explicit paths if you need correctness for “new files/contents.” [3] Practical recommendation - For “new files in a directory should trigger rerun”, don’t rely on cargo:rerun-if-changed=<dir> alone. Instead, enumerate the directory contents (recursively) and print cargo:rerun-if-changed=<file> for each, plus optionally the directory itself. [2][3]

Citations:


🏁 Script executed:

rg "rerun-if-changed" ./baml_language/rig_tests/crates/type_shapes/build.rs

Repository: BoundaryML/baml

Length of output: 241


Register the source directories with Cargo to detect new files.

The current implementation only emits cargo:rerun-if-changed for files that exist during the build. Cargo does not reliably detect new files added to a directory monitored only via its mtime. Adding a new .baml file or a new customizable fixture will not retrigger codegen until some already-watched path changes.

To fix this, register both the directories themselves and their contents:

Proposed fix
     println!("cargo:rerun-if-changed=build.rs");
+    println!("cargo:rerun-if-changed={}", baml_src.display());
     watch_dir(&baml_src);
     if customizable_dir.exists() {
+        println!("cargo:rerun-if-changed={}", customizable_dir.display());
         watch_dir(&customizable_dir);
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
println!("cargo:rerun-if-changed=build.rs");
watch_dir(&baml_src);
if customizable_dir.exists() {
watch_dir(&customizable_dir);
}
}
fn watch_dir(dir: &Path) {
let walker = walk_files(dir);
for path in walker {
println!("cargo:rerun-if-changed={}", path.display());
}
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed={}", baml_src.display());
watch_dir(&baml_src);
if customizable_dir.exists() {
println!("cargo:rerun-if-changed={}", customizable_dir.display());
watch_dir(&customizable_dir);
}
}
fn watch_dir(dir: &Path) {
let walker = walk_files(dir);
for path in walker {
println!("cargo:rerun-if-changed={}", path.display());
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/rig_tests/crates/type_shapes/build.rs` around lines 215 - 226,
The build script only registers individual files but not the directories
themselves, so adding new files won't trigger Cargo; update watch_dir to first
emit println!("cargo:rerun-if-changed={}", dir.display()) for the directory (so
Cargo watches the directory itself) and then iterate walk_files(dir) to emit
entries for each file; change calls that use watch_dir (e.g., where baml_src and
customizable_dir are passed) remain the same but now both the directory and its
current contents are registered for rebuilds.

.arg(&test_script)
.current_dir(&dir)
.output()
.unwrap_or_else(|_| panic!("Failed to run {}", script_name));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Include the OS error in the spawn-failure panic message.

The |_| closure discards the std::io::Error, making it hard to diagnose why the process failed to launch (e.g., bash not on PATH, permission denied).

🔧 Proposed fix
-            .unwrap_or_else(|_| panic!("Failed to run {}", script_name));
+            .unwrap_or_else(|e| panic!("Failed to run {}: {}", script_name, e));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.unwrap_or_else(|_| panic!("Failed to run {}", script_name));
.unwrap_or_else(|e| panic!("Failed to run {}: {}", script_name, e));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/rig_tests/crates/type_shapes/src/lib.rs` at line 34, The panic
on spawn failure discards the std::io::Error via the closure |_|; update the
unwrap_or_else call (the closure attached to spawn result where script_name is
used) to capture the error (e) and include it in the panic message so the OS
error is shown (e.g., panic!("Failed to run {}: {}", script_name, e)). Locate
the unwrap_or_else(...) call near the spawn/command invocation and replace the
|_| closure with a closure that takes the error and includes it in the panic.

@codspeed-hq

codspeed-hq Bot commented May 6, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 10.41%

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚡ 1 improved benchmark
✅ 18 untouched benchmarks

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime engine_init_cost 2.8 ms 2.5 ms +10.41%

Comparing sam/type-shapes-rig (c7ef019) with canary (48db958)

Open in CodSpeed

@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown

Binary size checks passed

7 passed

Artifact Platform Gzip Baseline Delta Status
bridge_cffi Linux 6.2 MB 5.7 MB +507.2 KB (+8.9%) OK
bridge_cffi-stripped Linux 5.2 MB 5.7 MB -449.6 KB (-7.9%) OK
bridge_cffi macOS 5.1 MB 5.1 MB +657 B (+0.0%) OK
bridge_cffi-stripped macOS 4.3 MB 4.7 MB -378.1 KB (-8.1%) OK
bridge_cffi Windows 5.1 MB 5.1 MB +446 B (+0.0%) OK
bridge_cffi-stripped Windows 4.4 MB 4.7 MB -263.8 KB (-5.7%) OK
bridge_wasm WASM 3.3 MB 3.3 MB +36.5 KB (+1.1%) OK

Generated by cargo size-gate · workflow run

@sxlijin
sxlijin force-pushed the sam/type-shapes-rig branch from 906fe53 to 7c6ba12 Compare May 6, 2026 23:17
@sxlijin sxlijin changed the title test(rig): add type_shapes crate covering BEP-030 Ty exhaustiveness fix(codegen-python): generate pydantic-friendly type aliases May 6, 2026
@sxlijin
sxlijin force-pushed the sam/type-shapes-rig branch from 7c6ba12 to cc96629 Compare May 6, 2026 23:21
coderabbitai[bot]
coderabbitai Bot previously requested changes May 6, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
baml_language/rig_tests/crates/type_shapes/baml_src/ns_generics/types.baml (1)

7-9: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Header comment still points to the wrong instantiation site.

This note says the differing-instantiation case is inside GenericLinkedList<T>, but that class uses next GenericLinkedList<T>? (Line 17). The non-matching instantiation is actually DifferingInstantiation.list (Line 46). Please realign the comment so it matches the exercised fixture.

Suggested minimal doc fix
-//   - "instantiation differs from declaration" — inside GenericLinkedList<T>,
-//     `next: GenericLinkedList<Wrapper<int>>` (different T arg) → rendered
-//     as `Union["GenericLinkedList[Wrapper[int]]", None]`.
+//   - "instantiation differs from declaration" — `DifferingInstantiation.list`
+//     uses `GenericLinkedList<Wrapper<int>>` (non-TypeVar generic arg at a
+//     non-declaration site) to exercise differing recursive instantiation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/rig_tests/crates/type_shapes/baml_src/ns_generics/types.baml`
around lines 7 - 9, The header comment incorrectly says the
differing-instantiation case is inside GenericLinkedList<T>; update the comment
to point at the actual site exercised by the fixture, namely
DifferingInstantiation.list (the instantiation where next is
GenericLinkedList<Wrapper<int>> vs the declaration GenericLinkedList<T>), so the
documentation matches the tested scenario and references
DifferingInstantiation.list instead of GenericLinkedList<T>.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@baml_language/languages/python/rust/codegen_python/src/leaf.rs`:
- Around line 320-338: The hoist that moves recursive aliases to the front (the
pairs.sort_by_key block that matches EmittedSymbol::TypeAlias(a) if a.recursive)
can break runtime .py imports because the TypeAliasType(...) RHS may reference
same-leaf names that are defined later; constrain this hoist to only run when
emitting stubs (e.g., when emitting .pyi) by gating the pairs.sort_by_key call
on the emission-mode flag, otherwise preserve the earlier stable sort order for
.py output, or alternatively implement forward-quoting of unresolved same-leaf
references in the TypeAlias RHS so runtime evaluation won’t raise NameError.

---

Duplicate comments:
In `@baml_language/rig_tests/crates/type_shapes/baml_src/ns_generics/types.baml`:
- Around line 7-9: The header comment incorrectly says the
differing-instantiation case is inside GenericLinkedList<T>; update the comment
to point at the actual site exercised by the fixture, namely
DifferingInstantiation.list (the instantiation where next is
GenericLinkedList<Wrapper<int>> vs the declaration GenericLinkedList<T>), so the
documentation matches the tested scenario and references
DifferingInstantiation.list instead of GenericLinkedList<T>.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: dacf5c68-6dbd-45c7-9a36-7a6c2899d6ec

📥 Commits

Reviewing files that changed from the base of the PR and between 906fe53 and 7c6ba12.

⛔ Files ignored due to path filters (131)
  • baml_language/Cargo.lock is excluded by !**/*.lock
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/b/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/b/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases_consumer/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases_consumer/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/_inlinedbaml.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/errors/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/errors/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/fs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/fs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/glob/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/glob/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/http/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/http/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/llm/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/llm/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/net/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/net/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/panics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/panics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/stream/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/stream/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/sys/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/sys/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/class_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/class_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/enums/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/enums/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/forward_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/forward_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/generics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/generics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lists/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lists/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/literals/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/literals/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lorem/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lorem/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/maps/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/maps/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/optional/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/optional/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/primitives/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/primitives/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/py.typed is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/recursion/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/recursion/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/b/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/b/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases_consumer/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases_consumer/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/errors/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/errors/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/fs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/fs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/glob/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/glob/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/http/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/http/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/llm/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/llm/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/net/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/net/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/panics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/panics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/stream/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/stream/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/sys/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/sys/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/class_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/class_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/enums/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/enums/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/forward_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/forward_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/generics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/generics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lists/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lists/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/literals/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/literals/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lorem/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lorem/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/maps/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/maps/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/optional/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/optional/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/primitives/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/primitives/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/recursion/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/recursion/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/unions/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/unions/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/testing/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/testing/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/unions/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/unions/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/testing/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/testing/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/pyproject.toml is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/test.ps1 is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/test.sh is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/test_main.py is excluded by !**/generated/**
📒 Files selected for processing (32)
  • baml_language/languages/python/rust/codegen_python/src/emit/type_alias.rs
  • baml_language/languages/python/rust/codegen_python/src/leaf.rs
  • baml_language/languages/python/rust/codegen_python/src/lib.rs
  • baml_language/rig_tests/crates/.gitignore
  • baml_language/rig_tests/crates/type_shapes/Cargo.toml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases_consumer/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_class_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_enums/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_forward_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_generics/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_ipsum/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lists/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_literals/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/cross_uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/streams.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_maps/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_media/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_optional/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_primitives/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_recursion/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_unions/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_void/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/root.baml
  • baml_language/rig_tests/crates/type_shapes/build.rs
  • baml_language/rig_tests/crates/type_shapes/customizable/test_main.py
  • baml_language/rig_tests/crates/type_shapes/src/lib.rs
✅ Files skipped from review due to trivial changes (18)
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/root.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/cross_uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_ipsum/uses.baml
  • baml_language/rig_tests/crates/type_shapes/Cargo.toml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_enums/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_class_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases/types.baml
  • baml_language/rig_tests/crates/type_shapes/customizable/test_main.py
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases_consumer/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_maps/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lists/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_literals/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_primitives/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_media/types.baml
🚧 Files skipped from review as they are similar to previous changes (9)
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_void/types.baml
  • baml_language/rig_tests/crates/type_shapes/src/lib.rs
  • baml_language/rig_tests/crates/.gitignore
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_optional/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_unions/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_forward_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/streams.baml
  • baml_language/rig_tests/crates/type_shapes/build.rs
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_recursion/types.baml

Comment thread baml_language/languages/python/rust/codegen_python/src/leaf.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
baml_language/languages/python/rust/codegen_python/src/translate_ty.rs (1)

174-195: ⚡ Quick win

Add unit tests for the quote_same_leaf_refs: true code path.

All test constructors set quote_same_leaf_refs: false, leaving the new Ty::Enum quoting branch (lines 62–69) and the should_quote_same_leaf guard in render_name_ref_or_self_ref (line 118) completely untested within this file. Per the coding guidelines, Rust unit tests are preferred over integration-only coverage.

At minimum, the following cases should be added:

🧪 Suggested test cases to add to translate_ty_covers_phase_g3_matrix
// Helper (add alongside ctx / ctx_with_self)
fn ctx_quoting(segments: &[&str]) -> TranslateCtx {
    TranslateCtx {
        current_leaf: leaf(segments),
        self_ref: None,
        quote_same_leaf_refs: true,
    }
}

// New cases:
Case {
    label: "enum same-leaf quoted when quote_same_leaf_refs",
    ty: Ty::Enum(name("user", &["ipsum"], "Sentiment")),
    ctx: ctx_quoting(&["ipsum"]),
    expected: "\"Sentiment\"",
},
Case {
    label: "enum cross-leaf not quoted when quote_same_leaf_refs",
    ty: Ty::Enum(name("user", &["ipsum"], "Sentiment")),
    ctx: ctx_quoting(&["lorem"]),
    expected: "ipsum.Sentiment",
},
Case {
    label: "class same-leaf quoted when quote_same_leaf_refs (no self_ref)",
    ty: Ty::Class(name("user", &["lorem"], "Resume"), vec![]),
    ctx: ctx_quoting(&["lorem"]),
    expected: "\"Resume\"",
},
Case {
    label: "type alias same-leaf quoted when quote_same_leaf_refs",
    ty: Ty::TypeAlias(name("user", &["util"], "StringList")),
    ctx: ctx_quoting(&["util"]),
    expected: "\"StringList\"",
},

As per coding guidelines: "Prefer writing Rust unit tests over integration tests where possible."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/languages/python/rust/codegen_python/src/translate_ty.rs`
around lines 174 - 195, Add unit tests exercising the quote_same_leaf_refs =
true path by adding a helper ctor (e.g., ctx_quoting) that returns TranslateCtx
with quote_same_leaf_refs: true and then extend
translate_ty_covers_phase_g3_matrix with the suggested cases: ensure Ty::Enum
with current_leaf equal to the enum's leaf yields a quoted name, with different
leaf yields fully-qualified name, and similarly add same-leaf quoted cases for
Ty::Class and Ty::TypeAlias (no self_ref). Update tests to reference the
existing helper functions leaf, name and the ctx/ctx_with_self patterns and
assert outputs from the code paths in render_name_ref_or_self_ref and the
Ty::Enum quoting branch.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@baml_language/languages/python/rust/codegen_python/src/translate_ty.rs`:
- Around line 174-195: Add unit tests exercising the quote_same_leaf_refs = true
path by adding a helper ctor (e.g., ctx_quoting) that returns TranslateCtx with
quote_same_leaf_refs: true and then extend translate_ty_covers_phase_g3_matrix
with the suggested cases: ensure Ty::Enum with current_leaf equal to the enum's
leaf yields a quoted name, with different leaf yields fully-qualified name, and
similarly add same-leaf quoted cases for Ty::Class and Ty::TypeAlias (no
self_ref). Update tests to reference the existing helper functions leaf, name
and the ctx/ctx_with_self patterns and assert outputs from the code paths in
render_name_ref_or_self_ref and the Ty::Enum quoting branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1b454250-d450-4c87-8a58-4da780b4be95

📥 Commits

Reviewing files that changed from the base of the PR and between 7c6ba12 and cc96629.

⛔ Files ignored due to path filters (9)
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/_inlinedbaml.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/forward_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/forward_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/forward_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/forward_refs/__init__.pyi is excluded by !**/generated/**
📒 Files selected for processing (5)
  • baml_language/languages/python/rust/codegen_python/src/emit/type_alias.rs
  • baml_language/languages/python/rust/codegen_python/src/leaf.rs
  • baml_language/languages/python/rust/codegen_python/src/lib.rs
  • baml_language/languages/python/rust/codegen_python/src/translate_ty.rs
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases/types.baml
✅ Files skipped from review due to trivial changes (1)
  • baml_language/languages/python/rust/codegen_python/src/emit/type_alias.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases/types.baml
  • baml_language/languages/python/rust/codegen_python/src/leaf.rs
  • baml_language/languages/python/rust/codegen_python/src/lib.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
baml_language/languages/python/rust/codegen_python/src/translate_ty.rs (1)

155-743: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add unit tests covering quote_same_leaf_refs: true.

Every unit test uses ctx() or ctx_with_self(), both of which hard-code quote_same_leaf_refs: false. The new should_quote_same_leaf predicate — including the Ty::Enum same-leaf quoting path, the Ty::Class same-leaf non-self-ref quoting, and the cross-leaf / root-namespace boundary behaviour — has zero unit-test coverage in this module. The coding guidelines require preferring Rust unit tests over integration tests.

At minimum, a helper and a few cases would close the gap:

🧪 Suggested unit test additions
+    fn ctx_quoting(segments: &[&str]) -> TranslateCtx {
+        TranslateCtx {
+            current_leaf: leaf(segments),
+            self_ref: None,
+            quote_same_leaf_refs: true,
+        }
+    }

Additional Case entries inside translate_ty_covers_phase_g3_matrix:

+            Case {
+                label: "quote_same_leaf: enum same leaf is quoted",
+                ty: Ty::Enum(name("user", &["ipsum"], "Sentiment")),
+                ctx: ctx_quoting(&["ipsum"]),
+                expected: "\"Sentiment\"",
+            },
+            Case {
+                label: "quote_same_leaf: enum cross leaf is not quoted",
+                ty: Ty::Enum(name("user", &["ipsum"], "Sentiment")),
+                ctx: ctx_quoting(&["lorem"]),
+                expected: "ipsum.Sentiment",
+            },
+            Case {
+                label: "quote_same_leaf: class same leaf is quoted",
+                ty: Ty::Class(name("user", &["util"], "Other"), vec![]),
+                ctx: ctx_quoting(&["util"]),
+                expected: "\"Other\"",
+            },
+            Case {
+                label: "quote_same_leaf: type alias same leaf is quoted",
+                ty: Ty::TypeAlias(name("user", &["util"], "Alias")),
+                ctx: ctx_quoting(&["util"]),
+                expected: "\"Alias\"",
+            },
+            Case {
+                label: "quote_same_leaf: type alias cross leaf is not quoted",
+                ty: Ty::TypeAlias(name("user", &["util"], "Alias")),
+                ctx: ctx_quoting(&["lorem"]),
+                expected: "util.Alias",
+            },
+            Case {
+                label: "quote_same_leaf: root-namespace class is quoted",
+                ty: Ty::Class(name("user", &[], "Foo"), vec![]),
+                ctx: ctx_quoting(&["lorem"]),
+                expected: "\"Foo\"",
+            },

As per coding guidelines: "Prefer writing Rust unit tests over integration tests where possible."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/languages/python/rust/codegen_python/src/translate_ty.rs`
around lines 155 - 743, Add unit tests that exercise the should_quote_same_leaf
behavior by creating new TranslateCtx helpers that set quote_same_leaf_refs:
true (e.g., a ctx_quote_same(…) and ctx_with_self_quote(…) mirroring ctx() and
ctx_with_self()), then add Case entries in translate_ty_covers_phase_g3_matrix
covering: Ty::Enum same-leaf quoting, Ty::Class same-leaf non-self-ref quoting,
and cross-leaf/root-namespace boundary cases that exercise stream and vendor
paths; use translate_ty and assert_ty as existing tests do so the new cases
validate the should_quote_same_leaf predicate and related paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@baml_language/languages/python/rust/codegen_python/src/translate_ty.rs`:
- Around line 155-743: Add unit tests that exercise the should_quote_same_leaf
behavior by creating new TranslateCtx helpers that set quote_same_leaf_refs:
true (e.g., a ctx_quote_same(…) and ctx_with_self_quote(…) mirroring ctx() and
ctx_with_self()), then add Case entries in translate_ty_covers_phase_g3_matrix
covering: Ty::Enum same-leaf quoting, Ty::Class same-leaf non-self-ref quoting,
and cross-leaf/root-namespace boundary cases that exercise stream and vendor
paths; use translate_ty and assert_ty as existing tests do so the new cases
validate the should_quote_same_leaf predicate and related paths.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c1a49a14-2725-4e75-8481-8d1e176922eb

📥 Commits

Reviewing files that changed from the base of the PR and between 436b11a and 6294968.

⛔ Files ignored due to path filters (127)
  • baml_language/Cargo.lock is excluded by !**/*.lock
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/b/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/a/b/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases_consumer/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/aliases_consumer/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/_inlinedbaml.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/errors/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/errors/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/fs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/fs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/glob/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/glob/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/http/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/http/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/llm/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/llm/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/net/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/net/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/panics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/panics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/stream/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/stream/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/sys/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/baml/sys/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/class_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/class_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/enums/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/enums/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/forward_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/forward_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/generics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/generics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lists/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lists/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/literals/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/literals/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lorem/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/lorem/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/maps/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/maps/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/optional/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/optional/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/primitives/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/primitives/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/py.typed is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/recursion/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/recursion/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/b/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/a/b/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases_consumer/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/aliases_consumer/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/errors/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/errors/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/fs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/fs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/glob/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/glob/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/http/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/http/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/llm/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/llm/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/net/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/net/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/panics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/panics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/stream/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/stream/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/sys/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/baml/sys/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/class_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/class_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/enums/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/enums/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/forward_refs/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/forward_refs/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/generics/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/generics/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lists/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lists/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/literals/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/literals/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lorem/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/lorem/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/maps/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/maps/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/media/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/media/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/optional/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/optional/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/primitives/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/primitives/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/recursion/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/recursion/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/unions/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/unions/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/testing/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/stream_types/vendor/testing/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/unions/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/unions/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/__init__.pyi is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/testing/__init__.py is excluded by !**/generated/**
  • baml_language/rig_tests/crates/type_shapes/generated/baml_sdk/vendor/testing/__init__.pyi is excluded by !**/generated/**
📒 Files selected for processing (34)
  • .pre-commit-config.yaml
  • baml_language/languages/python/rust/codegen_python/src/emit/type_alias.rs
  • baml_language/languages/python/rust/codegen_python/src/leaf.rs
  • baml_language/languages/python/rust/codegen_python/src/lib.rs
  • baml_language/languages/python/rust/codegen_python/src/translate_ty.rs
  • baml_language/rig_tests/crates/.gitignore
  • baml_language/rig_tests/crates/type_shapes/Cargo.toml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases_consumer/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_class_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_enums/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_forward_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_generics/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_ipsum/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lists/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_literals/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/cross_uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/streams.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_maps/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_media/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_optional/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_primitives/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_recursion/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_unions/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_void/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/root.baml
  • baml_language/rig_tests/crates/type_shapes/build.rs
  • baml_language/rig_tests/crates/type_shapes/customizable/test_main.py
  • baml_language/rig_tests/crates/type_shapes/src/lib.rs
✅ Files skipped from review due to trivial changes (18)
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_ipsum/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/uses.baml
  • baml_language/rig_tests/crates/type_shapes/Cargo.toml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_class_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_optional/types.baml
  • baml_language/languages/python/rust/codegen_python/src/emit/type_alias.rs
  • baml_language/rig_tests/crates/type_shapes/baml_src/root.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lists/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_enums/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_literals/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/streams.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_unions/types.baml
  • baml_language/rig_tests/crates/.gitignore
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases_consumer/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_maps/types.baml
🚧 Files skipped from review as they are similar to previous changes (13)
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/cross_uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_void/types.baml
  • baml_language/rig_tests/crates/type_shapes/src/lib.rs
  • baml_language/rig_tests/crates/type_shapes/customizable/test_main.py
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_forward_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_media/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_primitives/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_recursion/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_generics/types.baml
  • baml_language/languages/python/rust/codegen_python/src/lib.rs
  • baml_language/languages/python/rust/codegen_python/src/leaf.rs

@sxlijin
sxlijin dismissed coderabbitai[bot]’s stale review May 7, 2026 04:41

all of these issues are pre-existing

@sxlijin
sxlijin added this pull request to the merge queue May 7, 2026
@antoniosarosi
antoniosarosi removed this pull request from the merge queue due to a manual request May 7, 2026
@antoniosarosi
antoniosarosi added this pull request to the merge queue May 7, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 7, 2026
@sxlijin
sxlijin added this pull request to the merge queue May 7, 2026
@sxlijin
sxlijin removed this pull request from the merge queue due to a manual request May 7, 2026
coderabbitai[bot]
coderabbitai Bot previously requested changes May 7, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@baml_language/languages/python/rust/codegen_python/src/leaf.rs`:
- Around line 691-708: render_type_alias currently only quotes same-leaf name
references via TranslateCtx.quote_same_leaf_refs when a.recursive is true,
leaving cross-leaf references (e.g., util.Bar) as bare names that rely on
TYPE_CHECKING-only imports and thus fail at runtime when TypeAliasType evaluates
its RHS; update render_type_alias so that for recursive aliases (a.recursive)
any cross-leaf routed names are either emitted as quoted forward-ref strings in
the RHS or cause their modules to be imported at runtime (not only under if
typing.TYPE_CHECKING) — adjust TranslateCtx construction or the quoting logic
that uses quote_same_leaf_refs to detect routed_leaf != current_leaf and quote
those names (or flip their imports out of TYPE_CHECKING) so TypeAliasType("...",
...) has all names resolvable at module load time.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3776e41f-72c5-4b08-9c52-d1e9623e10ba

📥 Commits

Reviewing files that changed from the base of the PR and between b29970d and 2c6fb4e.

📒 Files selected for processing (2)
  • baml_language/languages/python/rust/codegen_python/src/leaf.rs
  • baml_language/languages/python/rust/codegen_python/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • baml_language/languages/python/rust/codegen_python/src/lib.rs

Comment thread baml_language/languages/python/rust/codegen_python/src/leaf.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
baml_language/languages/python/rust/codegen_python/src/leaf.rs (1)

715-720: ⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

Recursive aliases can still fail at import time when RHS uses cross-leaf/root names.

At Line 719, recursive alias rendering only enables same-leaf quoting. Cross-leaf/root references can remain bare in TypeAliasType RHS, but Lines 897-908 place those imports under typing.TYPE_CHECKING. Because TypeAliasType(...) evaluates RHS at module import time, this can still raise NameError in .py for recursive aliases that reference routed names.

#!/bin/bash
set -euo pipefail

# Verify recursive alias rendering path and quoting scope in codegen.
rg -n -C3 'TypeAliasType\(|quote_same_leaf_refs:\s*a\.recursive|if typing\.TYPE_CHECKING:' \
  baml_language/languages/python/rust/codegen_python/src/leaf.rs \
  baml_language/languages/python/rust/codegen_python/src/translate_ty.rs

# Inspect checked-in generated SDKs for recursive aliases whose RHS includes bare dotted names.
# Expected: either those refs are quoted, or corresponding imports are runtime-available.
fd -t d '^baml_sdk$' . | while read -r sdk_dir; do
  fd -t f -e py . "$sdk_dir" | while read -r py_file; do
    rg -n 'TypeAliasType\(' "$py_file" >/dev/null || continue
    echo "=== $py_file ==="
    rg -n -C3 'TypeAliasType\(|if typing\.TYPE_CHECKING:|^\s+from \.+ import ' "$py_file"
    echo
  done
done

Also applies to: 897-908


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 118287bc-038a-41b7-bec7-3f75bba1b0fc

📥 Commits

Reviewing files that changed from the base of the PR and between 2c6fb4e and 18f118d.

📒 Files selected for processing (2)
  • baml_language/languages/python/rust/codegen_python/src/leaf.rs
  • baml_language/languages/python/rust/codegen_python/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • baml_language/languages/python/rust/codegen_python/src/lib.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
baml_language/languages/python/rust/codegen_python/src/lib.rs (1)

2389-2413: ⚡ Quick win

Also assert no root self-import in __init__.pyi.

This test currently verifies only __init__.py. Adding the same guard for __init__.pyi keeps .py/.pyi invariants locked together.

Suggested test addition
         let out = to_source_code(&pool, &[]);
         let py = &out[&PathBuf::from("__init__.py")];
         assert!(
             !py.contains("from . import Foo") && !py.contains("from .. import Foo"),
             "root leaf should not import its own Foo:\n{py}"
         );
+        let pyi = &out[&PathBuf::from("__init__.pyi")];
+        assert!(
+            !pyi.contains("from . import Foo") && !pyi.contains("from .. import Foo"),
+            "root leaf stub should not import its own Foo:\n{pyi}"
+        );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/languages/python/rust/codegen_python/src/lib.rs` around lines
2389 - 2413, In the test root_leaf_does_not_self_import_root_types add the same
negative import assertion for the generated stub file: after obtaining
out[&PathBuf::from("__init__.py")] (variable py) also retrieve
out[&PathBuf::from("__init__.pyi")] (e.g., pyi) and assert that neither "from .
import Foo" nor "from .. import Foo" appear in pyi, mirroring the existing
assert for py so the .py and .pyi outputs stay consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@baml_language/languages/python/rust/codegen_python/src/lib.rs`:
- Around line 2389-2413: In the test root_leaf_does_not_self_import_root_types
add the same negative import assertion for the generated stub file: after
obtaining out[&PathBuf::from("__init__.py")] (variable py) also retrieve
out[&PathBuf::from("__init__.pyi")] (e.g., pyi) and assert that neither "from .
import Foo" nor "from .. import Foo" appear in pyi, mirroring the existing
assert for py so the .py and .pyi outputs stay consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 70c3f867-bfca-4ee2-9cf8-4c480caea380

📥 Commits

Reviewing files that changed from the base of the PR and between 18f118d and 18bae30.

📒 Files selected for processing (2)
  • baml_language/languages/python/rust/codegen_python/src/leaf.rs
  • baml_language/languages/python/rust/codegen_python/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • baml_language/languages/python/rust/codegen_python/src/leaf.rs

@sxlijin
sxlijin dismissed coderabbitai[bot]’s stale review May 7, 2026 09:24

preexisting issues

@sxlijin
sxlijin added this pull request to the merge queue May 7, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 7, 2026
sxlijin added 6 commits May 7, 2026 03:01
New rig_tests crate that exercises every type variant and routing rule
from bridge-python/18a-type-exhaustiveness.md. Generated baml_sdk/ is
checked into VCS so reviewers can diff codegen output directly.

Failures discovered while authoring the BAML source are recorded in
18b-type-exhaustiveness-failures.md (cross-namespace user-package refs,
$rust_type gating, pure-expression functions not emitting Python,
recursive-alias-before-class pydantic recursion, generic-class stream
companion losing type params, and others).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
baml_language/rig_tests/crates/type_shapes/build.rs (2)

101-108: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add Windows symlink fallback to file copy.

symlink_file commonly fails without elevated privileges/Developer Mode on Windows. Falling back to fs::copy avoids unnecessary build failures in CI/local environments.

Proposed fix
 #[cfg(windows)]
-std::os::windows::fs::symlink_file(&src, &dst).unwrap_or_else(|_| {
-    panic!(
-        "Failed to symlink {} from {}",
-        file_name.to_string_lossy(),
-        src.display()
-    )
-});
+if let Err(err) = std::os::windows::fs::symlink_file(&src, &dst) {
+    fs::copy(&src, &dst).unwrap_or_else(|copy_err| {
+        panic!(
+            "Failed to materialize {} from {} to {}: symlink failed with {err}; copy failed with {copy_err}",
+            file_name.to_string_lossy(),
+            src.display(),
+            dst.display()
+        )
+    });
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/rig_tests/crates/type_shapes/build.rs` around lines 101 - 108,
symlink_file on Windows (used in build.rs around
std::os::windows::fs::symlink_file(&src, &dst)) can fail without admin/DevMode;
update the unwrap_or_else panic fallback to attempt a plain fs::copy(&src, &dst)
when symlink creation fails (using src, dst and file_name to log any error) and
only panic if both symlink and copy fail, ensuring the error messages include
the underlying IO error for easier debugging.

215-226: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Watch source directories themselves in addition to files.

Right now only current files are registered. Registering the directory paths too makes rebuild triggering more reliable when new files are added.

#!/bin/bash
# Verify current build.rs only emits rerun-if-changed for files from walk_dir,
# and does not emit directory paths for baml_src/customizable.
rg -n 'cargo:rerun-if-changed|watch_dir\(' baml_language/rig_tests/crates/type_shapes/build.rs
Proposed fix
 println!("cargo:rerun-if-changed=build.rs");
+println!("cargo:rerun-if-changed={}", baml_src.display());
 watch_dir(&baml_src);
 if customizable_dir.exists() {
+    println!("cargo:rerun-if-changed={}", customizable_dir.display());
     watch_dir(&customizable_dir);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/rig_tests/crates/type_shapes/build.rs` around lines 215 - 226,
The build script currently only emits "cargo:rerun-if-changed" for individual
files from walk_files but not for the watched directories themselves; update the
logic so the directory paths are also emitted (e.g., before iterating files) so
new files trigger rebuilds—modify the call sites (watch_dir(&baml_src) and the
conditional watch_dir(&customizable_dir)) or the watch_dir function itself to
print a cargo:rerun-if-changed line for the directory (using the same println
pattern as println!("cargo:rerun-if-changed={}", path.display())) in addition to
emitting for each file returned by walk_files.
🧹 Nitpick comments (1)
baml_language/rig_tests/crates/type_shapes/customizable/test_main.py (1)

21-26: ⚡ Quick win

Assert the intentionally absent void namespace explicitly.

Since the comments document void as intentionally absent, add a negative assertion to lock that behavior (assert not hasattr(baml_sdk, "void")) and catch accidental generator regressions early.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/rig_tests/crates/type_shapes/customizable/test_main.py` around
lines 21 - 26, Add an explicit negative assertion for the intentionally absent
`void` namespace to detect regressions: in test_main.py near the comment about
`void` being intentionally absent, insert an assertion such as asserting not
hasattr(baml_sdk, "void") (or equivalent) before or within the loop over
namespaces so the test will fail if `baml_sdk.void` is ever generated; reference
the `baml_sdk` symbol and the explanatory comment as the insertion point.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@baml_language/rig_tests/crates/type_shapes/build.rs`:
- Around line 101-108: symlink_file on Windows (used in build.rs around
std::os::windows::fs::symlink_file(&src, &dst)) can fail without admin/DevMode;
update the unwrap_or_else panic fallback to attempt a plain fs::copy(&src, &dst)
when symlink creation fails (using src, dst and file_name to log any error) and
only panic if both symlink and copy fail, ensuring the error messages include
the underlying IO error for easier debugging.
- Around line 215-226: The build script currently only emits
"cargo:rerun-if-changed" for individual files from walk_files but not for the
watched directories themselves; update the logic so the directory paths are also
emitted (e.g., before iterating files) so new files trigger rebuilds—modify the
call sites (watch_dir(&baml_src) and the conditional
watch_dir(&customizable_dir)) or the watch_dir function itself to print a
cargo:rerun-if-changed line for the directory (using the same println pattern as
println!("cargo:rerun-if-changed={}", path.display())) in addition to emitting
for each file returned by walk_files.

---

Nitpick comments:
In `@baml_language/rig_tests/crates/type_shapes/customizable/test_main.py`:
- Around line 21-26: Add an explicit negative assertion for the intentionally
absent `void` namespace to detect regressions: in test_main.py near the comment
about `void` being intentionally absent, insert an assertion such as asserting
not hasattr(baml_sdk, "void") (or equivalent) before or within the loop over
namespaces so the test will fail if `baml_sdk.void` is ever generated; reference
the `baml_sdk` symbol and the explanatory comment as the insertion point.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 035d7180-a35c-40a7-ad20-24162cf92cde

📥 Commits

Reviewing files that changed from the base of the PR and between 8798e4e and c7ef019.

⛔ Files ignored due to path filters (1)
  • baml_language/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (33)
  • baml_language/languages/python/rust/codegen_python/src/emit/type_alias.rs
  • baml_language/languages/python/rust/codegen_python/src/leaf.rs
  • baml_language/languages/python/rust/codegen_python/src/lib.rs
  • baml_language/languages/python/rust/codegen_python/src/translate_ty.rs
  • baml_language/rig_tests/crates/.gitignore
  • baml_language/rig_tests/crates/type_shapes/Cargo.toml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases_consumer/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_class_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_enums/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_forward_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_generics/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_ipsum/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lists/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_literals/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/cross_uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/streams.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_maps/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_media/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_optional/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_primitives/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_recursion/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_unions/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_void/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/root.baml
  • baml_language/rig_tests/crates/type_shapes/build.rs
  • baml_language/rig_tests/crates/type_shapes/customizable/test_main.py
  • baml_language/rig_tests/crates/type_shapes/src/lib.rs
✅ Files skipped from review due to trivial changes (18)
  • baml_language/rig_tests/crates/.gitignore
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_void/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/cross_uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/root.baml
  • baml_language/rig_tests/crates/type_shapes/Cargo.toml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_class_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_enums/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lists/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_literals/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_optional/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_unions/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_maps/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_primitives/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_generics/types.baml
🚧 Files skipped from review as they are similar to previous changes (11)
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/ns_b/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_ipsum/uses.baml
  • baml_language/rig_tests/crates/type_shapes/src/lib.rs
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_a/uses.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_aliases_consumer/uses.baml
  • baml_language/languages/python/rust/codegen_python/src/lib.rs
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_media/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_forward_refs/types.baml
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_recursion/types.baml
  • baml_language/languages/python/rust/codegen_python/src/leaf.rs
  • baml_language/rig_tests/crates/type_shapes/baml_src/ns_lorem/streams.baml

@sxlijin
sxlijin added this pull request to the merge queue May 7, 2026
Merged via the queue into canary with commit 77ab850 May 7, 2026
43 checks passed
@sxlijin
sxlijin deleted the sam/type-shapes-rig branch May 7, 2026 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant