Nimblesite / Nimblesite/Basilisk
directives_cast rejects legal string forward refs (conflicts with ruff TC006) and only fires on assignment RHS
@MelbourneDeveloper is already working on this.
Since Aug 2, 2026.
- Dominant language
- Rust
- Stars
- 54
- Forks
- 3
- PR merge metrics
- No merged PRs in 30d
Description
Summary
Two problems with directives_cast:
- It rejects string forward references as
cast()'s first argument, which PEP 484 and typeshed explicitly permit. - It only fires when the
cast()call is the right-hand side of an assignment. In every other syntactic position it is silently not checked.
Together these make the rule both wrong and unevenly applied — and (1) puts Basilisk in direct, unsatisfiable conflict with ruff's TC006.
Problem 1 — string forward references are legal
typeshed's own signature admits str:
def cast(typ: type[_T] | str | Any, val: Any) -> _T: ...
Every quoted form is rejected:
from typing import cast
from uuid import UUID
class Local: ...
a = cast("UUID", object()) # error[directives_cast]
b = cast("Local", object()) # error
c = cast("int", 1) # error
d = cast("str", "x") # error
e = cast("dict[str, str]", {}) # error
f = cast("tuple[int, bytes]", (1, b"")) # error
g = cast(int, 1) # OK — only the unquoted form passes
Found 6 diagnostics (6 errors).
The message — "must be a type, not a value literal" — suggests the intent was to catch cast(1, x) or cast("some string value", x). A quoted type expression is not a value literal; it is the standard forward-reference spelling.
Unsatisfiable conflict with ruff
ruff's TC006 (runtime-cast-value) enforces the exact opposite and is in ruff's ALL set:
TC006 Add quotes to type expression in `typing.cast()`
A project running Basilisk + ruff (as Basilisk's own docs encourage, and as make lint does here) cannot satisfy both. Quoting satisfies ruff and fails Basilisk; unquoting satisfies Basilisk and fails ruff. The only escapes are a suppression in one tool or restructuring the code to avoid cast entirely — which is what we did:
# was: _, stdout, _ = cast("tuple[int, bytes, bytes]", raw)
raw: tuple[int, bytes, bytes] = Git().execute(..., with_extended_output=True)
_, stdout, _ = raw
Problem 2 — the rule only sees assignment RHS
from typing import cast
def sink(x: object, y: object = None) -> None: ...
assigned = cast("int", 1) # line 8 — FLAGGED
sink(cast("int", 1)) # line 9 — not flagged
sink(x=cast("int", 1)) # line 10 — not flagged
sink(cast("int", 1), y=cast("str", "a")) # line 11 — not flagged
def ret() -> int:
return cast("int", 1) # line 15 — not flagged
--> _castpos.py:8:17
Found 1 diagnostic (1 error).
Only the assignment is reported. This is how it presents in the wild: the Nimblesite Agentic Platform has 19 quoted cast() calls and basilisk check passes clean, because 18 of them sit in keyword-argument or return position:
src/nap/agent_workspace/host.py:517 agent_config_id=cast("UUID", kwargs["agent_config_id"]), # not flagged
src/nap/core/tool_content.py:115 return cast("ToolResultContent", raw) # not flagged
workspaces/.../git_http_server.py:129 _, stdout, _ = cast("tuple[...]", raw) # FLAGGED
One file out of the set errors, purely because of where the call sits. That reads as a random false positive to a user and makes the rule's real blast radius invisible until code is refactored.
Expected
- Accept
strascast()'s first argument, resolving it as a forward reference (and ideally validate that the string parses as a type expression, which would catch the genuinecast("hello", x)mistake). - Whatever the decision on (1), apply the rule uniformly across all expression positions.
- If quoted casts are to stay rejected, that conflict with ruff
TC006should be documented, because the two cannot both be satisfied.
Version
Reproduced identically on released basilisk 0.35.0 (Homebrew) and on 0.0.0-PLACEHOLDER built from typeshed @ 9ada1f77 (2026-07-21).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.