From 0e8ad0b2da007a9fdc33a88b517ebc5ff48bc7d6 Mon Sep 17 00:00:00 2001 From: David Brownman <109395161+xavdid-stripe@users.noreply.github.com> Date: Fri, 21 Nov 2025 09:56:46 -0800 Subject: [PATCH 1/3] throw more specific error when accessing Invoice.payment_intent (#1681) --- stripe/_stripe_object.py | 9 +++++++++ tests/test_stripe_object.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/stripe/_stripe_object.py b/stripe/_stripe_object.py index 0f44342f4..6ce504aa6 100644 --- a/stripe/_stripe_object.py +++ b/stripe/_stripe_object.py @@ -216,6 +216,15 @@ def __getitem__(self, k: str) -> Any: % (k, k, ", ".join(list(self.keys()))) ) else: + from stripe._invoice import Invoice + + # super specific one-off case to help users debug this property disappearing + # see also: https://go/j/DEVSDK-2835 + if isinstance(self, Invoice) and k == "payment_intent": + raise KeyError( + "The 'payment_intent' attribute is no longer available on Invoice objects. See the docs for more details: https://docs.stripe.com/changelog/basil/2025-03-31/add-support-for-multiple-partial-payments-on-invoices#why-is-this-a-breaking-change" + ) + raise err def __delitem__(self, k: str) -> None: diff --git a/tests/test_stripe_object.py b/tests/test_stripe_object.py index c6356d672..a963fcc5d 100644 --- a/tests/test_stripe_object.py +++ b/tests/test_stripe_object.py @@ -6,6 +6,7 @@ import pytest import stripe +from stripe._invoice import Invoice from stripe._stripe_object import StripeObject # We use this because it has a map, "restriction.currency_options" from string -> CurrencyOptions nested class. @@ -433,3 +434,36 @@ def test_can_update_api_key(self, http_client_mock): api_key="key2", stripe_account=None, ) + + def test_invoice_payment_method_gets_special_error(self): + def is_good_error(e: Exception) -> bool: + return "multiple-partial-payments-on-invoices" in str(e) + + i = Invoice() + + with pytest.raises(AttributeError) as e: + i.payment_intent # type: ignore + assert is_good_error(e.value) + + with pytest.raises(KeyError) as e: + i["payment_intent"] + assert is_good_error(e.value) + + # only that property gets the special error + with pytest.raises(AttributeError) as e: + i.blah # type: ignore + assert not is_good_error(e.value) + + with pytest.raises(KeyError) as e: + i["blah"] + assert not is_good_error(e.value) + + # other classes don't have that special error + so = StripeObject() + with pytest.raises(AttributeError) as e: + so.payment_intent # type: ignore + assert not is_good_error(e.value) + + with pytest.raises(KeyError) as e: + so["payment_intent"] + assert not is_good_error(e.value) From efc0c1d6bc8f9f168e12679f6526d3509ae80cf9 Mon Sep 17 00:00:00 2001 From: "stripe-openapi[bot]" <105521251+stripe-openapi[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 20:02:16 -0500 Subject: [PATCH 2/3] Update generated code for v2128 and (#1684) Co-authored-by: Stripe OpenAPI <105521251+stripe-openapi[bot]@users.noreply.github.com> --- API_VERSION | 2 +- OPENAPI_VERSION | 2 +- stripe/__init__.py | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/API_VERSION b/API_VERSION index 330433275..dc9d80dc3 100644 --- a/API_VERSION +++ b/API_VERSION @@ -1 +1 @@ -e62524b587909bee231a15ce0dc618f1d04f69a4 \ No newline at end of file +368be7755d15d02a1038325c7d159703b01662b0 \ No newline at end of file diff --git a/OPENAPI_VERSION b/OPENAPI_VERSION index ea1ecdee1..1d5ad796c 100644 --- a/OPENAPI_VERSION +++ b/OPENAPI_VERSION @@ -1 +1 @@ -v2124 \ No newline at end of file +v2128 \ No newline at end of file diff --git a/stripe/__init__.py b/stripe/__init__.py index 643e1efb7..e4a93185d 100644 --- a/stripe/__init__.py +++ b/stripe/__init__.py @@ -111,6 +111,7 @@ def set_app_info( if TYPE_CHECKING: from stripe import ( + _error as error, apps as apps, billing as billing, billing_portal as billing_portal, @@ -539,6 +540,7 @@ def set_app_info( # name -> (import_target, is_submodule) _import_map = { + "error": ("stripe._error", True), "apps": ("stripe.apps", True), "billing": ("stripe.billing", True), "billing_portal": ("stripe.billing_portal", True), From 93cdfb85b5f9cf63fb4eef77c3c6e8da3e81ba7c Mon Sep 17 00:00:00 2001 From: Prathmesh Ranaut Date: Fri, 21 Nov 2025 20:03:51 -0500 Subject: [PATCH 3/3] Bump version to 14.0.1 --- CHANGELOG.md | 5 +++++ VERSION | 2 +- pyproject.toml | 2 +- stripe/_version.py | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e12151a06..1d9972996 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 14.0.1 - 2025-11-21 +* [#1684](https://github.com/stripe/stripe-python/pull/1684) Update generated code + * `stripe.error` module is now accessible globally. Fixes [#1682](https://github.com/stripe/stripe-python/issues/1682) +* [#1681](https://github.com/stripe/stripe-python/pull/1681) Throw a specific error when accessing `payment_intent` property on `Invoice` object to ease debugging. + ## 14.0.0 - 2025-11-18 This release changes the pinned API version to `2025-11-17.clover`. diff --git a/VERSION b/VERSION index 4b964e965..63dba868a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -14.0.0 +14.0.1 diff --git a/pyproject.toml b/pyproject.toml index 3e9775ea0..c647f2e41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "stripe" -version = "14.0.0" +version = "14.0.1" readme = "README.md" description = "Python bindings for the Stripe API" authors = [{ name = "Stripe", email = "support@stripe.com" }] diff --git a/stripe/_version.py b/stripe/_version.py index 43c84ff02..c79d234de 100644 --- a/stripe/_version.py +++ b/stripe/_version.py @@ -1 +1 @@ -VERSION = "14.0.0" +VERSION = "14.0.1"