Skip to content

Commit ff34530

Browse files
authored
Upgrade to 3.10 syntax (#1341)
Co-authored-by: Dylan Anthony <dbanty@users.noreply.github.com>
1 parent 3d5e270 commit ff34530

File tree

242 files changed

+2974
-2902
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

242 files changed

+2974
-2902
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
default: major
3+
---
4+
5+
# Drop support for Python 3.9
6+
7+
Both `openapi-python-client` itself and any generated clients no longer support Python 3.9.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
default: major
3+
---
4+
5+
# Generated models now use `from __future__ import annotations`
6+
7+
This simplifies using forward references with the newer union syntax.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
default: note
3+
---
4+
5+
# Minimum Typer version is now 0.16
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
default: minor
3+
---
4+
5+
# Upgrade generated clients to 3.10 union syntax
6+
7+
All generated types now use the `A | B` syntax instead of `Union[A, B]` or `Optional[A]`.

.github/workflows/checks.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
test:
1212
strategy:
1313
matrix:
14-
python: [ "3.9", "3.10", "3.11", "3.12", "3.13" ]
14+
python: [ "3.10", "3.11", "3.12", "3.13", "3.14" ]
1515
os: [ ubuntu-latest, macos-latest, windows-latest ]
1616
runs-on: ${{ matrix.os }}
1717
steps:
@@ -78,7 +78,7 @@ jobs:
7878
- name: Set up Python
7979
uses: actions/setup-python@v6.0.0
8080
with:
81-
python-version: "3.9"
81+
python-version: "3.10"
8282

8383
- name: Get Python Version
8484
id: get_python_version
@@ -128,15 +128,15 @@ jobs:
128128
129129
# Find all of the downloaded coverage reports and combine them
130130
.venv/bin/python -m coverage combine
131-
131+
132132
# Create html report
133133
.venv/bin/python -m coverage html --skip-covered --skip-empty
134-
134+
135135
# Report in Markdown and write to summary.
136136
.venv/bin/python -m coverage report --format=markdown >> $GITHUB_STEP_SUMMARY
137-
137+
138138
# Report again and fail if under 100%.
139-
.venv/bin/python -m coverage report --fail-under=100
139+
.venv/bin/python -m coverage report --fail-under=100
140140
141141
- name: Upload HTML report if check failed.
142142
uses: actions/upload-artifact@v4.6.2
@@ -163,7 +163,7 @@ jobs:
163163
- name: Set up Python
164164
uses: actions/setup-python@v6.0.0
165165
with:
166-
python-version: "3.9"
166+
python-version: "3.10"
167167
- name: Get Python Version
168168
id: get_python_version
169169
run: echo "python_version=$(python --version)" >> $GITHUB_OUTPUT

end_to_end_tests/__snapshots__/test_end_to_end.ambr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
# name: test_documents_with_errors[bad-status-code]
33
'''
44
Generating /test-documents-with-errors
5-
Warning(s) encountered while generating. Client was generated, but some pieces may be missing
65

6+
Warning(s) encountered while generating. Client was generated, but some pieces may be missing
77
WARNING parsing GET / within default.
88

99
Invalid response status code pattern: abcdef, response will be omitted from generated client
@@ -16,8 +16,8 @@
1616
# name: test_documents_with_errors[circular-body-ref]
1717
'''
1818
Generating /test-documents-with-errors
19-
Warning(s) encountered while generating. Client was generated, but some pieces may be missing
2019

20+
Warning(s) encountered while generating. Client was generated, but some pieces may be missing
2121
WARNING parsing POST / within default. Endpoint will not be generated.
2222

2323
Circular $ref in request body
@@ -30,8 +30,8 @@
3030
# name: test_documents_with_errors[invalid-uuid-defaults]
3131
'''
3232
Generating /test-documents-with-errors
33-
Warning(s) encountered while generating. Client was generated, but some pieces may be missing
3433

34+
Warning(s) encountered while generating. Client was generated, but some pieces may be missing
3535
WARNING parsing PUT / within default. Endpoint will not be generated.
3636

3737
cannot parse parameter of endpoint put_: Invalid UUID value: 3
@@ -49,8 +49,8 @@
4949
# name: test_documents_with_errors[missing-body-ref]
5050
'''
5151
Generating /test-documents-with-errors
52-
Warning(s) encountered while generating. Client was generated, but some pieces may be missing
5352

53+
Warning(s) encountered while generating. Client was generated, but some pieces may be missing
5454
WARNING parsing POST / within default. Endpoint will not be generated.
5555

5656
Could not resolve $ref #/components/requestBodies/body in request body
@@ -63,8 +63,8 @@
6363
# name: test_documents_with_errors[optional-path-param]
6464
'''
6565
Generating /test-documents-with-errors
66-
Warning(s) encountered while generating. Client was generated, but some pieces may be missing
6766

67+
Warning(s) encountered while generating. Client was generated, but some pieces may be missing
6868
WARNING parsing GET /{optional} within default. Endpoint will not be generated.
6969

7070
Path parameter must be required

end_to_end_tests/docstrings-on-attributes-golden-record/my_test_api_client/client.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import ssl
2-
from typing import Any, Optional, Union
2+
from typing import Any
33

44
import httpx
55
from attrs import define, evolve, field
@@ -34,12 +34,12 @@ class Client:
3434
_base_url: str = field(alias="base_url")
3535
_cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
3636
_headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
37-
_timeout: Optional[httpx.Timeout] = field(default=None, kw_only=True, alias="timeout")
38-
_verify_ssl: Union[str, bool, ssl.SSLContext] = field(default=True, kw_only=True, alias="verify_ssl")
37+
_timeout: httpx.Timeout | None = field(default=None, kw_only=True, alias="timeout")
38+
_verify_ssl: str | bool | ssl.SSLContext = field(default=True, kw_only=True, alias="verify_ssl")
3939
_follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects")
4040
_httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args")
41-
_client: Optional[httpx.Client] = field(default=None, init=False)
42-
_async_client: Optional[httpx.AsyncClient] = field(default=None, init=False)
41+
_client: httpx.Client | None = field(default=None, init=False)
42+
_async_client: httpx.AsyncClient | None = field(default=None, init=False)
4343

4444
def with_headers(self, headers: dict[str, str]) -> "Client":
4545
"""Get a new client matching this one with additional headers"""
@@ -157,12 +157,12 @@ class AuthenticatedClient:
157157
_base_url: str = field(alias="base_url")
158158
_cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
159159
_headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
160-
_timeout: Optional[httpx.Timeout] = field(default=None, kw_only=True, alias="timeout")
161-
_verify_ssl: Union[str, bool, ssl.SSLContext] = field(default=True, kw_only=True, alias="verify_ssl")
160+
_timeout: httpx.Timeout | None = field(default=None, kw_only=True, alias="timeout")
161+
_verify_ssl: str | bool | ssl.SSLContext = field(default=True, kw_only=True, alias="verify_ssl")
162162
_follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects")
163163
_httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args")
164-
_client: Optional[httpx.Client] = field(default=None, init=False)
165-
_async_client: Optional[httpx.AsyncClient] = field(default=None, init=False)
164+
_client: httpx.Client | None = field(default=None, init=False)
165+
_async_client: httpx.AsyncClient | None = field(default=None, init=False)
166166

167167
token: str
168168
"""The token to use for authentication"""

end_to_end_tests/docstrings-on-attributes-golden-record/my_test_api_client/models/model_with_description.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
from __future__ import annotations
2+
13
from collections.abc import Mapping
2-
from typing import Any, TypeVar, Union
4+
from typing import Any, TypeVar
35

46
from attrs import define as _attrs_define
57
from attrs import field as _attrs_field
@@ -13,10 +15,10 @@
1315
class ModelWithDescription:
1416
"""This is a nice model."""
1517

16-
prop_with_no_desc: Union[Unset, str] = UNSET
17-
prop_with_desc: Union[Unset, str] = UNSET
18+
prop_with_no_desc: str | Unset = UNSET
19+
prop_with_desc: str | Unset = UNSET
1820
""" This is a nice property. """
19-
prop_with_long_desc: Union[Unset, str] = UNSET
21+
prop_with_long_desc: str | Unset = UNSET
2022
""" It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of
2123
foolishness,
2224
it was the epoch of belief, it was the epoch of incredulity, it was the season of light, it was the season of

end_to_end_tests/docstrings-on-attributes-golden-record/my_test_api_client/models/model_with_no_description.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
from __future__ import annotations
2+
13
from collections.abc import Mapping
2-
from typing import Any, TypeVar, Union
4+
from typing import Any, TypeVar
35

46
from attrs import define as _attrs_define
57
from attrs import field as _attrs_field
@@ -11,8 +13,8 @@
1113

1214
@_attrs_define
1315
class ModelWithNoDescription:
14-
prop_with_no_desc: Union[Unset, str] = UNSET
15-
prop_with_desc: Union[Unset, str] = UNSET
16+
prop_with_no_desc: str | Unset = UNSET
17+
prop_with_desc: str | Unset = UNSET
1618
""" This is a nice property. """
1719
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
1820

end_to_end_tests/docstrings-on-attributes-golden-record/my_test_api_client/types.py

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

33
from collections.abc import Mapping, MutableMapping
44
from http import HTTPStatus
5-
from typing import IO, BinaryIO, Generic, Literal, Optional, TypeVar, Union
5+
from typing import IO, BinaryIO, Generic, Literal, TypeVar
66

77
from attrs import define
88

@@ -15,13 +15,13 @@ def __bool__(self) -> Literal[False]:
1515
UNSET: Unset = Unset()
1616

1717
# The types that `httpx.Client(files=)` can accept, copied from that library.
18-
FileContent = Union[IO[bytes], bytes, str]
19-
FileTypes = Union[
18+
FileContent = IO[bytes] | bytes | str
19+
FileTypes = (
2020
# (filename, file (or bytes), content_type)
21-
tuple[Optional[str], FileContent, Optional[str]],
21+
tuple[str | None, FileContent, str | None]
2222
# (filename, file (or bytes), content_type, headers)
23-
tuple[Optional[str], FileContent, Optional[str], Mapping[str, str]],
24-
]
23+
| tuple[str | None, FileContent, str | None, Mapping[str, str]]
24+
)
2525
RequestFiles = list[tuple[str, FileTypes]]
2626

2727

@@ -30,8 +30,8 @@ class File:
3030
"""Contains information for file uploads"""
3131

3232
payload: BinaryIO
33-
file_name: Optional[str] = None
34-
mime_type: Optional[str] = None
33+
file_name: str | None = None
34+
mime_type: str | None = None
3535

3636
def to_tuple(self) -> FileTypes:
3737
"""Return a tuple representation that httpx will accept for multipart/form-data"""
@@ -48,7 +48,7 @@ class Response(Generic[T]):
4848
status_code: HTTPStatus
4949
content: bytes
5050
headers: MutableMapping[str, str]
51-
parsed: Optional[T]
51+
parsed: T | None
5252

5353

5454
__all__ = ["UNSET", "File", "FileTypes", "RequestFiles", "Response", "Unset"]

0 commit comments

Comments
 (0)