Skip to content

Commit 76bd866

Browse files
authored
Add Python 3.14 support (#629)
1 parent aabaa89 commit 76bd866

File tree

19 files changed

+468
-402
lines changed

19 files changed

+468
-402
lines changed

.github/workflows/codegen.yml

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,6 @@ jobs:
1818
shell: bash
1919

2020
steps:
21-
- name: Run Cimon (eBPF).
22-
if: runner.os == 'Linux'
23-
uses: cycodelabs/cimon-action@v0
24-
with:
25-
prevent: true
26-
allowed-hosts: >
27-
files.pythonhosted.org
28-
install.python-poetry.org
29-
pypi.org
30-
3121
- name: Checkout repository.
3222
uses: actions/checkout@v4
3323

@@ -39,7 +29,7 @@ jobs:
3929
- name: Setup Poetry.
4030
uses: snok/install-poetry@v1
4131
with:
42-
version: 1.8.3
32+
version: 2.2.1
4333

4434
- name: Install dependencies.
4535
run: poetry install --no-interaction

.github/workflows/publish_release.yml

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,6 @@ jobs:
1313
runs-on: ubuntu-latest
1414

1515
steps:
16-
- name: Run Cimon (eBPF).
17-
uses: cycodelabs/cimon-action@v0
18-
with:
19-
prevent: true
20-
allowed-hosts: >
21-
files.pythonhosted.org
22-
install.python-poetry.org
23-
pypi.org
24-
upload.pypi.org
25-
*.sigstore.dev
26-
2716
- name: Checkout repository.
2817
uses: actions/checkout@v4
2918
with:
@@ -37,7 +26,7 @@ jobs:
3726
- name: Setup Poetry.
3827
uses: snok/install-poetry@v1
3928
with:
40-
version: 1.8.3
29+
version: 2.2.1
4130

4231
- name: Install Poetry Plugin.
4332
run: poetry self add "poetry-dynamic-versioning[plugin]"

.github/workflows/ruff.yml

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

1212
steps:
13-
- name: Run Cimon (eBPF).
14-
uses: cycodelabs/cimon-action@v0
15-
with:
16-
prevent: true
17-
allowed-hosts: >
18-
files.pythonhosted.org
19-
pypi.org
20-
2113
- name: Checkout repository.
2214
uses: actions/checkout@v4
2315

@@ -29,10 +21,10 @@ jobs:
2921
- name: Run linter check.
3022
uses: astral-sh/ruff-action@v3
3123
with:
32-
version: 0.7.0
24+
version: 0.14.1
3325

3426
- name: Run code style check.
3527
uses: astral-sh/ruff-action@v3
3628
with:
37-
version: 0.7.0
29+
version: 0.14.1
3830
args: "format --check"

.github/workflows/test.yml

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
strategy:
1111
matrix:
1212
os: [ macos-latest, ubuntu-latest, windows-latest ]
13-
python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13" ]
13+
python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13", "3.14" ]
1414

1515
runs-on: ${{matrix.os}}
1616

@@ -19,19 +19,6 @@ jobs:
1919
shell: bash
2020

2121
steps:
22-
- name: Run Cimon (eBPF).
23-
if: runner.os == 'Linux'
24-
uses: cycodelabs/cimon-action@v0
25-
with:
26-
prevent: true
27-
allowed-hosts: >
28-
files.pythonhosted.org
29-
install.python-poetry.org
30-
pypi.org
31-
*.atproto.blue
32-
*.marshal.dev
33-
plc.directory
34-
3522
- name: Checkout repository.
3623
uses: actions/checkout@v4
3724

@@ -43,7 +30,7 @@ jobs:
4330
- name: Setup Poetry.
4431
uses: snok/install-poetry@v1
4532
with:
46-
version: 1.8.3
33+
version: 2.2.1
4734

4835
- name: Install dependencies.
4936
run: poetry install --without docs

.github/workflows/update_lexicons.yml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,6 @@ jobs:
1313
runs-on: ubuntu-latest
1414

1515
steps:
16-
- name: Run Cimon (eBPF).
17-
uses: cycodelabs/cimon-action@v0
18-
with:
19-
prevent: true
20-
allowed-hosts: >
21-
files.pythonhosted.org
22-
install.python-poetry.org
23-
pypi.org
24-
2516
- name: Checkout repository.
2617
uses: actions/checkout@v4
2718

packages/atproto/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
verify_jwt_async,
3232
)
3333

34-
__all__ = [
34+
__all__ = [ # noqa: RUF022
3535
# client
3636
'AsyncClient',
3737
'Client',

packages/atproto_client/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
__all__ = [
77
'AsyncClient',
88
'Client',
9-
'models',
10-
'SessionEvent',
119
'Session',
10+
'SessionEvent',
11+
'models',
1212
]

packages/atproto_client/models/dot_dict.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,13 @@ def __reduce__(self): # noqa: ANN204
134134
@staticmethod
135135
def __convert(obj: t.Any) -> t.Any:
136136
if isinstance(obj, dict):
137-
return DotDict(t.cast(t.Dict[str, t.Any], obj))
137+
return DotDict(t.cast('t.Dict[str, t.Any]', obj))
138138
if isinstance(obj, list):
139-
return [DotDict.__convert(v) for v in t.cast(t.List[t.Any], obj)]
139+
return [DotDict.__convert(v) for v in t.cast('t.List[t.Any]', obj)]
140140
if isinstance(obj, set):
141-
return {DotDict.__convert(v) for v in t.cast(t.Set[t.Any], obj)}
141+
return {DotDict.__convert(v) for v in t.cast('t.Set[t.Any]', obj)}
142142
if isinstance(obj, tuple):
143-
return tuple(DotDict.__convert(v) for v in t.cast(t.Tuple[t.Any], obj))
143+
return tuple(DotDict.__convert(v) for v in t.cast('t.Tuple[t.Any]', obj))
144144
return obj
145145

146146

packages/atproto_client/models/string_formats.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33
import re
44
from datetime import datetime
55
from functools import wraps
6-
from typing import Callable, Mapping, Set, Union, cast
6+
from typing import TYPE_CHECKING, Callable, Mapping, Set, Union, cast
77
from urllib.parse import urlparse
88

99
from atproto_core.exceptions import InvalidNsidError
1010
from atproto_core.nsid import validate_nsid as atproto_core_validate_nsid
1111
from pydantic import BeforeValidator, Field, ValidationInfo
12-
from pydantic_core import core_schema
1312
from typing_extensions import Annotated, Literal
1413

14+
if TYPE_CHECKING:
15+
from pydantic_core import core_schema
16+
1517
_OPT_IN_KEY: Literal['strict_string_format'] = 'strict_string_format'
1618

1719
# constants
@@ -82,7 +84,7 @@ def only_validate_if_strict(validate_fn: Callable[..., str]) -> Callable[..., st
8284
def wrapper(v: str, info: ValidationInfo) -> str:
8385
"""Could likely be generalized to support arbitrary signatures."""
8486
if info and isinstance(info.context, Mapping) and info.context.get(_OPT_IN_KEY, False):
85-
return cast(core_schema.WithInfoValidatorFunction, validate_fn)(v, info)
87+
return cast('core_schema.WithInfoValidatorFunction', validate_fn)(v, info)
8688
return v
8789

8890
return wrapper

packages/atproto_client/models/utils.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,15 @@ def _get_or_create(
8787
return None
8888

8989
# we are sure that this is dict because of check above
90-
model_data = t.cast(t.Dict[str, t.Any], model_data)
90+
model_data = t.cast('t.Dict[str, t.Any]', model_data)
9191

9292
# resolve a record model by type and try to deserialize
9393
record_type: t.Any = model_data.get(_TYPE_SERVICE_FIELD)
9494
if record_type not in RECORD_TYPE_TO_MODEL_CLASS:
9595
return None
9696

9797
# now we are sure that this is str because it's in RECORD_TYPE_TO_MODEL_CLASS
98-
record_type = t.cast(str, record_type)
98+
record_type = t.cast('str', record_type)
9999

100100
return get_or_create(
101101
model_data,
@@ -120,15 +120,15 @@ def _get_or_create(
120120
def get_response_model(response: 'Response', model: t.Type[M]) -> M:
121121
if model is bool:
122122
# Could not be False? Because the exception with errors will be raised from the server
123-
return t.cast(M, response.success)
123+
return t.cast('M', response.success)
124124
if model is bytes:
125-
return t.cast(M, response.content)
125+
return t.cast('M', response.content)
126126

127127
if not isinstance(response.content, dict):
128128
raise ModelError("Can't properly parse response model because JSON is expected in response")
129129

130130
# casting to M because of enabled strict mode
131-
return t.cast(M, get_or_create(response.content, model, strict=True))
131+
return t.cast('M', get_or_create(response.content, model, strict=True))
132132

133133

134134
def get_model_as_dict(model: t.Union[DotDict, BlobRef, ModelBase]) -> t.Dict[str, t.Any]:

0 commit comments

Comments
 (0)