Skip to content

feat(python): read a model's declaration and check rule A (#1386) - #1433

Draft
yujiyokoo wants to merge 2 commits into
feat/python-sdk-eql-markersfrom
feat/python-sdk-declaration-reader
Draft

yujiyokoo wants to merge 2 commits into
feat/python-sdk-eql-markersfrom
feat/python-sdk-declaration-reader

Conversation

@yujiyokoo

Copy link
Copy Markdown
Contributor

Summary

A Python developer marks a class as a model with @stackencrypt.model("users"). The decorator now reads the class's fields when the class is defined. A field without exactly one stash marker raises DeclarationError at the class statement, so the developer sees the mistake where they wrote it.

A stash marker says how a field is stored. TextEq encrypts it, Passthrough stores it as it is, and Ignore leaves it out.

Changes

  • _declaration.py: the model decorator and the field reader.
  • _errors.py: StashError and DeclarationError.
  • Tests for dataclasses, attrs, Pydantic, NamedTuple, and SQLAlchemy classes. Each test runs twice, with and without from __future__ import annotations.
  • pyproject.toml: attrs, Pydantic, and SQLAlchemy join the test extra only. The package itself imports none of them.

Verification

  • mise run test: 113 passed and 2 skipped, on Python 3.14.
  • The same tests on Python 3.9, in a separate environment: 113 passed and 2 skipped.
  • mypy --strict passes. pyright reports 0 errors.
  • pnpm run test:scripts: 83 test files pass.

Related

Closes #1386. Part of #1341.

Review notes

  • DECLARATION_MARKER_NOT_OUTERMOST is a new error code, for a marker in the wrong place, such as Annotated[Mapped[str], TextEq]. The spec's DECLARATION_NOT_OUTERMOST stays for the decorator order. The constructor check in python: declaration meaning — type table, hints, engine check, constructor #1387 finds that.
  • A relationship to a class defined later in the file is refused, because its hint does not resolve yet. The spec accepts this for v1.
  • On Python 3.14 without the future import, Python can fail to read the annotations itself. The error then names the class, not the field.

🤖 Generated with Claude Code

@changeset-bot

changeset-bot Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 2d76b18

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

yujiyokoo and others added 2 commits October 29, 2026 16:03
`@stackencrypt.model("users")` reads a class's fields when the class is
defined. A field without exactly one stash marker raises
`DeclarationError` at the class statement. It works with dataclasses,
attrs, Pydantic, `NamedTuple`, and SQLAlchemy classes.

`DECLARATION_MARKER_NOT_OUTERMOST` is a new error code, for a marker in
the wrong place. The spec's `DECLARATION_NOT_OUTERMOST` moves to #1387.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codes such as `declaration_no_marker` and the reason `rule_a` follow
the amendment on #1341.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@yujiyokoo
yujiyokoo force-pushed the feat/python-sdk-eql-markers branch from 0ebe128 to d777757 Compare October 29, 2026 07:06
@yujiyokoo
yujiyokoo force-pushed the feat/python-sdk-declaration-reader branch from 905205f to 2d76b18 Compare October 29, 2026 07:06

This branch has not been deployed

No deployments
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