mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-19 03:54:18 +02:00
fix(json_schema): keep min/maxLength when format falls back to str
_create_string_type returned early for any format, dropping minLength, maxLength, and pattern even when the format resolves to a plain str (custom formats / uri-reference). Fixes #4404
This commit is contained in:
parent
875e8e18bd
commit
578bc73f12
2 changed files with 35 additions and 8 deletions
|
|
@ -269,13 +269,6 @@ def _create_string_type(schema: Mapping[str, Any]) -> type | Annotated[Any, ...]
|
|||
if "const" in schema:
|
||||
return Literal[schema["const"]] # type: ignore
|
||||
|
||||
if fmt := schema.get("format"):
|
||||
if fmt == "uri":
|
||||
return AnyUrl
|
||||
elif fmt == "uri-reference":
|
||||
return str
|
||||
return FORMAT_TYPES.get(fmt, str)
|
||||
|
||||
constraints = {
|
||||
k: v
|
||||
for k, v in {
|
||||
|
|
@ -286,7 +279,22 @@ def _create_string_type(schema: Mapping[str, Any]) -> type | Annotated[Any, ...]
|
|||
if v is not None
|
||||
}
|
||||
|
||||
if not constraints:
|
||||
# Resolve format first. Non-str formats (date-time, email, uri, json) do not
|
||||
# take length/pattern constraints. Str-backed formats (unknown custom names
|
||||
# and uri-reference) must still honor minLength/maxLength/pattern.
|
||||
if fmt := schema.get("format"):
|
||||
if fmt == "uri":
|
||||
return AnyUrl
|
||||
if fmt == "uri-reference":
|
||||
base: type | Annotated[Any, ...] = str
|
||||
else:
|
||||
base = FORMAT_TYPES.get(fmt, str)
|
||||
if base is not str:
|
||||
return base
|
||||
if not constraints:
|
||||
return str
|
||||
# Fall through to apply StringConstraints on the str-backed format.
|
||||
elif not constraints:
|
||||
return str
|
||||
|
||||
annotated: Any = Annotated[str, StringConstraints(**constraints)]
|
||||
|
|
|
|||
|
|
@ -112,3 +112,22 @@ class TestFormatTypes:
|
|||
)
|
||||
assert isinstance(result.full_uri, AnyUrl)
|
||||
assert isinstance(result.ref_uri, str)
|
||||
|
||||
def test_str_backed_format_keeps_max_length(self):
|
||||
"""Unknown/custom formats fall back to str and must still enforce length."""
|
||||
t = json_schema_to_type(
|
||||
{"type": "string", "format": "phone", "maxLength": 3}
|
||||
)
|
||||
validator = TypeAdapter(t)
|
||||
assert validator.validate_python("123") == "123"
|
||||
with pytest.raises(ValidationError):
|
||||
validator.validate_python("abcd")
|
||||
|
||||
def test_uri_reference_format_keeps_min_length(self):
|
||||
t = json_schema_to_type(
|
||||
{"type": "string", "format": "uri-reference", "minLength": 2}
|
||||
)
|
||||
validator = TypeAdapter(t)
|
||||
assert validator.validate_python("/a") == "/a"
|
||||
with pytest.raises(ValidationError):
|
||||
validator.validate_python("")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue