Skip to content

Commit 014a845

Browse files
release: 1.30.2 (#665)
* chore(package): mark python 3.13 as supported * fix(parsing): correctly handle nested discriminated unions * release: 1.30.2 --------- Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
1 parent 03d6b10 commit 014a845

File tree

6 files changed

+70
-8
lines changed

6 files changed

+70
-8
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "1.30.1"
2+
".": "1.30.2"
33
}

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## 1.30.2 (2025-07-09)
4+
5+
Full Changelog: [v1.30.1...v1.30.2](https://github.com/Finch-API/finch-api-python/compare/v1.30.1...v1.30.2)
6+
7+
### Bug Fixes
8+
9+
* **parsing:** correctly handle nested discriminated unions ([28bdcad](https://github.com/Finch-API/finch-api-python/commit/28bdcad5d94a336a9585c1ba646feee058143d88))
10+
11+
12+
### Chores
13+
14+
* **package:** mark python 3.13 as supported ([837dbdf](https://github.com/Finch-API/finch-api-python/commit/837dbdf09c38f2472a3fcdab561a2a378c715ad8))
15+
316
## 1.30.1 (2025-07-08)
417

518
Full Changelog: [v1.30.0...v1.30.1](https://github.com/Finch-API/finch-api-python/compare/v1.30.0...v1.30.1)

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "finch-api"
3-
version = "1.30.1"
3+
version = "1.30.2"
44
description = "The official Python library for the Finch API"
55
dynamic = ["readme"]
66
license = "Apache-2.0"
@@ -24,6 +24,7 @@ classifiers = [
2424
"Programming Language :: Python :: 3.10",
2525
"Programming Language :: Python :: 3.11",
2626
"Programming Language :: Python :: 3.12",
27+
"Programming Language :: Python :: 3.13",
2728
"Operating System :: OS Independent",
2829
"Operating System :: POSIX",
2930
"Operating System :: MacOS",

src/finch/_models.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import os
44
import inspect
5-
from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, cast
5+
from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast
66
from datetime import date, datetime
77
from typing_extensions import (
8+
List,
89
Unpack,
910
Literal,
1011
ClassVar,
@@ -366,7 +367,7 @@ def _construct_field(value: object, field: FieldInfo, key: str) -> object:
366367
if type_ is None:
367368
raise RuntimeError(f"Unexpected field type is None for {key}")
368369

369-
return construct_type(value=value, type_=type_)
370+
return construct_type(value=value, type_=type_, metadata=getattr(field, "metadata", None))
370371

371372

372373
def is_basemodel(type_: type) -> bool:
@@ -420,7 +421,7 @@ def construct_type_unchecked(*, value: object, type_: type[_T]) -> _T:
420421
return cast(_T, construct_type(value=value, type_=type_))
421422

422423

423-
def construct_type(*, value: object, type_: object) -> object:
424+
def construct_type(*, value: object, type_: object, metadata: Optional[List[Any]] = None) -> object:
424425
"""Loose coercion to the expected type with construction of nested values.
425426
426427
If the given value does not match the expected type then it is returned as-is.
@@ -438,8 +439,10 @@ def construct_type(*, value: object, type_: object) -> object:
438439
type_ = type_.__value__ # type: ignore[unreachable]
439440

440441
# unwrap `Annotated[T, ...]` -> `T`
441-
if is_annotated_type(type_):
442-
meta: tuple[Any, ...] = get_args(type_)[1:]
442+
if metadata is not None:
443+
meta: tuple[Any, ...] = tuple(metadata)
444+
elif is_annotated_type(type_):
445+
meta = get_args(type_)[1:]
443446
type_ = extract_type_arg(type_, 0)
444447
else:
445448
meta = tuple()

src/finch/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

33
__title__ = "finch"
4-
__version__ = "1.30.1" # x-release-please-version
4+
__version__ = "1.30.2" # x-release-please-version

tests/test_models.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,3 +889,48 @@ class ModelB(BaseModel):
889889
)
890890

891891
assert isinstance(m, ModelB)
892+
893+
894+
def test_nested_discriminated_union() -> None:
895+
class InnerType1(BaseModel):
896+
type: Literal["type_1"]
897+
898+
class InnerModel(BaseModel):
899+
inner_value: str
900+
901+
class InnerType2(BaseModel):
902+
type: Literal["type_2"]
903+
some_inner_model: InnerModel
904+
905+
class Type1(BaseModel):
906+
base_type: Literal["base_type_1"]
907+
value: Annotated[
908+
Union[
909+
InnerType1,
910+
InnerType2,
911+
],
912+
PropertyInfo(discriminator="type"),
913+
]
914+
915+
class Type2(BaseModel):
916+
base_type: Literal["base_type_2"]
917+
918+
T = Annotated[
919+
Union[
920+
Type1,
921+
Type2,
922+
],
923+
PropertyInfo(discriminator="base_type"),
924+
]
925+
926+
model = construct_type(
927+
type_=T,
928+
value={
929+
"base_type": "base_type_1",
930+
"value": {
931+
"type": "type_2",
932+
},
933+
},
934+
)
935+
assert isinstance(model, Type1)
936+
assert isinstance(model.value, InnerType2)

0 commit comments

Comments
 (0)