python3-commons 0.8.32__tar.gz → 0.8.33__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.
Files changed (56) hide show
  1. {python3_commons-0.8.32/src/python3_commons.egg-info → python3_commons-0.8.33}/PKG-INFO +4 -4
  2. {python3_commons-0.8.32 → python3_commons-0.8.33}/pyproject.toml +5 -5
  3. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/serializers/msgspec.py +27 -9
  4. {python3_commons-0.8.32 → python3_commons-0.8.33/src/python3_commons.egg-info}/PKG-INFO +4 -4
  5. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons.egg-info/requires.txt +3 -3
  6. python3_commons-0.8.33/tests/conftest.py +117 -0
  7. {python3_commons-0.8.32 → python3_commons-0.8.33}/tests/test_msgpack.py +1 -1
  8. {python3_commons-0.8.32 → python3_commons-0.8.33}/tests/test_msgspec.py +24 -9
  9. {python3_commons-0.8.32 → python3_commons-0.8.33}/uv.lock +55 -55
  10. python3_commons-0.8.32/tests/conftest.py +0 -79
  11. {python3_commons-0.8.32 → python3_commons-0.8.33}/.coveragerc +0 -0
  12. {python3_commons-0.8.32 → python3_commons-0.8.33}/.github/workflows/python-publish.yaml +0 -0
  13. {python3_commons-0.8.32 → python3_commons-0.8.33}/.github/workflows/release-on-tag-push.yml +0 -0
  14. {python3_commons-0.8.32 → python3_commons-0.8.33}/.gitignore +0 -0
  15. {python3_commons-0.8.32 → python3_commons-0.8.33}/.pre-commit-config.yaml +0 -0
  16. {python3_commons-0.8.32 → python3_commons-0.8.33}/.python-version +0 -0
  17. {python3_commons-0.8.32 → python3_commons-0.8.33}/AUTHORS.rst +0 -0
  18. {python3_commons-0.8.32 → python3_commons-0.8.33}/CHANGELOG.rst +0 -0
  19. {python3_commons-0.8.32 → python3_commons-0.8.33}/LICENSE +0 -0
  20. {python3_commons-0.8.32 → python3_commons-0.8.33}/README.md +0 -0
  21. {python3_commons-0.8.32 → python3_commons-0.8.33}/README.rst +0 -0
  22. {python3_commons-0.8.32 → python3_commons-0.8.33}/docs/Makefile +0 -0
  23. {python3_commons-0.8.32 → python3_commons-0.8.33}/docs/_static/.gitignore +0 -0
  24. {python3_commons-0.8.32 → python3_commons-0.8.33}/docs/authors.rst +0 -0
  25. {python3_commons-0.8.32 → python3_commons-0.8.33}/docs/changelog.rst +0 -0
  26. {python3_commons-0.8.32 → python3_commons-0.8.33}/docs/conf.py +0 -0
  27. {python3_commons-0.8.32 → python3_commons-0.8.33}/docs/index.rst +0 -0
  28. {python3_commons-0.8.32 → python3_commons-0.8.33}/docs/license.rst +0 -0
  29. {python3_commons-0.8.32 → python3_commons-0.8.33}/setup.cfg +0 -0
  30. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/__init__.py +0 -0
  31. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/api_client.py +0 -0
  32. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/audit.py +0 -0
  33. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/auth.py +0 -0
  34. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/cache.py +0 -0
  35. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/conf.py +0 -0
  36. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/db/__init__.py +0 -0
  37. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/db/helpers.py +0 -0
  38. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/db/models/__init__.py +0 -0
  39. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/db/models/auth.py +0 -0
  40. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/db/models/common.py +0 -0
  41. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/db/models/rbac.py +0 -0
  42. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/fs.py +0 -0
  43. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/helpers.py +0 -0
  44. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/log/__init__.py +0 -0
  45. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/log/filters.py +0 -0
  46. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/log/formatters.py +0 -0
  47. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/object_storage.py +0 -0
  48. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/permissions.py +0 -0
  49. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/serializers/__init__.py +0 -0
  50. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/serializers/json.py +0 -0
  51. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons/serializers/msgpack.py +0 -0
  52. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons.egg-info/SOURCES.txt +0 -0
  53. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons.egg-info/dependency_links.txt +0 -0
  54. {python3_commons-0.8.32 → python3_commons-0.8.33}/src/python3_commons.egg-info/top_level.txt +0 -0
  55. {python3_commons-0.8.32 → python3_commons-0.8.33}/tests/test_audit.py +0 -0
  56. {python3_commons-0.8.32 → python3_commons-0.8.33}/tests/test_helpers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python3-commons
3
- Version: 0.8.32
3
+ Version: 0.8.33
4
4
  Summary: Re-usable Python3 code
5
5
  Author-email: Oleg Korsak <kamikaze.is.waiting.you@gmail.com>
6
6
  License-Expression: GPL-3.0
@@ -12,7 +12,7 @@ Requires-Python: ==3.13.*
12
12
  Description-Content-Type: text/x-rst
13
13
  License-File: LICENSE
14
14
  License-File: AUTHORS.rst
15
- Requires-Dist: aiohttp[speedups]~=3.12.2
15
+ Requires-Dist: aiohttp[speedups]~=3.12.4
16
16
  Requires-Dist: asyncpg~=0.30.0
17
17
  Requires-Dist: fastapi-users-db-sqlalchemy~=7.0.0
18
18
  Requires-Dist: fastapi-users[sqlalchemy]~=14.0.1
@@ -22,8 +22,8 @@ Requires-Dist: msgpack~=1.1.0
22
22
  Requires-Dist: msgspec~=0.19.0
23
23
  Requires-Dist: pydantic[email]~=2.11.5
24
24
  Requires-Dist: pydantic-settings~=2.9.1
25
- Requires-Dist: python-jose==3.4.0
26
- Requires-Dist: SQLAlchemy[asyncio]~=2.0.40
25
+ Requires-Dist: python-jose~=3.5.0
26
+ Requires-Dist: SQLAlchemy[asyncio]~=2.0.41
27
27
  Requires-Dist: valkey[libvalkey]~=6.1.0
28
28
  Requires-Dist: zeep~=4.3.1
29
29
  Dynamic: license-file
@@ -19,7 +19,7 @@ keywords = []
19
19
  requires-python = "==3.13.*"
20
20
 
21
21
  dependencies = [
22
- "aiohttp[speedups]~=3.12.2",
22
+ "aiohttp[speedups]~=3.12.4",
23
23
  "asyncpg~=0.30.0",
24
24
  "fastapi-users-db-sqlalchemy~=7.0.0",
25
25
  "fastapi-users[sqlalchemy]~=14.0.1",
@@ -29,8 +29,8 @@ dependencies = [
29
29
  "msgspec~=0.19.0",
30
30
  "pydantic[email]~=2.11.5",
31
31
  "pydantic-settings~=2.9.1",
32
- "python-jose==3.4.0",
33
- "SQLAlchemy[asyncio]~=2.0.40",
32
+ "python-jose~=3.5.0",
33
+ "SQLAlchemy[asyncio]~=2.0.41",
34
34
  "valkey[libvalkey]~=6.1.0",
35
35
  "zeep~=4.3.1"
36
36
  ]
@@ -41,8 +41,8 @@ dev = [
41
41
  "pip==25.1.1",
42
42
  "pre-commit==4.2.0",
43
43
  "pyright==1.1.401",
44
- "ruff==0.11.11",
45
- "setuptools==80.8.0",
44
+ "ruff==0.11.12",
45
+ "setuptools==80.9.0",
46
46
  "setuptools_scm==8.3.1",
47
47
  "wheel==0.45.1",
48
48
  ]
@@ -2,16 +2,18 @@ import dataclasses
2
2
  import json
3
3
  import logging
4
4
  import struct
5
- from _decimal import Decimal
6
5
  from datetime import date, datetime
7
- from typing import Any
6
+ from decimal import Decimal
7
+ from typing import Any, Type, TypeVar
8
8
 
9
9
  from msgspec import msgpack
10
10
  from msgspec.msgpack import Ext, encode
11
+ from pydantic import BaseModel
11
12
 
12
13
  from python3_commons.serializers.json import CustomJSONEncoder
13
14
 
14
15
  logger = logging.getLogger(__name__)
16
+ T = TypeVar('T')
15
17
 
16
18
 
17
19
  def enc_hook(obj: Any) -> Any:
@@ -45,28 +47,44 @@ MSGPACK_DECODER = msgpack.Decoder(ext_hook=ext_hook)
45
47
  MSGPACK_DECODER_NATIVE = msgpack.Decoder()
46
48
 
47
49
 
48
- def serialize_msgpack_native(data) -> bytes:
49
- return encode(data)
50
+ def serialize_msgpack_native(data: Any) -> bytes:
51
+ if isinstance(data, BaseModel):
52
+ data = data.model_dump()
50
53
 
54
+ result = encode(data)
51
55
 
52
- def deserialize_msgpack_native(data: bytes, data_type=None):
56
+ return result
57
+
58
+
59
+ def deserialize_msgpack_native(data: bytes, data_type: Type[T] | None = None) -> T | Any:
53
60
  if data_type:
54
- result = msgpack.decode(data, type=data_type)
61
+ if issubclass(data_type, BaseModel):
62
+ decoded = MSGPACK_DECODER_NATIVE.decode(data)
63
+ result = data_type.model_validate(decoded)
64
+ else:
65
+ result = msgpack.decode(data, type=data_type)
55
66
  else:
56
67
  result = MSGPACK_DECODER_NATIVE.decode(data)
57
68
 
58
69
  return result
59
70
 
60
71
 
61
- def serialize_msgpack(data) -> bytes:
72
+ def serialize_msgpack(data: Any) -> bytes:
73
+ if isinstance(data, BaseModel):
74
+ data = data.model_dump()
75
+
62
76
  result = MSGPACK_ENCODER.encode(data)
63
77
 
64
78
  return result
65
79
 
66
80
 
67
- def deserialize_msgpack(data: bytes, data_type=None):
81
+ def deserialize_msgpack(data: bytes, data_type: Type[T] | None = None) -> T | Any:
68
82
  if data_type:
69
- result = msgpack.decode(data, type=data_type)
83
+ if issubclass(data_type, BaseModel):
84
+ decoded = MSGPACK_DECODER.decode(data)
85
+ result = data_type.model_validate(decoded)
86
+ else:
87
+ result = msgpack.decode(data, type=data_type)
70
88
  else:
71
89
  result = MSGPACK_DECODER.decode(data)
72
90
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python3-commons
3
- Version: 0.8.32
3
+ Version: 0.8.33
4
4
  Summary: Re-usable Python3 code
5
5
  Author-email: Oleg Korsak <kamikaze.is.waiting.you@gmail.com>
6
6
  License-Expression: GPL-3.0
@@ -12,7 +12,7 @@ Requires-Python: ==3.13.*
12
12
  Description-Content-Type: text/x-rst
13
13
  License-File: LICENSE
14
14
  License-File: AUTHORS.rst
15
- Requires-Dist: aiohttp[speedups]~=3.12.2
15
+ Requires-Dist: aiohttp[speedups]~=3.12.4
16
16
  Requires-Dist: asyncpg~=0.30.0
17
17
  Requires-Dist: fastapi-users-db-sqlalchemy~=7.0.0
18
18
  Requires-Dist: fastapi-users[sqlalchemy]~=14.0.1
@@ -22,8 +22,8 @@ Requires-Dist: msgpack~=1.1.0
22
22
  Requires-Dist: msgspec~=0.19.0
23
23
  Requires-Dist: pydantic[email]~=2.11.5
24
24
  Requires-Dist: pydantic-settings~=2.9.1
25
- Requires-Dist: python-jose==3.4.0
26
- Requires-Dist: SQLAlchemy[asyncio]~=2.0.40
25
+ Requires-Dist: python-jose~=3.5.0
26
+ Requires-Dist: SQLAlchemy[asyncio]~=2.0.41
27
27
  Requires-Dist: valkey[libvalkey]~=6.1.0
28
28
  Requires-Dist: zeep~=4.3.1
29
29
  Dynamic: license-file
@@ -1,4 +1,4 @@
1
- aiohttp[speedups]~=3.12.2
1
+ aiohttp[speedups]~=3.12.4
2
2
  asyncpg~=0.30.0
3
3
  fastapi-users-db-sqlalchemy~=7.0.0
4
4
  fastapi-users[sqlalchemy]~=14.0.1
@@ -8,7 +8,7 @@ msgpack~=1.1.0
8
8
  msgspec~=0.19.0
9
9
  pydantic[email]~=2.11.5
10
10
  pydantic-settings~=2.9.1
11
- python-jose==3.4.0
12
- SQLAlchemy[asyncio]~=2.0.40
11
+ python-jose~=3.5.0
12
+ SQLAlchemy[asyncio]~=2.0.41
13
13
  valkey[libvalkey]~=6.1.0
14
14
  zeep~=4.3.1
@@ -0,0 +1,117 @@
1
+ from dataclasses import dataclass
2
+ from datetime import date, datetime
3
+ from decimal import Decimal
4
+ from uuid import UUID, uuid4
5
+
6
+ import msgspec
7
+ import pytest
8
+ from pydantic import BaseModel
9
+
10
+
11
+ @pytest.fixture
12
+ def data_dict():
13
+ return {
14
+ 'A': 1,
15
+ 'B': 'B',
16
+ 'C': None,
17
+ 'D': datetime(2023, 7, 25, 1, 2, 3),
18
+ 'E': date(2023, 7, 24),
19
+ 'F': Decimal('1.23'),
20
+ }
21
+
22
+
23
+ @dataclass
24
+ class TestData:
25
+ a: int
26
+ b: str
27
+ c: str | None
28
+ d: datetime
29
+ e: date
30
+ f: Decimal
31
+
32
+
33
+ @pytest.fixture
34
+ def data_dataclass():
35
+ return TestData(a=1, b='B', c=None, d=datetime(2023, 7, 25, 1, 2, 3), e=date(2023, 7, 24), f=Decimal('1.23'))
36
+
37
+
38
+ class SubStruc(msgspec.Struct):
39
+ uid: UUID
40
+ name: str
41
+
42
+
43
+ class TestStruct(msgspec.Struct):
44
+ a: int
45
+ b: str
46
+ c: str | None
47
+ d: datetime
48
+ e: date
49
+ f: Decimal
50
+ sub: SubStruc
51
+
52
+
53
+ class PydanticSubStruc(BaseModel):
54
+ uid: UUID
55
+ name: str
56
+
57
+
58
+ class PydanticTestStruct(BaseModel):
59
+ a: int
60
+ b: str
61
+ c: str | None
62
+ d: datetime
63
+ e: date
64
+ f: Decimal
65
+ sub: PydanticSubStruc
66
+
67
+
68
+ @pytest.fixture
69
+ def msgspec_struct() -> TestStruct:
70
+ return TestStruct(
71
+ a=1,
72
+ b='B',
73
+ c=None,
74
+ d=datetime(2023, 7, 25, 1, 2, 3),
75
+ e=date(2023, 7, 24),
76
+ f=Decimal('1.23'),
77
+ sub=SubStruc(uid=uuid4(), name='sub-struct'),
78
+ )
79
+
80
+
81
+ @pytest.fixture
82
+ def pydantic_struct() -> PydanticTestStruct:
83
+ return PydanticTestStruct(
84
+ a=1,
85
+ b='B',
86
+ c=None,
87
+ d=datetime(2023, 7, 25, 1, 2, 3),
88
+ e=date(2023, 7, 24),
89
+ f=Decimal('1.23'),
90
+ sub=PydanticSubStruc(uid=uuid4(), name='sub-struct'),
91
+ )
92
+
93
+
94
+ @pytest.fixture
95
+ def s3_file_objects() -> tuple:
96
+ return (
97
+ (
98
+ 'file_a.txt',
99
+ datetime(2024, 1, 1),
100
+ b'ABCDE',
101
+ ),
102
+ (
103
+ 'file_b.txt',
104
+ datetime(2024, 1, 2),
105
+ b'FGHIJ',
106
+ ),
107
+ (
108
+ 'file_c.txt',
109
+ datetime(2024, 1, 3),
110
+ b'KLMNO',
111
+ ),
112
+ (
113
+ 'file_d.txt',
114
+ datetime(2024, 1, 4),
115
+ b'PQRST',
116
+ ),
117
+ )
@@ -1,4 +1,4 @@
1
- from datetime import datetime, date
1
+ from datetime import date, datetime
2
2
  from decimal import Decimal
3
3
 
4
4
  from python3_commons.serializers import msgpack
@@ -16,8 +16,9 @@ def test_encode_decode_dict_to_msgpack(data_dict):
16
16
  'F': '1.23',
17
17
  }
18
18
  binary_data = msgspec.serialize_msgpack(data_dict)
19
+ deserialized_data = msgspec.deserialize_msgpack(binary_data)
19
20
 
20
- assert msgspec.deserialize_msgpack(binary_data) == data_dict
21
+ assert deserialized_data == expected_result
21
22
 
22
23
 
23
24
  def test_encode_decode_dataclass_to_msgpack(data_dataclass):
@@ -26,18 +27,18 @@ def test_encode_decode_dataclass_to_msgpack(data_dataclass):
26
27
  assert msgspec.deserialize_msgpack(binary_data, data_type=data_dataclass.__class__) == data_dataclass
27
28
 
28
29
 
29
- def test_encode_decode_struct_to_msgpack(data_struct):
30
- binary_data = msgspec.serialize_msgpack(data_struct)
31
- decoded_struct = msgspec.deserialize_msgpack(binary_data, data_struct.__class__)
30
+ def test_encode_decode_struct_to_msgpack(msgspec_struct):
31
+ binary_data = msgspec.serialize_msgpack(msgspec_struct)
32
+ decoded_struct = msgspec.deserialize_msgpack(binary_data, msgspec_struct.__class__)
32
33
 
33
- assert decoded_struct == data_struct
34
+ assert decoded_struct == msgspec_struct
34
35
 
35
36
 
36
- def test_encode_decode_struct_to_msgpack_native(data_struct):
37
- binary_data = msgspec.serialize_msgpack_native(data_struct)
38
- decoded_struct = msgspec.deserialize_msgpack_native(binary_data, data_struct.__class__)
37
+ def test_encode_decode_struct_to_msgpack_native(msgspec_struct):
38
+ binary_data = msgspec.serialize_msgpack_native(msgspec_struct)
39
+ decoded_struct = msgspec.deserialize_msgpack_native(binary_data, msgspec_struct.__class__)
39
40
 
40
- assert decoded_struct == data_struct
41
+ assert decoded_struct == msgspec_struct
41
42
 
42
43
 
43
44
  def test_encode_decode_decimal_to_msgpack():
@@ -54,3 +55,17 @@ def test_encode_decode_str_to_msgpack():
54
55
  decoded_value = msgspec.deserialize_msgpack(binary_data)
55
56
 
56
57
  assert decoded_value == value
58
+
59
+
60
+ def test_encode_decode_pydantic_struct_to_msgpack(pydantic_struct):
61
+ binary_data = msgspec.serialize_msgpack(pydantic_struct)
62
+ decoded_struct = msgspec.deserialize_msgpack(binary_data, pydantic_struct.__class__)
63
+
64
+ assert decoded_struct == pydantic_struct
65
+
66
+
67
+ def test_encode_decode_pydantic_struct_to_msgpack_native(pydantic_struct):
68
+ binary_data = msgspec.serialize_msgpack_native(pydantic_struct)
69
+ decoded_struct = msgspec.deserialize_msgpack_native(binary_data, pydantic_struct.__class__)
70
+
71
+ assert decoded_struct == pydantic_struct
@@ -25,7 +25,7 @@ wheels = [
25
25
 
26
26
  [[package]]
27
27
  name = "aiohttp"
28
- version = "3.12.2"
28
+ version = "3.12.4"
29
29
  source = { registry = "https://pypi.org/simple" }
30
30
  dependencies = [
31
31
  { name = "aiohappyeyeballs" },
@@ -36,25 +36,25 @@ dependencies = [
36
36
  { name = "propcache" },
37
37
  { name = "yarl" },
38
38
  ]
39
- sdist = { url = "https://files.pythonhosted.org/packages/06/a2/a946c4f5c54233c97788c2278ea50beaadf45211f452f932b36ce322f660/aiohttp-3.12.2.tar.gz", hash = "sha256:0018956472ee535d2cad761a5bb88eb4ad80f94cd86472cee26a244799f7c79f", size = 7780423, upload-time = "2025-05-27T00:04:27.79Z" }
40
- wheels = [
41
- { url = "https://files.pythonhosted.org/packages/f9/ed/a341ddf8402cc4a177eb63a63d2aee2f177a94b1f2d53ef192e43e82760f/aiohttp-3.12.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e6dd24e72e7425b4eee49eeaa1a08742774f5a0c84041e80625aeba45812f92e", size = 687252, upload-time = "2025-05-27T00:03:03.275Z" },
42
- { url = "https://files.pythonhosted.org/packages/e8/93/00e623a2c984d95a52e7f9e92d178828beb4a5d31b9231b0fda77fc13e98/aiohttp-3.12.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5293245b743d3e41fd4de631aed6018e0016488686ee70d3dbd9ac61cc040429", size = 464914, upload-time = "2025-05-27T00:03:05.71Z" },
43
- { url = "https://files.pythonhosted.org/packages/5e/ad/4fea70b2d1994edf3c34220a41f0ac1263ee4b704343248f7d15fa8e3b8e/aiohttp-3.12.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b2c7bc896696ada3df4ffd787b80d08af53eb16658fd19623f469f89c5f95846", size = 457217, upload-time = "2025-05-27T00:03:07.981Z" },
44
- { url = "https://files.pythonhosted.org/packages/fb/f1/f20c87b0baf096f2d36897fe4a9a0e703f32dbf7b3fcaae0a5a196f779dc/aiohttp-3.12.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e4991a7dcdd577a749429248321196dba6ade4315c6262e9b2ba9a3bb80e9cb", size = 1696029, upload-time = "2025-05-27T00:03:10.072Z" },
45
- { url = "https://files.pythonhosted.org/packages/d9/4a/1b0507cfd73c1736e5cd607c7f16790747112c86e0c17860b1b635ad7d52/aiohttp-3.12.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:88f8d247c4b6cc75eb5ef1724998b3076f5f2f6b7d357560caa5b5da08228cb4", size = 1677295, upload-time = "2025-05-27T00:03:12.856Z" },
46
- { url = "https://files.pythonhosted.org/packages/7d/ca/ffb5d548d6aa195797bebd5e3688821c40c2a6503363e5849d7114678a59/aiohttp-3.12.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e1f3968162f274ed8e97aad591da178fb04725a386a4852b1c0285f3a51390af", size = 1729363, upload-time = "2025-05-27T00:03:15.623Z" },
47
- { url = "https://files.pythonhosted.org/packages/98/3e/e6cb54d8329b7c60b6678631c228339730632ea7c18dd6279e64ad134d52/aiohttp-3.12.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4de7a3a7e482f5832838047c1612c0c3d1f4309e3e2d4ea80cb1b7f5ab0c6bbe", size = 1778736, upload-time = "2025-05-27T00:03:17.936Z" },
48
- { url = "https://files.pythonhosted.org/packages/2d/be/76db303c98159b6c0494fe4f14a6c57a28c81db9010d2d5d764219339f0a/aiohttp-3.12.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86ca0aa49854b195e314171756d06f81c1286541425a929950f7316d617cc3b1", size = 1701064, upload-time = "2025-05-27T00:03:20.234Z" },
49
- { url = "https://files.pythonhosted.org/packages/c3/c1/d6d4abdeffaa9dee12b27c80919a1bda50aea22d5a1dc03c001a005b16ea/aiohttp-3.12.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bff129c6674f3a14c68a0f49337ebd8637440201cbd8af05df52cb2d7db0902", size = 1614772, upload-time = "2025-05-27T00:03:22.472Z" },
50
- { url = "https://files.pythonhosted.org/packages/8c/69/da43fe30ef3323add2ac03b11cef91c50b648d544953732aeff9a47cdb5e/aiohttp-3.12.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:62179517ef8d0abc950ab7e6545e97142bef3f58007da12b9cff5260e8084fd1", size = 1667793, upload-time = "2025-05-27T00:03:25.273Z" },
51
- { url = "https://files.pythonhosted.org/packages/8c/03/367badf467bd9708b2eaa5fc36689b9b2e43489b63d8508fddc508ceaace/aiohttp-3.12.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:48d743fbc8a88dffb2d2e96f17f9e2310aaa672bd2103b198d7613361affd1a3", size = 1699458, upload-time = "2025-05-27T00:03:27.542Z" },
52
- { url = "https://files.pythonhosted.org/packages/d2/12/c7443b288263b4ab3d8c6329de0be8df2967445aa9731b738da7b34f04ca/aiohttp-3.12.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:385f01fe9be53a0466fb66504b00ab00ca7faa0a285186327509cbbe1386363f", size = 1642052, upload-time = "2025-05-27T00:03:30.23Z" },
53
- { url = "https://files.pythonhosted.org/packages/4e/76/2be34ed27931ab1a4cdd40eba3ef2d71bf0eff9d6c0ac8793e92f20f3ac1/aiohttp-3.12.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:631f4da6b1d503f9df883ba86846fa0ff455eae60497fab5f1d21683b2a2784e", size = 1718187, upload-time = "2025-05-27T00:03:32.474Z" },
54
- { url = "https://files.pythonhosted.org/packages/43/39/84d014db48122973171c3cfcf23a2c3ba765163ef8169d6b959d9440152b/aiohttp-3.12.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:7e071f1371f38c15dad609bb57d698fe4614b1817e7808966c643336f5615655", size = 1751656, upload-time = "2025-05-27T00:03:35.213Z" },
55
- { url = "https://files.pythonhosted.org/packages/27/b6/7b13d143352494e943ae3f89b5286dc4ed85f8d5487a09f3dd86efb16eb3/aiohttp-3.12.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:166d8ba47fca7667dd3169be8bd0fb9ffd0f19fd80f0d5291b1e36ab0f77d02c", size = 1700547, upload-time = "2025-05-27T00:03:37.613Z" },
56
- { url = "https://files.pythonhosted.org/packages/42/19/1b42589a0f80f14b1bc81ccc5fb0f8c4398fbd03b5886d1307c7aadd8279/aiohttp-3.12.2-cp313-cp313-win32.whl", hash = "sha256:01ac3cc4a0c81f87ed72c614066bfdee15358c5c2cdf30048dd8823826cbc61e", size = 413024, upload-time = "2025-05-27T00:03:39.782Z" },
57
- { url = "https://files.pythonhosted.org/packages/d0/d7/00abc34b16f1ea9dc8cedffe45c0f454157472480e5b44b6c15f175aa9c6/aiohttp-3.12.2-cp313-cp313-win_amd64.whl", hash = "sha256:cbf833ca90fda31ec505e80f58f8011c64030fb8e368bce0d60f1f9aae162389", size = 438964, upload-time = "2025-05-27T00:03:41.932Z" },
39
+ sdist = { url = "https://files.pythonhosted.org/packages/57/77/92b356837fad83cc5709afc0b6e21dce65a413293fed15e6999bafdf36b0/aiohttp-3.12.4.tar.gz", hash = "sha256:d8229b412121160740f5745583c786f3f494d2416fe5f76aabd815da6ab6b193", size = 7781788, upload-time = "2025-05-29T01:36:57.715Z" }
40
+ wheels = [
41
+ { url = "https://files.pythonhosted.org/packages/b3/c5/acc9a65cd92b263050dcc2986e2aee598fc6f3e0b251c9ce7138bf9f387c/aiohttp-3.12.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:789e9ddd591a3161a4e222942e10036d3fb4477464d9a454be2613966b0bce6b", size = 687716, upload-time = "2025-05-29T01:35:37.749Z" },
42
+ { url = "https://files.pythonhosted.org/packages/3b/8b/c36084efb762c8b388e35b564c5c87d287e4d24a77422f7570e36f8195f4/aiohttp-3.12.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8eb37972e6aebe4cab53b0008c4ca7cd412f3f01872f255763ac4bb0ce253d83", size = 465372, upload-time = "2025-05-29T01:35:39.701Z" },
43
+ { url = "https://files.pythonhosted.org/packages/d0/d5/c390226c7f0a2a0e4a7477fb293d311157092231fdb7ab79eb8ad325b3b0/aiohttp-3.12.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ca6af3e929de2c2d3272680437ee5b1e32fa4ac1fb9dfdcc06f5441542d06110", size = 457673, upload-time = "2025-05-29T01:35:42.458Z" },
44
+ { url = "https://files.pythonhosted.org/packages/bc/1a/fdf6ade28154d249b605a6e85f7eb424363618ebcb35f93a7f837fd1f9c9/aiohttp-3.12.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a9b8b482be5c81ceee91fecead2c82b7bec7cfb8b81c0389d6fa4cd82f3bb53", size = 1696485, upload-time = "2025-05-29T01:35:44.489Z" },
45
+ { url = "https://files.pythonhosted.org/packages/71/02/1670b62c82d6e19c77df235b96a56ec055eb40d63b6feff93146544d0224/aiohttp-3.12.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b3f9d7c7486f28cc0fd6bfe5b9accc4ecfe3d4f0471ec53e08aa610e5642dbf3", size = 1677750, upload-time = "2025-05-29T01:35:47.567Z" },
46
+ { url = "https://files.pythonhosted.org/packages/af/eb/75c9863328a9f1f7200ebadf0fefec3a50a2f31e9ccf489faf9c132b87ad/aiohttp-3.12.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e42986c6fc949926bcf0928b5440e6adf20b9a14c04dd9ea5e3ba9c7bbd4433a", size = 1729821, upload-time = "2025-05-29T01:35:49.98Z" },
47
+ { url = "https://files.pythonhosted.org/packages/8a/ac/75ef05d10aae033d9bc87d0eea35d904e505c0a7a5d7c7838d1d8b63e954/aiohttp-3.12.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58dded319d52e63ea3c40dbae3f44c1264fa4bb692845b7ff8ce1ddc9319fce3", size = 1779191, upload-time = "2025-05-29T01:35:52.257Z" },
48
+ { url = "https://files.pythonhosted.org/packages/b3/5e/36e5957a073dddb69ed37e5ffa8581548d5d7b9d00daa4ba98fff6c85219/aiohttp-3.12.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1102668bf8c4b744528ef0b5bdaeeb17930832653d1ed9558ab59a0fae91dcf9", size = 1701521, upload-time = "2025-05-29T01:35:54.413Z" },
49
+ { url = "https://files.pythonhosted.org/packages/4e/98/16c3dc7c2534d5109f02da5c88e34e327d8ceddb9b976b4861d787461a59/aiohttp-3.12.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e46c5ad27747416ef0a914da2ad175d9066d8d011960f7b66c9b4f02ef7acfcc", size = 1615227, upload-time = "2025-05-29T01:35:56.595Z" },
50
+ { url = "https://files.pythonhosted.org/packages/74/cb/87eaf79aa41a6bc99c3dd1219caf190f282b5742647bf3abb7b66b7eb221/aiohttp-3.12.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cbcde696c4d4d07b616e10f942e183f90a86ff65e27a03c338067deb1204b148", size = 1668248, upload-time = "2025-05-29T01:36:00.295Z" },
51
+ { url = "https://files.pythonhosted.org/packages/d6/04/2ff57af92f76b0973652710bf9a539d66eb78b4cddace90fc39a5b04bdd7/aiohttp-3.12.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:002e027d4840cb187e5ba6889043e1e90ed114ef8e798133d51db834696a6de2", size = 1699915, upload-time = "2025-05-29T01:36:02.599Z" },
52
+ { url = "https://files.pythonhosted.org/packages/15/d6/0d9916e03cebd697b3c4fc48998733188e8b834368e727b46650a3a1b005/aiohttp-3.12.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cf12c660159897cebdd3ab377550b3563218286f33a57f56753018b1897796ae", size = 1642508, upload-time = "2025-05-29T01:36:05.236Z" },
53
+ { url = "https://files.pythonhosted.org/packages/83/b4/9cf887a3d2cf58828ac6a076d240171d6196dcf7d1edafcb005103f457fb/aiohttp-3.12.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c9e3db6a3c3e53e48b3324eb40e7c5da2a4c78cdcd3ac4e7d7945876dd421de1", size = 1718642, upload-time = "2025-05-29T01:36:07.362Z" },
54
+ { url = "https://files.pythonhosted.org/packages/e5/b0/266567f3c5232e211f1c9bea121a05d115a3f7761c7029ff4ee4f88e6fba/aiohttp-3.12.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e10365dcf61a7c5ed9287c4e20edc0d7a6cc09faf042d7dc570f16ed3291c680", size = 1752113, upload-time = "2025-05-29T01:36:09.519Z" },
55
+ { url = "https://files.pythonhosted.org/packages/61/f9/58b3ce002d1b0b3630ccd02ecbfc6932d00242eb40182e76a65ddbf6ec26/aiohttp-3.12.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c20421e165410bb632f64c5693b1f69e6911dbde197fa0dcd3a0c65d505f776b", size = 1701004, upload-time = "2025-05-29T01:36:11.692Z" },
56
+ { url = "https://files.pythonhosted.org/packages/ee/7c/c1a5e7704fef91f115bd399e47b9613cf11c8caec041a326e966f190c994/aiohttp-3.12.4-cp313-cp313-win32.whl", hash = "sha256:834a2f08eb800af07066af9f26eda4c2d6f7fe0737a3c0aef448f1ba8132fed9", size = 413468, upload-time = "2025-05-29T01:36:13.876Z" },
57
+ { url = "https://files.pythonhosted.org/packages/65/31/e252246332a12abf17f66c8f8360730a5a3a1dd354ca48ccfb90bbb122db/aiohttp-3.12.4-cp313-cp313-win_amd64.whl", hash = "sha256:4c78018c4e8118efac767d5d91c3565919c7e021762c4644198ec5b8d426a071", size = 439411, upload-time = "2025-05-29T01:36:16.365Z" },
58
58
  ]
59
59
 
60
60
  [package.optional-dependencies]
@@ -869,11 +869,11 @@ bcrypt = [
869
869
 
870
870
  [[package]]
871
871
  name = "pyasn1"
872
- version = "0.4.8"
872
+ version = "0.6.1"
873
873
  source = { registry = "https://pypi.org/simple" }
874
- sdist = { url = "https://files.pythonhosted.org/packages/a4/db/fffec68299e6d7bad3d504147f9094830b704527a7fc098b721d38cc7fa7/pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", size = 146820, upload-time = "2019-11-16T17:27:38.772Z" }
874
+ sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" }
875
875
  wheels = [
876
- { url = "https://files.pythonhosted.org/packages/62/1e/a94a8d635fa3ce4cfc7f506003548d0a2447ae76fd5ca53932970fe3053f/pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", size = 77145, upload-time = "2019-11-16T17:27:11.07Z" },
876
+ { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" },
877
877
  ]
878
878
 
879
879
  [[package]]
@@ -1089,16 +1089,16 @@ wheels = [
1089
1089
 
1090
1090
  [[package]]
1091
1091
  name = "python-jose"
1092
- version = "3.4.0"
1092
+ version = "3.5.0"
1093
1093
  source = { registry = "https://pypi.org/simple" }
1094
1094
  dependencies = [
1095
1095
  { name = "ecdsa" },
1096
1096
  { name = "pyasn1" },
1097
1097
  { name = "rsa" },
1098
1098
  ]
1099
- sdist = { url = "https://files.pythonhosted.org/packages/8e/a0/c49687cf40cb6128ea4e0559855aff92cd5ebd1a60a31c08526818c0e51e/python-jose-3.4.0.tar.gz", hash = "sha256:9a9a40f418ced8ecaf7e3b28d69887ceaa76adad3bcaa6dae0d9e596fec1d680", size = 92145, upload-time = "2025-02-18T17:26:41.985Z" }
1099
+ sdist = { url = "https://files.pythonhosted.org/packages/c6/77/3a1c9039db7124eb039772b935f2244fbb73fc8ee65b9acf2375da1c07bf/python_jose-3.5.0.tar.gz", hash = "sha256:fb4eaa44dbeb1c26dcc69e4bd7ec54a1cb8dd64d3b4d81ef08d90ff453f2b01b", size = 92726, upload-time = "2025-05-28T17:31:54.288Z" }
1100
1100
  wheels = [
1101
- { url = "https://files.pythonhosted.org/packages/63/b0/2586ea6b6fd57a994ece0b56418cbe93fff0efb85e2c9eb6b0caf24a4e37/python_jose-3.4.0-py2.py3-none-any.whl", hash = "sha256:9c9f616819652d109bd889ecd1e15e9a162b9b94d682534c9c2146092945b78f", size = 34616, upload-time = "2025-02-18T17:26:40.826Z" },
1101
+ { url = "https://files.pythonhosted.org/packages/d9/c3/0bd11992072e6a1c513b16500a5d07f91a24017c5909b02c72c62d7ad024/python_jose-3.5.0-py2.py3-none-any.whl", hash = "sha256:abd1202f23d34dfad2c3d28cb8617b90acf34132c7afd60abd0b0b7d3cb55771", size = 34624, upload-time = "2025-05-28T17:31:52.802Z" },
1102
1102
  ]
1103
1103
 
1104
1104
  [[package]]
@@ -1149,7 +1149,7 @@ testing = [
1149
1149
 
1150
1150
  [package.metadata]
1151
1151
  requires-dist = [
1152
- { name = "aiohttp", extras = ["speedups"], specifier = "~=3.12.2" },
1152
+ { name = "aiohttp", extras = ["speedups"], specifier = "~=3.12.4" },
1153
1153
  { name = "asyncpg", specifier = "~=0.30.0" },
1154
1154
  { name = "fastapi-users", extras = ["sqlalchemy"], specifier = "~=14.0.1" },
1155
1155
  { name = "fastapi-users-db-sqlalchemy", specifier = "~=7.0.0" },
@@ -1159,8 +1159,8 @@ requires-dist = [
1159
1159
  { name = "msgspec", specifier = "~=0.19.0" },
1160
1160
  { name = "pydantic", extras = ["email"], specifier = "~=2.11.5" },
1161
1161
  { name = "pydantic-settings", specifier = "~=2.9.1" },
1162
- { name = "python-jose", specifier = "==3.4.0" },
1163
- { name = "sqlalchemy", extras = ["asyncio"], specifier = "~=2.0.40" },
1162
+ { name = "python-jose", specifier = "==3.5.0" },
1163
+ { name = "sqlalchemy", extras = ["asyncio"], specifier = "~=2.0.41" },
1164
1164
  { name = "valkey", extras = ["libvalkey"], specifier = "~=6.1.0" },
1165
1165
  { name = "zeep", specifier = "~=4.3.1" },
1166
1166
  ]
@@ -1171,8 +1171,8 @@ dev = [
1171
1171
  { name = "pip", specifier = "==25.1.1" },
1172
1172
  { name = "pre-commit", specifier = "==4.2.0" },
1173
1173
  { name = "pyright", specifier = "==1.1.401" },
1174
- { name = "ruff", specifier = "==0.11.11" },
1175
- { name = "setuptools", specifier = "==80.8.0" },
1174
+ { name = "ruff", specifier = "==0.11.12" },
1175
+ { name = "setuptools", specifier = "==80.9.0" },
1176
1176
  { name = "setuptools-scm", specifier = "==8.3.1" },
1177
1177
  { name = "wheel", specifier = "==0.45.1" },
1178
1178
  ]
@@ -1261,36 +1261,36 @@ wheels = [
1261
1261
 
1262
1262
  [[package]]
1263
1263
  name = "ruff"
1264
- version = "0.11.11"
1265
- source = { registry = "https://pypi.org/simple" }
1266
- sdist = { url = "https://files.pythonhosted.org/packages/b2/53/ae4857030d59286924a8bdb30d213d6ff22d8f0957e738d0289990091dd8/ruff-0.11.11.tar.gz", hash = "sha256:7774173cc7c1980e6bf67569ebb7085989a78a103922fb83ef3dfe230cd0687d", size = 4186707, upload-time = "2025-05-22T19:19:34.363Z" }
1267
- wheels = [
1268
- { url = "https://files.pythonhosted.org/packages/b1/14/f2326676197bab099e2a24473158c21656fbf6a207c65f596ae15acb32b9/ruff-0.11.11-py3-none-linux_armv6l.whl", hash = "sha256:9924e5ae54125ed8958a4f7de320dab7380f6e9fa3195e3dc3b137c6842a0092", size = 10229049, upload-time = "2025-05-22T19:18:45.516Z" },
1269
- { url = "https://files.pythonhosted.org/packages/9a/f3/bff7c92dd66c959e711688b2e0768e486bbca46b2f35ac319bb6cce04447/ruff-0.11.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c8a93276393d91e952f790148eb226658dd275cddfde96c6ca304873f11d2ae4", size = 11053601, upload-time = "2025-05-22T19:18:49.269Z" },
1270
- { url = "https://files.pythonhosted.org/packages/e2/38/8e1a3efd0ef9d8259346f986b77de0f62c7a5ff4a76563b6b39b68f793b9/ruff-0.11.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d6e333dbe2e6ae84cdedefa943dfd6434753ad321764fd937eef9d6b62022bcd", size = 10367421, upload-time = "2025-05-22T19:18:51.754Z" },
1271
- { url = "https://files.pythonhosted.org/packages/b4/50/557ad9dd4fb9d0bf524ec83a090a3932d284d1a8b48b5906b13b72800e5f/ruff-0.11.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7885d9a5e4c77b24e8c88aba8c80be9255fa22ab326019dac2356cff42089fc6", size = 10581980, upload-time = "2025-05-22T19:18:54.011Z" },
1272
- { url = "https://files.pythonhosted.org/packages/c4/b2/e2ed82d6e2739ece94f1bdbbd1d81b712d3cdaf69f0a1d1f1a116b33f9ad/ruff-0.11.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1b5ab797fcc09121ed82e9b12b6f27e34859e4227080a42d090881be888755d4", size = 10089241, upload-time = "2025-05-22T19:18:56.041Z" },
1273
- { url = "https://files.pythonhosted.org/packages/3d/9f/b4539f037a5302c450d7c695c82f80e98e48d0d667ecc250e6bdeb49b5c3/ruff-0.11.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e231ff3132c1119ece836487a02785f099a43992b95c2f62847d29bace3c75ac", size = 11699398, upload-time = "2025-05-22T19:18:58.248Z" },
1274
- { url = "https://files.pythonhosted.org/packages/61/fb/32e029d2c0b17df65e6eaa5ce7aea5fbeaed22dddd9fcfbbf5fe37c6e44e/ruff-0.11.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a97c9babe1d4081037a90289986925726b802d180cca784ac8da2bbbc335f709", size = 12427955, upload-time = "2025-05-22T19:19:00.981Z" },
1275
- { url = "https://files.pythonhosted.org/packages/6e/e3/160488dbb11f18c8121cfd588e38095ba779ae208292765972f7732bfd95/ruff-0.11.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8c4ddcbe8a19f59f57fd814b8b117d4fcea9bee7c0492e6cf5fdc22cfa563c8", size = 12069803, upload-time = "2025-05-22T19:19:03.258Z" },
1276
- { url = "https://files.pythonhosted.org/packages/ff/16/3b006a875f84b3d0bff24bef26b8b3591454903f6f754b3f0a318589dcc3/ruff-0.11.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6224076c344a7694c6fbbb70d4f2a7b730f6d47d2a9dc1e7f9d9bb583faf390b", size = 11242630, upload-time = "2025-05-22T19:19:05.871Z" },
1277
- { url = "https://files.pythonhosted.org/packages/65/0d/0338bb8ac0b97175c2d533e9c8cdc127166de7eb16d028a43c5ab9e75abd/ruff-0.11.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:882821fcdf7ae8db7a951df1903d9cb032bbe838852e5fc3c2b6c3ab54e39875", size = 11507310, upload-time = "2025-05-22T19:19:08.584Z" },
1278
- { url = "https://files.pythonhosted.org/packages/6f/bf/d7130eb26174ce9b02348b9f86d5874eafbf9f68e5152e15e8e0a392e4a3/ruff-0.11.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:dcec2d50756463d9df075a26a85a6affbc1b0148873da3997286caf1ce03cae1", size = 10441144, upload-time = "2025-05-22T19:19:13.621Z" },
1279
- { url = "https://files.pythonhosted.org/packages/b3/f3/4be2453b258c092ff7b1761987cf0749e70ca1340cd1bfb4def08a70e8d8/ruff-0.11.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99c28505ecbaeb6594701a74e395b187ee083ee26478c1a795d35084d53ebd81", size = 10081987, upload-time = "2025-05-22T19:19:15.821Z" },
1280
- { url = "https://files.pythonhosted.org/packages/6c/6e/dfa4d2030c5b5c13db158219f2ec67bf333e8a7748dccf34cfa2a6ab9ebc/ruff-0.11.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9263f9e5aa4ff1dec765e99810f1cc53f0c868c5329b69f13845f699fe74f639", size = 11073922, upload-time = "2025-05-22T19:19:18.104Z" },
1281
- { url = "https://files.pythonhosted.org/packages/ff/f4/f7b0b0c3d32b593a20ed8010fa2c1a01f2ce91e79dda6119fcc51d26c67b/ruff-0.11.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:64ac6f885e3ecb2fdbb71de2701d4e34526651f1e8503af8fb30d4915a3fe345", size = 11568537, upload-time = "2025-05-22T19:19:20.889Z" },
1282
- { url = "https://files.pythonhosted.org/packages/d2/46/0e892064d0adc18bcc81deed9aaa9942a27fd2cd9b1b7791111ce468c25f/ruff-0.11.11-py3-none-win32.whl", hash = "sha256:1adcb9a18802268aaa891ffb67b1c94cd70578f126637118e8099b8e4adcf112", size = 10536492, upload-time = "2025-05-22T19:19:23.642Z" },
1283
- { url = "https://files.pythonhosted.org/packages/1b/d9/232e79459850b9f327e9f1dc9c047a2a38a6f9689e1ec30024841fc4416c/ruff-0.11.11-py3-none-win_amd64.whl", hash = "sha256:748b4bb245f11e91a04a4ff0f96e386711df0a30412b9fe0c74d5bdc0e4a531f", size = 11612562, upload-time = "2025-05-22T19:19:27.013Z" },
1284
- { url = "https://files.pythonhosted.org/packages/ce/eb/09c132cff3cc30b2e7244191dcce69437352d6d6709c0adf374f3e6f476e/ruff-0.11.11-py3-none-win_arm64.whl", hash = "sha256:6c51f136c0364ab1b774767aa8b86331bd8e9d414e2d107db7a2189f35ea1f7b", size = 10735951, upload-time = "2025-05-22T19:19:30.043Z" },
1264
+ version = "0.11.12"
1265
+ source = { registry = "https://pypi.org/simple" }
1266
+ sdist = { url = "https://files.pythonhosted.org/packages/15/0a/92416b159ec00cdf11e5882a9d80d29bf84bba3dbebc51c4898bfbca1da6/ruff-0.11.12.tar.gz", hash = "sha256:43cf7f69c7d7c7d7513b9d59c5d8cafd704e05944f978614aa9faff6ac202603", size = 4202289, upload-time = "2025-05-29T13:31:40.037Z" }
1267
+ wheels = [
1268
+ { url = "https://files.pythonhosted.org/packages/60/cc/53eb79f012d15e136d40a8e8fc519ba8f55a057f60b29c2df34efd47c6e3/ruff-0.11.12-py3-none-linux_armv6l.whl", hash = "sha256:c7680aa2f0d4c4f43353d1e72123955c7a2159b8646cd43402de6d4a3a25d7cc", size = 10285597, upload-time = "2025-05-29T13:30:57.539Z" },
1269
+ { url = "https://files.pythonhosted.org/packages/e7/d7/73386e9fb0232b015a23f62fea7503f96e29c29e6c45461d4a73bac74df9/ruff-0.11.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:2cad64843da9f134565c20bcc430642de897b8ea02e2e79e6e02a76b8dcad7c3", size = 11053154, upload-time = "2025-05-29T13:31:00.865Z" },
1270
+ { url = "https://files.pythonhosted.org/packages/4e/eb/3eae144c5114e92deb65a0cb2c72326c8469e14991e9bc3ec0349da1331c/ruff-0.11.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9b6886b524a1c659cee1758140138455d3c029783d1b9e643f3624a5ee0cb0aa", size = 10403048, upload-time = "2025-05-29T13:31:03.413Z" },
1271
+ { url = "https://files.pythonhosted.org/packages/29/64/20c54b20e58b1058db6689e94731f2a22e9f7abab74e1a758dfba058b6ca/ruff-0.11.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc3a3690aad6e86c1958d3ec3c38c4594b6ecec75c1f531e84160bd827b2012", size = 10597062, upload-time = "2025-05-29T13:31:05.539Z" },
1272
+ { url = "https://files.pythonhosted.org/packages/29/3a/79fa6a9a39422a400564ca7233a689a151f1039110f0bbbabcb38106883a/ruff-0.11.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f97fdbc2549f456c65b3b0048560d44ddd540db1f27c778a938371424b49fe4a", size = 10155152, upload-time = "2025-05-29T13:31:07.986Z" },
1273
+ { url = "https://files.pythonhosted.org/packages/e5/a4/22c2c97b2340aa968af3a39bc38045e78d36abd4ed3fa2bde91c31e712e3/ruff-0.11.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74adf84960236961090e2d1348c1a67d940fd12e811a33fb3d107df61eef8fc7", size = 11723067, upload-time = "2025-05-29T13:31:10.57Z" },
1274
+ { url = "https://files.pythonhosted.org/packages/bc/cf/3e452fbd9597bcd8058856ecd42b22751749d07935793a1856d988154151/ruff-0.11.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b56697e5b8bcf1d61293ccfe63873aba08fdbcbbba839fc046ec5926bdb25a3a", size = 12460807, upload-time = "2025-05-29T13:31:12.88Z" },
1275
+ { url = "https://files.pythonhosted.org/packages/2f/ec/8f170381a15e1eb7d93cb4feef8d17334d5a1eb33fee273aee5d1f8241a3/ruff-0.11.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d47afa45e7b0eaf5e5969c6b39cbd108be83910b5c74626247e366fd7a36a13", size = 12063261, upload-time = "2025-05-29T13:31:15.236Z" },
1276
+ { url = "https://files.pythonhosted.org/packages/0d/bf/57208f8c0a8153a14652a85f4116c0002148e83770d7a41f2e90b52d2b4e/ruff-0.11.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bf9603fe1bf949de8b09a2da896f05c01ed7a187f4a386cdba6760e7f61be", size = 11329601, upload-time = "2025-05-29T13:31:18.68Z" },
1277
+ { url = "https://files.pythonhosted.org/packages/c3/56/edf942f7fdac5888094d9ffa303f12096f1a93eb46570bcf5f14c0c70880/ruff-0.11.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08033320e979df3b20dba567c62f69c45e01df708b0f9c83912d7abd3e0801cd", size = 11522186, upload-time = "2025-05-29T13:31:21.216Z" },
1278
+ { url = "https://files.pythonhosted.org/packages/ed/63/79ffef65246911ed7e2290aeece48739d9603b3a35f9529fec0fc6c26400/ruff-0.11.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:929b7706584f5bfd61d67d5070f399057d07c70585fa8c4491d78ada452d3bef", size = 10449032, upload-time = "2025-05-29T13:31:23.417Z" },
1279
+ { url = "https://files.pythonhosted.org/packages/88/19/8c9d4d8a1c2a3f5a1ea45a64b42593d50e28b8e038f1aafd65d6b43647f3/ruff-0.11.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7de4a73205dc5756b8e09ee3ed67c38312dce1aa28972b93150f5751199981b5", size = 10129370, upload-time = "2025-05-29T13:31:25.777Z" },
1280
+ { url = "https://files.pythonhosted.org/packages/bc/0f/2d15533eaa18f460530a857e1778900cd867ded67f16c85723569d54e410/ruff-0.11.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2635c2a90ac1b8ca9e93b70af59dfd1dd2026a40e2d6eebaa3efb0465dd9cf02", size = 11123529, upload-time = "2025-05-29T13:31:28.396Z" },
1281
+ { url = "https://files.pythonhosted.org/packages/4f/e2/4c2ac669534bdded835356813f48ea33cfb3a947dc47f270038364587088/ruff-0.11.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d05d6a78a89166f03f03a198ecc9d18779076ad0eec476819467acb401028c0c", size = 11577642, upload-time = "2025-05-29T13:31:30.647Z" },
1282
+ { url = "https://files.pythonhosted.org/packages/a7/9b/c9ddf7f924d5617a1c94a93ba595f4b24cb5bc50e98b94433ab3f7ad27e5/ruff-0.11.12-py3-none-win32.whl", hash = "sha256:f5a07f49767c4be4772d161bfc049c1f242db0cfe1bd976e0f0886732a4765d6", size = 10475511, upload-time = "2025-05-29T13:31:32.917Z" },
1283
+ { url = "https://files.pythonhosted.org/packages/fd/d6/74fb6d3470c1aada019ffff33c0f9210af746cca0a4de19a1f10ce54968a/ruff-0.11.12-py3-none-win_amd64.whl", hash = "sha256:5a4d9f8030d8c3a45df201d7fb3ed38d0219bccd7955268e863ee4a115fa0832", size = 11523573, upload-time = "2025-05-29T13:31:35.782Z" },
1284
+ { url = "https://files.pythonhosted.org/packages/44/42/d58086ec20f52d2b0140752ae54b355ea2be2ed46f914231136dd1effcc7/ruff-0.11.12-py3-none-win_arm64.whl", hash = "sha256:65194e37853158d368e333ba282217941029a28ea90913c67e558c611d04daa5", size = 10697770, upload-time = "2025-05-29T13:31:38.009Z" },
1285
1285
  ]
1286
1286
 
1287
1287
  [[package]]
1288
1288
  name = "setuptools"
1289
- version = "80.8.0"
1289
+ version = "80.9.0"
1290
1290
  source = { registry = "https://pypi.org/simple" }
1291
- sdist = { url = "https://files.pythonhosted.org/packages/8d/d2/ec1acaaff45caed5c2dedb33b67055ba9d4e96b091094df90762e60135fe/setuptools-80.8.0.tar.gz", hash = "sha256:49f7af965996f26d43c8ae34539c8d99c5042fbff34302ea151eaa9c207cd257", size = 1319720, upload-time = "2025-05-20T14:02:53.503Z" }
1291
+ sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" }
1292
1292
  wheels = [
1293
- { url = "https://files.pythonhosted.org/packages/58/29/93c53c098d301132196c3238c312825324740851d77a8500a2462c0fd888/setuptools-80.8.0-py3-none-any.whl", hash = "sha256:95a60484590d24103af13b686121328cc2736bee85de8936383111e421b9edc0", size = 1201470, upload-time = "2025-05-20T14:02:51.348Z" },
1293
+ { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" },
1294
1294
  ]
1295
1295
 
1296
1296
  [[package]]
@@ -1,79 +0,0 @@
1
- from dataclasses import dataclass
2
- from datetime import datetime, date
3
- from decimal import Decimal
4
- from uuid import UUID, uuid4
5
-
6
- import msgspec
7
- import pytest
8
-
9
-
10
- @pytest.fixture
11
- def data_dict():
12
- return {
13
- 'A': 1,
14
- 'B': 'B',
15
- 'C': None,
16
- 'D': datetime(2023, 7, 25, 1, 2, 3),
17
- 'E': date(2023, 7, 24),
18
- 'F': Decimal('1.23'),
19
- }
20
-
21
-
22
- @dataclass
23
- class TestData:
24
- a: int
25
- b: str
26
- c: str | None
27
- d: datetime
28
- e: date
29
- f: Decimal
30
-
31
-
32
- @pytest.fixture
33
- def data_dataclass():
34
- return TestData(
35
- a=1,
36
- b='B',
37
- c=None,
38
- d=datetime(2023, 7, 25, 1, 2, 3),
39
- e=date(2023, 7, 24),
40
- f=Decimal('1.23')
41
- )
42
-
43
-
44
- class SubStruc(msgspec.Struct):
45
- uid: UUID
46
- name: str
47
-
48
-
49
- class TestStruct(msgspec.Struct):
50
- a: int
51
- b: str
52
- c: str | None
53
- d: datetime
54
- e: date
55
- f: Decimal
56
- sub: SubStruc
57
-
58
-
59
- @pytest.fixture
60
- def data_struct() -> TestStruct:
61
- return TestStruct(
62
- a=1,
63
- b='B',
64
- c=None,
65
- d=datetime(2023, 7, 25, 1, 2, 3),
66
- e=date(2023, 7, 24),
67
- f=Decimal('1.23'),
68
- sub=SubStruc(uid=uuid4(), name='sub-struct')
69
- )
70
-
71
-
72
- @pytest.fixture
73
- def s3_file_objects() -> tuple:
74
- return (
75
- ('file_a.txt', datetime(2024, 1, 1), b'ABCDE', ),
76
- ('file_b.txt', datetime(2024, 1, 2), b'FGHIJ', ),
77
- ('file_c.txt', datetime(2024, 1, 3), b'KLMNO', ),
78
- ('file_d.txt', datetime(2024, 1, 4), b'PQRST', ),
79
- )