Skip to content

Python#11

Merged
egenn merged 12 commits into
mainfrom
python
Apr 6, 2026
Merged

Python#11
egenn merged 12 commits into
mainfrom
python

Conversation

@egenn
Copy link
Copy Markdown
Member

@egenn egenn commented Apr 6, 2026

No description provided.

Copilot AI review requested due to automatic review settings April 6, 2026 03:36
@egenn egenn merged commit 412b3e3 into main Apr 6, 2026
3 checks passed
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request enhances the Python implementation of the Amino Acid Annotation (A3) format by adding license information, updating project metadata, and refining validation logic. Key improvements include the explicit rejection of boolean values in position fields and more robust error handling that collects multiple validation issues before raising an exception. Tests were updated to reflect these changes, and several dependencies were bumped. Feedback was provided regarding a redundant boolean check in the range normalization logic that is already covered by the Position type validator.

Comment on lines +90 to +91
if isinstance(s, bool) or isinstance(e, bool):
raise ValueError("boolean values are not valid positions")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The check for boolean values here is redundant. The RegionEntry model defines the index field as list[tuple[Position, Position]], and the Position type alias already includes a BeforeValidator(_reject_bool) that handles this check. Since _normalize_ranges is a before validator, Pydantic will subsequently validate its output against the field's type annotation, making this explicit check unnecessary. Relying on the Position type for this validation will make the code more concise and less repetitive.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the Python A3 implementation to tighten validation semantics (especially around booleans and bounds checking), improve error reporting ergonomics, and polish package/repo metadata.

Changes:

  • Add explicit rejection of boolean values where integers are expected (positions/ranges) and improve bounds-check error aggregation.
  • Adjust JSON envelope handling ($schema, a3_version) and update tests accordingly.
  • Refresh package metadata (license, classifiers/URLs) and update docs/badges/lockfile.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
README.md Adds a Crates.io version badge for the Rust crate.
python/rtemis_a3/uv.lock Updates locked tool/dependency versions (e.g., click/ruff/ty/zensical).
python/rtemis_a3/tests/test_models.py Adds boolean-rejection tests; switches bounds tests to the functional API and asserts multi-error behavior.
python/rtemis_a3/tests/test_api.py Updates envelope expectations (defaults + schema/version validation) and adds wrong-schema/version tests.
python/rtemis_a3/src/rtemis/a3/errors.py Expands A3ValidationError docs and adds a messages convenience property.
python/rtemis_a3/src/rtemis/a3/api.py Adds envelope validation and wraps model bounds failures into A3ValidationError.
python/rtemis_a3/src/rtemis/a3/_models.py Introduces _BoundsErrors, adds boolean rejection for positions/ranges, and changes bounds failures to raise _BoundsErrors.
python/rtemis_a3/README.md Updates the wire-format example to include $schema and a3_version.
python/rtemis_a3/pyproject.toml Improves project metadata (description, license, classifiers, URLs).
python/rtemis_a3/LICENSE Adds MPL-2.0 license text to the Python package.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +82 to +84
except _BoundsErrors as exc:
errors = [{"loc": (), "msg": msg, "type": "value_error"} for msg in exc.messages]
raise A3ValidationError("\n".join(exc.messages), errors) from exc
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

_BoundsErrors are converted into A3ValidationError.errors, but the generated entries all use loc=() and omit the offending field path. This makes the structured errors list much less useful for programmatic consumers and also conflicts with the docstring claim that loc contains field-path components. Consider having _BoundsErrors carry structured error objects (with loc tuples), or parse the path prefix in each message into a loc tuple when building errors.

Copilot uses AI. Check for mistakes.
Comment on lines +141 to +143
except _BoundsErrors as exc:
errors = [{"loc": (), "msg": msg, "type": "value_error"} for msg in exc.messages]
raise A3ValidationError("\n".join(exc.messages), errors) from exc
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

Same issue as above: bounds-check violations are mapped to errors entries with loc=(), losing the field path and limiting how callers can present/associate errors. Prefer emitting structured loc tuples for each bounds violation (either by carrying them in _BoundsErrors or deriving them here).

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +24
Structured error list. Each entry has at minimum ``loc`` (tuple of
field path components), ``msg`` (human-readable message), and
``type`` (error kind string). Pydantic structural errors follow
Pydantic's native format; bounds and envelope errors follow the same
shape for consistency.
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

The docstring says bounds errors “follow the same shape” as Pydantic errors with loc as a tuple of field-path components, but bounds violations are currently surfaced with loc=() in api.py. Either adjust the documentation here to reflect the actual structure, or (preferably) emit per-violation loc tuples for bounds errors to match the documented contract.

Suggested change
Structured error list. Each entry has at minimum ``loc`` (tuple of
field path components), ``msg`` (human-readable message), and
``type`` (error kind string). Pydantic structural errors follow
Pydantic's native format; bounds and envelope errors follow the same
shape for consistency.
Structured error list. Each entry has at minimum ``loc`` (a tuple of
field path components, or ``()`` for root-level/non-field-specific
violations), ``msg`` (human-readable message), and ``type`` (error
kind string). Pydantic structural errors follow Pydantic's native
format; contextual errors such as bounds or envelope violations may
use an empty ``loc`` when no specific field path applies.

Copilot uses AI. Check for mistakes.
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.

2 participants