gmt-python-sdk 0.40.1__tar.gz → 0.41.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gmt_python_sdk-0.41.0/.release-please-manifest.json +3 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/CHANGELOG.md +8 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/PKG-INFO +1 -1
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/pyproject.toml +1 -1
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_models.py +80 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_version.py +1 -1
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_models.py +57 -3
- gmt_python_sdk-0.40.1/.release-please-manifest.json +0 -3
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/.gitignore +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/CONTRIBUTING.md +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/LICENSE +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/README.md +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/SECURITY.md +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/api.md +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/bin/check-release-environment +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/bin/publish-pypi +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/examples/.keep +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/release-please-config.json +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/requirements-dev.lock +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_base_client.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_client.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_compat.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_constants.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_exceptions.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_files.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_qs.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_resource.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_streaming.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_types.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_compat.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_datetime_parse.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_json.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_logs.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_path.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_proxy.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_reflection.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_resources_proxy.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_streams.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_sync.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_transform.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_typing.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/_utils/_utils.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/lib/.keep +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/pagination.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/py.typed +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/accounts.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/profile/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/profile/discount.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/profile/profile.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/profile/referral/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/profile/referral/referral.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/profile/referral/transaction.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/purchases/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/purchases/bulk.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/purchases/purchases.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/purchases_by_hash.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/service.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/telegram/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/telegram/purchases.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/telegram/telegram.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/webhooks.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/account_list_countries_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/account_list_countries_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/account_list_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/account_list_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/account_retrieve_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile/discount_retrieve_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile/referral/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile/referral/transaction_list_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile/referral/transaction_list_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile/referral_retrieve_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile/referral_transfer_balance_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile/referral_transfer_balance_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_language_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_language_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_login_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_login_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_password_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_password_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_retrieve_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_unbind_telegram_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchase_create_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchase_create_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchase_list_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchase_list_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchase_refund_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchase_request_verification_code_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchase_request_verification_code_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchase_retrieve_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchases/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchases/bulk_create_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchases/bulk_create_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchases/bulk_retrieve_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchases_by_hash_request_verification_code_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchases_by_hash_request_verification_code_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchases_by_hash_retrieve_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/service_get_server_time_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/service_health_check_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram/purchase_create_premium_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram/purchase_create_premium_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram/purchase_create_stars_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram/purchase_create_stars_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram/purchase_list_premium_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram/purchase_list_premium_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram/purchase_list_stars_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram/purchase_list_stars_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram_get_premium_price_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram_get_premium_price_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram_get_stars_price_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram_get_stars_price_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/webhook_test_params.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/webhook_test_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/profile/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/profile/referral/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/profile/referral/test_transaction.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/profile/test_discount.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/profile/test_referral.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/purchases/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/purchases/test_bulk.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/telegram/__init__.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/telegram/test_purchases.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/test_accounts.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/test_profile.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/test_purchases.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/test_purchases_by_hash.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/test_service.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/test_telegram.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/test_webhooks.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/conftest.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/sample_file.txt +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_client.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_extract_files.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_files.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_qs.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_required_args.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_response.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_streaming.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_transform.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_utils/test_datetime_parse.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_utils/test_json.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_utils/test_path.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_utils/test_proxy.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/test_utils/test_typing.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/utils.py +0 -0
- {gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/uv.lock +0 -0
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.41.0 (2026-05-12)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.40.1...v0.41.0](https://github.com/cameo6/gmt-python-sdk/compare/v0.40.1...v0.41.0)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* **internal/types:** support eagerly validating pydantic iterators ([6f57eab](https://github.com/cameo6/gmt-python-sdk/commit/6f57eab5d36d8ebe7e1da5a46b3ac0cf66e82ed4))
|
|
10
|
+
|
|
3
11
|
## 0.40.1 (2026-05-09)
|
|
4
12
|
|
|
5
13
|
Full Changelog: [v0.40.0...v0.40.1](https://github.com/cameo6/gmt-python-sdk/compare/v0.40.0...v0.40.1)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: gmt-python-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.41.0
|
|
4
4
|
Summary: The official Python library for the gmt API
|
|
5
5
|
Project-URL: Homepage, https://github.com/cameo6/gmt-python-sdk
|
|
6
6
|
Project-URL: Repository, https://github.com/cameo6/gmt-python-sdk
|
|
@@ -25,7 +25,9 @@ from typing_extensions import (
|
|
|
25
25
|
ClassVar,
|
|
26
26
|
Protocol,
|
|
27
27
|
Required,
|
|
28
|
+
Annotated,
|
|
28
29
|
ParamSpec,
|
|
30
|
+
TypeAlias,
|
|
29
31
|
TypedDict,
|
|
30
32
|
TypeGuard,
|
|
31
33
|
final,
|
|
@@ -79,7 +81,15 @@ from ._compat import (
|
|
|
79
81
|
from ._constants import RAW_RESPONSE_HEADER
|
|
80
82
|
|
|
81
83
|
if TYPE_CHECKING:
|
|
84
|
+
from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler
|
|
85
|
+
from pydantic_core import CoreSchema, core_schema
|
|
82
86
|
from pydantic_core.core_schema import ModelField, ModelSchema, LiteralSchema, ModelFieldsSchema
|
|
87
|
+
else:
|
|
88
|
+
try:
|
|
89
|
+
from pydantic_core import CoreSchema, core_schema
|
|
90
|
+
except ImportError:
|
|
91
|
+
CoreSchema = None
|
|
92
|
+
core_schema = None
|
|
83
93
|
|
|
84
94
|
__all__ = ["BaseModel", "GenericModel"]
|
|
85
95
|
|
|
@@ -396,6 +406,76 @@ class BaseModel(pydantic.BaseModel):
|
|
|
396
406
|
)
|
|
397
407
|
|
|
398
408
|
|
|
409
|
+
class _EagerIterable(list[_T], Generic[_T]):
|
|
410
|
+
"""
|
|
411
|
+
Accepts any Iterable[T] input (including generators), consumes it
|
|
412
|
+
eagerly, and validates all items upfront.
|
|
413
|
+
|
|
414
|
+
Validation preserves the original container type where possible
|
|
415
|
+
(e.g. a set[T] stays a set[T]). Serialization (model_dump / JSON)
|
|
416
|
+
always emits a list — round-tripping through model_dump() will not
|
|
417
|
+
restore the original container type.
|
|
418
|
+
"""
|
|
419
|
+
|
|
420
|
+
@classmethod
|
|
421
|
+
def __get_pydantic_core_schema__(
|
|
422
|
+
cls,
|
|
423
|
+
source_type: Any,
|
|
424
|
+
handler: GetCoreSchemaHandler,
|
|
425
|
+
) -> CoreSchema:
|
|
426
|
+
(item_type,) = get_args(source_type) or (Any,)
|
|
427
|
+
item_schema: CoreSchema = handler.generate_schema(item_type)
|
|
428
|
+
list_of_items_schema: CoreSchema = core_schema.list_schema(item_schema)
|
|
429
|
+
|
|
430
|
+
return core_schema.no_info_wrap_validator_function(
|
|
431
|
+
cls._validate,
|
|
432
|
+
list_of_items_schema,
|
|
433
|
+
serialization=core_schema.plain_serializer_function_ser_schema(
|
|
434
|
+
cls._serialize,
|
|
435
|
+
info_arg=False,
|
|
436
|
+
),
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
@staticmethod
|
|
440
|
+
def _validate(v: Iterable[_T], handler: "ValidatorFunctionWrapHandler") -> Any:
|
|
441
|
+
original_type: type[Any] = type(v)
|
|
442
|
+
|
|
443
|
+
# Normalize to list so list_schema can validate each item
|
|
444
|
+
if isinstance(v, list):
|
|
445
|
+
items: list[_T] = v
|
|
446
|
+
else:
|
|
447
|
+
try:
|
|
448
|
+
items = list(v)
|
|
449
|
+
except TypeError as e:
|
|
450
|
+
raise TypeError("Value is not iterable") from e
|
|
451
|
+
|
|
452
|
+
# Validate items against the inner schema
|
|
453
|
+
validated: list[_T] = handler(items)
|
|
454
|
+
|
|
455
|
+
# Reconstruct original container type
|
|
456
|
+
if original_type is list:
|
|
457
|
+
return validated
|
|
458
|
+
# str(list) produces the list's repr, not a string built from items,
|
|
459
|
+
# so skip reconstruction for str and its subclasses.
|
|
460
|
+
if issubclass(original_type, str):
|
|
461
|
+
return validated
|
|
462
|
+
try:
|
|
463
|
+
return original_type(validated)
|
|
464
|
+
except (TypeError, ValueError):
|
|
465
|
+
# If the type cannot be reconstructed, just return the validated list
|
|
466
|
+
return validated
|
|
467
|
+
|
|
468
|
+
@staticmethod
|
|
469
|
+
def _serialize(v: Iterable[_T]) -> list[_T]:
|
|
470
|
+
"""Always serialize as a list so Pydantic's JSON encoder is happy."""
|
|
471
|
+
if isinstance(v, list):
|
|
472
|
+
return v
|
|
473
|
+
return list(v)
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
EagerIterable: TypeAlias = Annotated[Iterable[_T], _EagerIterable]
|
|
477
|
+
|
|
478
|
+
|
|
399
479
|
def _construct_field(value: object, field: FieldInfo, key: str) -> object:
|
|
400
480
|
if value is None:
|
|
401
481
|
return field_get_default(field)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional, cast
|
|
2
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Union, Iterable, Optional, cast
|
|
3
3
|
from datetime import datetime, timezone
|
|
4
|
-
from
|
|
4
|
+
from collections import deque
|
|
5
|
+
from typing_extensions import Literal, Annotated, TypedDict, TypeAliasType
|
|
5
6
|
|
|
6
7
|
import pytest
|
|
7
8
|
import pydantic
|
|
@@ -9,7 +10,7 @@ from pydantic import Field
|
|
|
9
10
|
|
|
10
11
|
from gmt._utils import PropertyInfo
|
|
11
12
|
from gmt._compat import PYDANTIC_V1, parse_obj, model_dump, model_json
|
|
12
|
-
from gmt._models import DISCRIMINATOR_CACHE, BaseModel, construct_type
|
|
13
|
+
from gmt._models import DISCRIMINATOR_CACHE, BaseModel, EagerIterable, construct_type
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class BasicModel(BaseModel):
|
|
@@ -961,3 +962,56 @@ def test_extra_properties() -> None:
|
|
|
961
962
|
assert model.a.prop == 1
|
|
962
963
|
assert isinstance(model.a, Item)
|
|
963
964
|
assert model.other == "foo"
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
# NOTE: Workaround for Pydantic Iterable behavior.
|
|
968
|
+
# Iterable fields are replaced with a ValidatorIterator and may be consumed
|
|
969
|
+
# during serialization, which can cause subsequent dumps to return empty data.
|
|
970
|
+
# See: https://github.com/pydantic/pydantic/issues/9541
|
|
971
|
+
@pytest.mark.parametrize(
|
|
972
|
+
"data, expected_validated",
|
|
973
|
+
[
|
|
974
|
+
([1, 2, 3], [1, 2, 3]),
|
|
975
|
+
((1, 2, 3), (1, 2, 3)),
|
|
976
|
+
(set([1, 2, 3]), set([1, 2, 3])),
|
|
977
|
+
(iter([1, 2, 3]), [1, 2, 3]),
|
|
978
|
+
([], []),
|
|
979
|
+
((x for x in [1, 2, 3]), [1, 2, 3]),
|
|
980
|
+
(map(lambda x: x, [1, 2, 3]), [1, 2, 3]),
|
|
981
|
+
(frozenset([1, 2, 3]), frozenset([1, 2, 3])),
|
|
982
|
+
(deque([1, 2, 3]), deque([1, 2, 3])),
|
|
983
|
+
],
|
|
984
|
+
ids=["list", "tuple", "set", "iterator", "empty", "generator", "map", "frozenset", "deque"],
|
|
985
|
+
)
|
|
986
|
+
@pytest.mark.skipif(PYDANTIC_V1, reason="this is only supported in pydantic v2")
|
|
987
|
+
def test_iterable_construction(data: Iterable[int], expected_validated: Iterable[int]) -> None:
|
|
988
|
+
class TypeWithIterable(TypedDict):
|
|
989
|
+
items: EagerIterable[int]
|
|
990
|
+
|
|
991
|
+
class Model(BaseModel):
|
|
992
|
+
data: TypeWithIterable
|
|
993
|
+
|
|
994
|
+
m = Model.model_validate({"data": {"items": data}})
|
|
995
|
+
assert m.data["items"] == expected_validated
|
|
996
|
+
|
|
997
|
+
# Verify repeated dumps don't lose data (the original bug)
|
|
998
|
+
assert m.model_dump()["data"]["items"] == list(expected_validated)
|
|
999
|
+
assert m.model_dump()["data"]["items"] == list(expected_validated)
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
@pytest.mark.skipif(PYDANTIC_V1, reason="this is only supported in pydantic v2")
|
|
1003
|
+
def test_iterable_construction_str_falls_back_to_list() -> None:
|
|
1004
|
+
# str is iterable (over chars), but str(list_of_chars) produces the list's repr
|
|
1005
|
+
# rather than reconstructing a string from items. We special-case str to fall
|
|
1006
|
+
# back to list instead of attempting reconstruction.
|
|
1007
|
+
class TypeWithIterable(TypedDict):
|
|
1008
|
+
items: EagerIterable[str]
|
|
1009
|
+
|
|
1010
|
+
class Model(BaseModel):
|
|
1011
|
+
data: TypeWithIterable
|
|
1012
|
+
|
|
1013
|
+
m = Model.model_validate({"data": {"items": "hello"}})
|
|
1014
|
+
|
|
1015
|
+
# falls back to list of chars rather than calling str(["h", "e", "l", "l", "o"])
|
|
1016
|
+
assert m.data["items"] == ["h", "e", "l", "l", "o"]
|
|
1017
|
+
assert m.model_dump()["data"]["items"] == ["h", "e", "l", "l", "o"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/profile/referral/__init__.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/profile/referral/referral.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/resources/profile/referral/transaction.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/account_list_countries_params.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/account_list_countries_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile/discount_retrieve_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile/referral_retrieve_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_language_params.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_language_response.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_login_params.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_login_response.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_password_params.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_change_password_response.py
RENAMED
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/profile_unbind_telegram_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchases/bulk_create_params.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchases/bulk_create_response.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchases/bulk_retrieve_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/purchases_by_hash_retrieve_response.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/service_get_server_time_response.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/service_health_check_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram/purchase_list_stars_params.py
RENAMED
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram_get_premium_price_params.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram_get_premium_price_response.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram_get_stars_price_params.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/src/gmt/types/telegram_get_stars_price_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/profile/referral/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/profile/test_discount.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/profile/test_referral.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/telegram/test_purchases.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.40.1 → gmt_python_sdk-0.41.0}/tests/api_resources/test_purchases_by_hash.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|