Skip to content

Commit fbf710d

Browse files
authored
Release 7.3.0: PaymentRequiredError for HTTP 402 (#123)
* Release 7.2.1: PaymentRequiredError for HTTP 402. * Pin ruff to 0.15.16. * Bump requests, ruff, and CI while keeping Python 3.9. * Match example-app CI: checkout@v5 and setup-python@v6. * Release 7.3.0 Bump the PaymentRequiredError release from 7.2.1 to 7.3.0.
1 parent 2ec259a commit fbf710d

10 files changed

Lines changed: 32 additions & 9 deletions

File tree

.github/workflows/lint.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ jobs:
1010
runs-on: ubuntu-latest
1111

1212
steps:
13-
- uses: actions/checkout@v4
13+
- uses: actions/checkout@v5
1414

1515
- name: Set up Python
16-
uses: actions/setup-python@v5
16+
uses: actions/setup-python@v6
1717
with:
1818
python-version: '3.13'
19+
cache: pip
1920

2021
- name: Install ruff
2122
run: |

.github/workflows/specs.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
15+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
1616

1717
steps:
18-
- uses: actions/checkout@v4
18+
- uses: actions/checkout@v5
1919

2020
- name: Set up Python ${{ matrix.python-version }}
21-
uses: actions/setup-python@v5
21+
uses: actions/setup-python@v6
2222
with:
2323
python-version: ${{ matrix.python-version }}
24+
cache: pip
2425

2526
- name: Install dependencies
2627
run: |

CHANGELOG.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
master
22
------
33

4+
7.3.0 (2026-09-07)
5+
------------------
6+
7+
- add ``PaymentRequiredError`` for HTTP 402 responses
8+
- raise the ``requests`` minimum to ``2.32.5``
9+
- pin ``ruff`` to ``0.15.22``
10+
- test on Python 3.9–3.14
11+
412
7.2.0 (2026-06-09)
513
------------------
614

DEVELOPMENT.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Test
2424
2525
$ make test
2626
27-
Runs ``python3 -m unittest -v castle.test``. CI runs the same suite on Python 3.9–3.13 via GitHub Actions (``.github/workflows/specs.yml``).
27+
Runs ``python3 -m unittest -v castle.test``. CI runs the same suite on Python 3.9–3.14 via GitHub Actions (``.github/workflows/specs.yml``).
2828

2929
Linting
3030
-------

README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ All exceptions inherit from ``CastleError``. The most useful ones:
190190
- ``InvalidRequestTokenError`` — the request token is missing or invalid
191191
- ``InvalidParametersError`` — 422 response with validation details
192192
- ``RateLimitError`` — 429 response; back off and retry
193+
- ``PaymentRequiredError`` — 402 response
193194
- ``UnauthorizedError`` — 401; bad API secret
194195
- ``InternalServerError`` — 5xx response from Castle
195196
- ``WebhookVerificationError`` — webhook signature did not match

castle/core/process_response.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
InternalServerError,
1111
InvalidRequestTokenError,
1212
RateLimitError,
13+
PaymentRequiredError,
1314
)
1415
from castle.logger import Logger
1516

1617
RESPONSE_ERRORS = {
1718
400: BadRequestError,
1819
401: UnauthorizedError,
20+
402: PaymentRequiredError,
1921
403: ForbiddenError,
2022
404: NotFoundError,
2123
419: UserUnauthorizedError,

castle/errors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,9 @@ class RateLimitError(APIError):
5555
pass
5656

5757

58+
class PaymentRequiredError(APIError):
59+
pass
60+
61+
5862
class InternalServerError(APIError):
5963
pass

castle/test/core/process_response_test.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
InternalServerError,
1414
InvalidRequestTokenError,
1515
RateLimitError,
16+
PaymentRequiredError,
1617
)
1718

1819

@@ -91,6 +92,10 @@ def test_verify_419(self):
9192
with self.assertRaises(UserUnauthorizedError):
9293
CoreProcessResponse(response(status_code=419)).verify()
9394

95+
def test_verify_402(self):
96+
with self.assertRaises(PaymentRequiredError):
97+
CoreProcessResponse(response(status_code=402)).verify()
98+
9499
def test_verify_429(self):
95100
with self.assertRaises(RateLimitError):
96101
CoreProcessResponse(response(status_code=429)).verify()

castle/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION = '7.2.0'
1+
VERSION = '7.3.0'

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ authors = [
1313
requires-python = ">=3.9"
1414
dynamic = ["version"]
1515
dependencies = [
16-
"requests>=2.31",
16+
"requests>=2.32.5",
1717
]
1818
classifiers = [
1919
"Environment :: Web Environment",
@@ -27,6 +27,7 @@ classifiers = [
2727
"Programming Language :: Python :: 3.11",
2828
"Programming Language :: Python :: 3.12",
2929
"Programming Language :: Python :: 3.13",
30+
"Programming Language :: Python :: 3.14",
3031
]
3132

3233
[project.urls]
@@ -36,7 +37,7 @@ Changelog = "https://github.com/castle/castle-python/blob/master/CHANGELOG.rst"
3637

3738
[project.optional-dependencies]
3839
test = ["responses>=0.23"]
39-
lint = ["ruff>=0.6"]
40+
lint = ["ruff==0.15.22"]
4041

4142
[tool.setuptools.dynamic]
4243
version = { attr = "castle.version.VERSION" }

0 commit comments

Comments
 (0)