From dcfbd58a82291c18a0d8eb39b032892578372f82 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 15:59:33 +0000 Subject: [PATCH 1/8] chore(internal): codegen related update --- requirements-dev.lock | 2 +- requirements.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-dev.lock b/requirements-dev.lock index 5e2eddce..04ab853d 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -56,7 +56,7 @@ httpx==0.28.1 # via httpx-aiohttp # via lithic # via respx -httpx-aiohttp==0.1.6 +httpx-aiohttp==0.1.8 # via lithic idna==3.4 # via anyio diff --git a/requirements.lock b/requirements.lock index d849a86d..52f3ff0b 100644 --- a/requirements.lock +++ b/requirements.lock @@ -43,7 +43,7 @@ httpcore==1.0.2 httpx==0.28.1 # via httpx-aiohttp # via lithic -httpx-aiohttp==0.1.6 +httpx-aiohttp==0.1.8 # via lithic idna==3.4 # via anyio From e858da478df9e173121ec85b25c325592b829a7d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:25:37 +0000 Subject: [PATCH 2/8] chore(internal): bump pinned h11 dep --- requirements-dev.lock | 4 ++-- requirements.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements-dev.lock b/requirements-dev.lock index 04ab853d..8c6da18f 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -48,9 +48,9 @@ filelock==3.12.4 frozenlist==1.6.2 # via aiohttp # via aiosignal -h11==0.14.0 +h11==0.16.0 # via httpcore -httpcore==1.0.2 +httpcore==1.0.9 # via httpx httpx==0.28.1 # via httpx-aiohttp diff --git a/requirements.lock b/requirements.lock index 52f3ff0b..afc9481d 100644 --- a/requirements.lock +++ b/requirements.lock @@ -36,9 +36,9 @@ exceptiongroup==1.2.2 frozenlist==1.6.2 # via aiohttp # via aiosignal -h11==0.14.0 +h11==0.16.0 # via httpcore -httpcore==1.0.2 +httpcore==1.0.9 # via httpx httpx==0.28.1 # via httpx-aiohttp From 5899b78cbb1a18810f41a7eb1b8ea4dfe0932117 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 15:26:28 +0000 Subject: [PATCH 3/8] chore(package): mark python 3.13 as supported --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 4fb110da..fced9ec0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: MacOS", From 76e15cfc9cd15bfea7025837ca9068a5b744eb0a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 18:22:51 +0000 Subject: [PATCH 4/8] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index b628d43c..dd2b46a6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 164 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-1aaf1d9d9aea1bfa14a48559f01d539aa1449d65f252dc9c3b606c7bca300af1.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-41b87f6139d55188993492b9c042a6bc1bc0506c166334c387072b57b6c79869.yml openapi_spec_hash: 3327246caf3bcbd3504ce99c81062075 -config_hash: a5d12cd64a37624cbe350cd7b2380693 +config_hash: f390dcd4de9109eff9667160949feef2 From a2b90935ed8d4be3118828e48877327c0ab648b5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 18:46:28 +0000 Subject: [PATCH 5/8] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index dd2b46a6..6bfd44b3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 164 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-41b87f6139d55188993492b9c042a6bc1bc0506c166334c387072b57b6c79869.yml openapi_spec_hash: 3327246caf3bcbd3504ce99c81062075 -config_hash: f390dcd4de9109eff9667160949feef2 +config_hash: b7425db12ddcc27a89a38de7042c4fa2 From b0120a3ad10826bc27ded420fb6308ae331aab26 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 18:54:03 +0000 Subject: [PATCH 6/8] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 6bfd44b3..dd2b46a6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 164 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-41b87f6139d55188993492b9c042a6bc1bc0506c166334c387072b57b6c79869.yml openapi_spec_hash: 3327246caf3bcbd3504ce99c81062075 -config_hash: b7425db12ddcc27a89a38de7042c4fa2 +config_hash: f390dcd4de9109eff9667160949feef2 From a64aca3063355ce5cd73844d1bc51f70c41c2d9e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 9 Jul 2025 10:18:39 +0000 Subject: [PATCH 7/8] fix(parsing): correctly handle nested discriminated unions --- src/lithic/_models.py | 13 ++++++++----- tests/test_models.py | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/lithic/_models.py b/src/lithic/_models.py index 4f214980..528d5680 100644 --- a/src/lithic/_models.py +++ b/src/lithic/_models.py @@ -2,9 +2,10 @@ import os import inspect -from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, cast +from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast from datetime import date, datetime from typing_extensions import ( + List, Unpack, Literal, ClassVar, @@ -366,7 +367,7 @@ def _construct_field(value: object, field: FieldInfo, key: str) -> object: if type_ is None: raise RuntimeError(f"Unexpected field type is None for {key}") - return construct_type(value=value, type_=type_) + return construct_type(value=value, type_=type_, metadata=getattr(field, "metadata", None)) def is_basemodel(type_: type) -> bool: @@ -420,7 +421,7 @@ def construct_type_unchecked(*, value: object, type_: type[_T]) -> _T: return cast(_T, construct_type(value=value, type_=type_)) -def construct_type(*, value: object, type_: object) -> object: +def construct_type(*, value: object, type_: object, metadata: Optional[List[Any]] = None) -> object: """Loose coercion to the expected type with construction of nested values. 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: type_ = type_.__value__ # type: ignore[unreachable] # unwrap `Annotated[T, ...]` -> `T` - if is_annotated_type(type_): - meta: tuple[Any, ...] = get_args(type_)[1:] + if metadata is not None: + meta: tuple[Any, ...] = tuple(metadata) + elif is_annotated_type(type_): + meta = get_args(type_)[1:] type_ = extract_type_arg(type_, 0) else: meta = tuple() diff --git a/tests/test_models.py b/tests/test_models.py index 00798c04..a7f4b143 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -889,3 +889,48 @@ class ModelB(BaseModel): ) assert isinstance(m, ModelB) + + +def test_nested_discriminated_union() -> None: + class InnerType1(BaseModel): + type: Literal["type_1"] + + class InnerModel(BaseModel): + inner_value: str + + class InnerType2(BaseModel): + type: Literal["type_2"] + some_inner_model: InnerModel + + class Type1(BaseModel): + base_type: Literal["base_type_1"] + value: Annotated[ + Union[ + InnerType1, + InnerType2, + ], + PropertyInfo(discriminator="type"), + ] + + class Type2(BaseModel): + base_type: Literal["base_type_2"] + + T = Annotated[ + Union[ + Type1, + Type2, + ], + PropertyInfo(discriminator="base_type"), + ] + + model = construct_type( + type_=T, + value={ + "base_type": "base_type_1", + "value": { + "type": "type_2", + }, + }, + ) + assert isinstance(model, Type1) + assert isinstance(model.value, InnerType2) From 40c5f85de7ce052441084181c8d88f124d6f278f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 9 Jul 2025 10:19:05 +0000 Subject: [PATCH 8/8] release: 0.97.1 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 15 +++++++++++++++ pyproject.toml | 2 +- src/lithic/_version.py | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ca93fdaa..7fef08e1 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.97.0" + ".": "0.97.1" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ecba4cc..831bef86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 0.97.1 (2025-07-09) + +Full Changelog: [v0.97.0...v0.97.1](https://github.com/lithic-com/lithic-python/compare/v0.97.0...v0.97.1) + +### Bug Fixes + +* **parsing:** correctly handle nested discriminated unions ([a64aca3](https://github.com/lithic-com/lithic-python/commit/a64aca3063355ce5cd73844d1bc51f70c41c2d9e)) + + +### Chores + +* **internal:** bump pinned h11 dep ([e858da4](https://github.com/lithic-com/lithic-python/commit/e858da478df9e173121ec85b25c325592b829a7d)) +* **internal:** codegen related update ([dcfbd58](https://github.com/lithic-com/lithic-python/commit/dcfbd58a82291c18a0d8eb39b032892578372f82)) +* **package:** mark python 3.13 as supported ([5899b78](https://github.com/lithic-com/lithic-python/commit/5899b78cbb1a18810f41a7eb1b8ea4dfe0932117)) + ## 0.97.0 (2025-07-03) Full Changelog: [v0.96.0...v0.97.0](https://github.com/lithic-com/lithic-python/compare/v0.96.0...v0.97.0) diff --git a/pyproject.toml b/pyproject.toml index fced9ec0..5a75c8b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lithic" -version = "0.97.0" +version = "0.97.1" description = "The official Python library for the lithic API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/lithic/_version.py b/src/lithic/_version.py index eb8d03fa..c73cab8a 100644 --- a/src/lithic/_version.py +++ b/src/lithic/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "lithic" -__version__ = "0.97.0" # x-release-please-version +__version__ = "0.97.1" # x-release-please-version