Skip to content

Reparent string constraints under PatternConstraint + test improvements#458

Open
Seth Fitzsimmons (mojodna) wants to merge 4 commits intodevfrom
pattern-constraints
Open

Reparent string constraints under PatternConstraint + test improvements#458
Seth Fitzsimmons (mojodna) wants to merge 4 commits intodevfrom
pattern-constraints

Conversation

@mojodna
Copy link
Collaborator

@mojodna Seth Fitzsimmons (mojodna) commented Mar 4, 2026

Summary

  • Reparent 8 StringConstraint subclasses (CountryCodeAlpha2, HexColor, LanguageTag, NoWhitespace, SnakeCase, PhoneNumber, RegionCode, WikidataId) under PatternConstraint as thin __init__-only wrappers
  • Enrich PatternConstraint with optional description, min_length, max_length keyword parameters for JSON Schema annotations
  • Extract _raise_validation_error() helper on StringConstraint to deduplicate error construction across PatternConstraint, JsonPointerConstraint, and StrippedConstraint
  • Fix StrippedConstraint JSON schema pattern to accept empty string (matching Python validator behavior)
  • Strengthen weak test assertions to check error messages, not just error presence
  • Parametrize PatternConstraint subclass tests: 16 individual methods → two data-driven tests covering all 8 subclasses

-285 net lines across constraints and tests. Enables isinstance-based dispatch for pattern constraints in downstream codegen.

JsonPointerConstraint and StrippedConstraint remain as direct StringConstraint subclasses (non-regex validation logic).

Test plan

  • Existing validation and JSON schema tests pass (behavioral safety net)
  • isinstance parametrized test confirms all 8 subclasses are PatternConstraint instances
  • Tests verify PatternConstraint kwargs emit/omit JSON Schema annotations correctly
  • StrippedConstraint empty-string acceptance tested against both validator and JSON schema pattern
  • make check passes

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is fantastic, especially the:

Net -112 lines.

And also the:

Enables isinstance-based dispatch for pattern constraints in downstream codegen.

Would you mind humoring me with the numpy-style docs? I was so close to getting it all on numpy.

Eliminates duplicated validate() and __get_pydantic_json_schema__()
across CountryCodeAlpha2, HexColor, LanguageTag, NoWhitespace,
SnakeCase, PhoneNumber, RegionCode, and WikidataId constraints.
Each is now a thin __init__-only wrapper calling super().__init__().

PatternConstraint gains optional keyword-only description, min_length,
max_length parameters for JSON Schema annotations. StringConstraint
gains _raise_validation_error() to deduplicate error construction
across PatternConstraint, JsonPointerConstraint, and
StrippedConstraint.
The previous pattern ^(\S.*)?\S$ required at least one non-whitespace
character, rejecting empty string. The validator itself accepts empty
string ("" == "".strip()), so the JSON schema was more restrictive
than the Python validation.

New pattern ^(\S(.*\S)?)?$ matches empty string (outer group optional),
single non-whitespace chars, and strings bookended by non-whitespace.

Updated all JSON schema baselines and inline expectations.
Replace `len(errors()) > 0` with error message assertions in
hex color and no-whitespace invalid tests. The weak assertions
only checked that validation failed, not that the correct error
was raised.
Replace 16 individual valid/invalid test methods with two parametrized
tests driven by PATTERN_CONSTRAINT_CASES. Covers all 8 PatternConstraint
subclasses: LanguageTag, CountryCodeAlpha2, RegionCode, WikidataId,
PhoneNumber, HexColor, NoWhitespace, SnakeCase.

Moved SnakeCaseConstraint tests from TestErrorHandling (where they were
misplaced) into the parametrized data.

Non-PatternConstraint tests remain as standalone methods: base
PatternConstraint (custom pattern), StrippedConstraint, and
JsonPointerConstraint (empty-string special case).
@mojodna Seth Fitzsimmons (mojodna) changed the title Reparent 8 string constraints under PatternConstraint Reparent string constraints under PatternConstraint + test improvements Mar 5, 2026
@mojodna
Copy link
Collaborator Author

Now -285 net lines after I found some more things to simplify.

I also fixed a JSON Schema validation bug with StrippedString--its behavior differed from Pydantic's validate().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants