Skip to content

Commit 40a2f26

Browse files
authored
fix: Pydantic 2.11.0 compatibility (hotfix) (#106)
#### Relevant issue or PR n/a #### Description of changes - Make tests pass with new pydantic. - Upper bound all runtime dependencies. #### Testing done CI #### License - [x] By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache 2.0 license](https://pasteurlabs.github.io/tesseract/LICENSE). - [x] I sign the Developer Certificate of Origin below by adding my name and email address to the `Signed-off-by` line. <details> <summary><b>Developer Certificate of Origin</b></summary> ```text Developer Certificate of Origin Version 1.1 Copyright (C) 2004, 2006 The Linux Foundation and its contributors. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. ``` </details> Signed-off-by: Dion Häfner <dion.haefner@simulation.science>
1 parent 16163c5 commit 40a2f26

File tree

6 files changed

+30
-27
lines changed

6 files changed

+30
-27
lines changed

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ jinja2==3.1.6
33
typer==0.15.2
44
rich==13.9.4
55
pyyaml==6.0.1
6-
pydantic==2.10.6
6+
pydantic==2.11.0
77
numpy==2.2.4
88
requests==2.32.3
99
pip

tesseract_core/runtime/experimental.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ def serialize(obj: LazySequence, __info: Any) -> Any:
138138
This is not an encouraged use case, but it is supported for completeness.
139139
"""
140140
materialized_sequence = list(obj)
141-
serializer = SchemaSerializer(sequence_of_item_schema)
141+
serializer = SchemaSerializer(sequence_schema)
142+
142143
return serializer.to_python(materialized_sequence, **__info.__dict__)
143144

144145
origin = get_origin(_source_type)
@@ -153,13 +154,11 @@ def serialize(obj: LazySequence, __info: Any) -> Any:
153154
assert len(args) == 1
154155

155156
# Wrap in TypeAdapter so we don't need conditional logic for Python types vs. Pydantic models
156-
_source_type = TypeAdapter(args[0])
157-
158-
item_schema = _source_type.core_schema
159-
sequence_of_item_schema = core_schema.list_schema(item_schema)
157+
item_schema = TypeAdapter(args[0]).core_schema
158+
sequence_schema = _handler(_source_type)
160159

161160
obj_or_path = core_schema.union_schema(
162-
[sequence_of_item_schema, core_schema.str_schema(pattern="^@")]
161+
[sequence_schema, core_schema.str_schema(pattern="^@")]
163162
)
164163
load_schema = core_schema.chain_schema(
165164
# first load data, then validate it with the wrapped schema
@@ -170,7 +169,7 @@ def serialize(obj: LazySequence, __info: Any) -> Any:
170169
serialization=core_schema.plain_serializer_function_ser_schema(
171170
serialize,
172171
info_arg=True,
173-
return_schema=sequence_of_item_schema,
172+
return_schema=sequence_schema,
174173
),
175174
),
176175
]

tesseract_core/runtime/meta/pyproject.toml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ name = "tesseract_runtime"
33
version = "0.1.0"
44
requires-python = ">=3.9"
55
dependencies = [
6-
"pydantic>=2.10",
7-
"fastapi>=0.115",
8-
"requests>=2.32",
9-
"uvicorn>=0.34",
10-
"click>=8.1",
11-
"typer>=0.15",
12-
"fsspec[http,s3]>=2024.12",
13-
"msgpack>=1.1",
14-
"pybase64>=1.4",
15-
"numpy>=1.26",
6+
"pydantic>=2.10,<=2.11.0",
7+
"fastapi>=0.115,<=0.115.12",
8+
"requests>=2.32,<=2.32.3",
9+
"uvicorn>=0.34,<=0.34.0",
10+
"click>=8.1,<=8.1.8",
11+
"typer>=0.15,<=0.15.2",
12+
"fsspec[http,s3]>=2024.12,<=2025.3.0",
13+
"msgpack>=1.1,<=1.1.0",
14+
"pybase64>=1.4,<=1.4.1",
15+
"numpy>=1.26,<=2.2.4",
1616
]
1717

1818
[project.scripts]

tesseract_core/runtime/meta/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pydantic==2.10.6
1+
pydantic==2.11.0
22
fastapi==0.115.12
33
requests==2.32.3
44
uvicorn==0.34.0

tesseract_core/runtime/schema_generation.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -271,13 +271,13 @@ def create_apply_schema(
271271
InputSchema,
272272
lambda x, _: x,
273273
model_prefix="Apply_",
274-
model_kwargs={"model_config": ConfigDict(extra="forbid")},
274+
model_kwargs={"model_config": (ConfigDict, ConfigDict(extra="forbid"))},
275275
)
276276
OutputSchema = apply_function_to_model_tree(
277277
OutputSchema,
278278
lambda x, _: x,
279279
model_prefix="Apply_",
280-
model_kwargs={"model_config": ConfigDict(extra="forbid")},
280+
model_kwargs={"model_config": (ConfigDict, ConfigDict(extra="forbid"))},
281281
)
282282

283283
class ApplyInputSchema(BaseModel):
@@ -325,14 +325,14 @@ def replace_array_with_shapedtype(obj: T, _: Any) -> Union[T, type[ShapeDType]]:
325325
InputSchema,
326326
replace_array_with_shapedtype,
327327
model_prefix="AbstractEval_",
328-
model_kwargs={"model_config": ConfigDict(extra="forbid")},
328+
model_kwargs={"model_config": (ConfigDict, ConfigDict(extra="forbid"))},
329329
)
330330

331331
GeneratedOutputSchema = apply_function_to_model_tree(
332332
OutputSchema,
333333
replace_array_with_shapedtype,
334334
model_prefix="AbstractEval_",
335-
model_kwargs={"model_config": ConfigDict(extra="forbid")},
335+
model_kwargs={"model_config": (ConfigDict, ConfigDict(extra="forbid"))},
336336
)
337337

338338
class AbstractInputSchema(BaseModel):
@@ -463,7 +463,7 @@ def _find_shape_from_path(path_patterns: dict, concrete_path: str) -> tuple:
463463
InputSchema,
464464
lambda x, _: x,
465465
model_prefix=f"{ad_flavor.title()}_",
466-
model_kwargs={"model_config": ConfigDict(extra="forbid")},
466+
model_kwargs={"model_config": (ConfigDict, ConfigDict(extra="forbid"))},
467467
)
468468

469469
def result_validator(

tesseract_core/runtime/schema_types.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,13 @@ def __get_pydantic_core_schema__(
170170
Does most of the heavy lifting for validation and serialization.
171171
"""
172172
# Create a Pydantic model for the encoded array, for easier validation
173-
array_schema = get_array_model(
174-
cls.expected_shape, cls.expected_dtype, [flag.name for flag in cls.flags]
175-
).__get_pydantic_core_schema__(_source_type, _handler)
173+
array_schema = _handler(
174+
get_array_model(
175+
cls.expected_shape,
176+
cls.expected_dtype,
177+
[flag.name for flag in cls.flags],
178+
)
179+
)
176180

177181
python_to_array_ = partial(
178182
python_to_array,

0 commit comments

Comments
 (0)