Skip to content

Commit 72e8a40

Browse files
committed
Fix compatibility with Python 3.9 and 3.10
Closes #194
1 parent ace5d08 commit 72e8a40

File tree

9 files changed

+51
-16
lines changed

9 files changed

+51
-16
lines changed

CHANGELOG.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
12+
- Compatibility with Python 3.9 and Python 3.10
13+
1014
## [3.0.1] - 2025-04-15
1115

1216
### Fixed
@@ -37,7 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3741
- Add `filter_tasks`, extracting that workflow from `get_tasks`
3842
- Paginate results via an `Iterator` in `get_tasks`, `filter_task`, `get_projects`,
3943
`get_collaborators`, `get_sections`, `get_comments`, `get_labels`, `get_shared_labels`
40-
- Receive `date` and `datetime` arguments as objects, not strings
44+
- Receive `date` and `datetime` arguments as objects, not strings
4145
- Remove support for `X-Request-Id` header, unused on the API level
4246
- "Hide" internal modules and functions
4347
- Task URLs are now obtained on demand, improving performance when not needed

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ warn_required_dynamic_aliases = true
8181
warn_untyped_fields = true
8282

8383
[tool.ruff]
84-
target-version = "py313" # used by some linters like UP, FA, PERF
84+
target-version = "py39" # used by some linters like UP, FA, PERF
8585

8686
[tool.ruff.lint]
8787
select = [

tests/data/test_defaults.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ class PaginatedItems(TypedDict):
216216
"id": "6X7rM8997g3RQmvh",
217217
"content": "A comment",
218218
"posted_uid": "34567",
219-
"posted_at": "2019-09-22T07:00:00.00000Z",
219+
"posted_at": "2019-09-22T07:00:00.000000Z",
220220
"task_id": "6X7rM8997g3RQmvh",
221221
"project_id": "6X7rfEVP8hvv25ZQ",
222222
"attachment": DEFAULT_ATTACHMENT_RESPONSE,

tests/test_api_completed_tasks.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
from __future__ import annotations
22

3-
from datetime import UTC, datetime
3+
import sys
4+
from datetime import datetime, timezone
45
from typing import TYPE_CHECKING, Any
56

7+
if sys.version_info >= (3, 11):
8+
from datetime import UTC
9+
else:
10+
UTC = timezone.utc
11+
612
import pytest
713
import responses
814

tests/test_api_tasks.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
from __future__ import annotations
22

3-
from datetime import UTC, datetime
3+
import sys
4+
from datetime import datetime, timezone
45
from typing import TYPE_CHECKING, Any
56

7+
if sys.version_info >= (3, 11):
8+
from datetime import UTC
9+
else:
10+
UTC = timezone.utc
11+
612
import pytest
713
import responses
814

todoist_api_python/_core/utils.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1+
from __future__ import annotations
2+
13
import asyncio
2-
from collections.abc import AsyncGenerator, Callable, Iterator
3-
from datetime import UTC, date, datetime
4-
from typing import TypeVar, cast
4+
import sys
5+
from datetime import date, datetime, timezone
6+
from typing import TYPE_CHECKING, TypeVar, cast
7+
8+
if TYPE_CHECKING:
9+
from collections.abc import AsyncGenerator, Callable, Iterator
10+
11+
if sys.version_info >= (3, 11):
12+
from datetime import UTC
13+
else:
14+
UTC = timezone.utc
515

616
T = TypeVar("T")
717

todoist_api_python/api.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from __future__ import annotations
22

3+
import sys
34
from collections.abc import Callable, Iterator
4-
from typing import TYPE_CHECKING, Annotated, Any, Literal, Self, TypeVar
5+
from typing import TYPE_CHECKING, Annotated, Any, Literal, TypeVar
56
from weakref import finalize
67

78
import requests
@@ -41,6 +42,11 @@
4142
from datetime import date, datetime
4243
from types import TracebackType
4344

45+
if sys.version_info >= (3, 11):
46+
from typing import Self
47+
else:
48+
Self = TypeVar("Self", bound="TodoistAPI")
49+
4450

4551
LanguageCode = Annotated[str, Predicate(lambda x: len(x) == 2)] # noqa: PLR2004
4652
ColorString = Annotated[
@@ -103,8 +109,7 @@ def __enter__(self) -> Self:
103109
The with statement will bind this method's return value to the target(s)
104110
specified in the as clause of the statement, if any.
105111
106-
:return: The TodoistAPI instance.
107-
:rtype: Self
112+
:return: This TodoistAPI instance.
108113
"""
109114
return self
110115

@@ -463,7 +468,6 @@ def uncomplete_task(self, task_id: str) -> bool:
463468
:param task_id: The ID of the task to reopen.
464469
:return: True if the task was uncompleted successfully,
465470
False otherwise (possibly raise `HTTPError` instead).
466-
:rtype: bool
467471
:raises requests.exceptions.HTTPError: If the API request fails.
468472
"""
469473
endpoint = get_api_url(f"{TASKS_PATH}/{task_id}/reopen")

todoist_api_python/api_async.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING, Annotated, Literal, Self
3+
import sys
4+
from typing import TYPE_CHECKING, Annotated, Literal, TypeVar
45

56
from annotated_types import Ge, Le, MaxLen, MinLen
67

@@ -30,6 +31,11 @@
3031
ViewStyle,
3132
)
3233

34+
if sys.version_info >= (3, 11):
35+
from typing import Self
36+
else:
37+
Self = TypeVar("Self", bound="TodoistAPIAsync")
38+
3339

3440
class TodoistAPIAsync:
3541
"""
@@ -58,7 +64,7 @@ async def __aenter__(self) -> Self:
5864
The with statement will bind this method's return value to the target(s)
5965
specified in the as clause of the statement, if any.
6066
61-
:return: The TodoistAPIAsync instance.
67+
:return: This TodoistAPIAsync instance.
6268
"""
6369
return self
6470

@@ -332,7 +338,6 @@ async def uncomplete_task(self, task_id: str) -> bool:
332338
:param task_id: The ID of the task to reopen.
333339
:return: True if the task was uncompleted successfully,
334340
False otherwise (possibly raise `HTTPError` instead).
335-
:rtype: bool
336341
:raises requests.exceptions.HTTPError: If the API request fails.
337342
"""
338343
return await run_async(lambda: self._api.uncomplete_task(task_id))

todoist_api_python/models.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
ViewStyle = Literal["list", "board", "calendar"]
1313
DurationUnit = Literal["minute", "day"]
1414
ApiDate = UTCDateTimePattern["%FT%T.%fZ"] # type: ignore[valid-type]
15-
ApiDue = Union[ # noqa: UP007 # https://github.com/rnag/dataclass-wizard/issues/189
15+
ApiDue = Union[ # https://github.com/rnag/dataclass-wizard/issues/189
1616
DatePattern["%F"], DateTimePattern["%FT%T"], UTCDateTimePattern["%FT%TZ"] # type: ignore[valid-type] # noqa: F722
1717
]
1818

0 commit comments

Comments
 (0)