Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Compatibility with Python 3.9 and Python 3.10

## [3.0.1] - 2025-04-15

### Fixed
Expand Down Expand Up @@ -37,7 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add `filter_tasks`, extracting that workflow from `get_tasks`
- Paginate results via an `Iterator` in `get_tasks`, `filter_task`, `get_projects`,
`get_collaborators`, `get_sections`, `get_comments`, `get_labels`, `get_shared_labels`
- Receive `date` and `datetime` arguments as objects, not strings
- Receive `date` and `datetime` arguments as objects, not strings
- Remove support for `X-Request-Id` header, unused on the API level
- "Hide" internal modules and functions
- Task URLs are now obtained on demand, improving performance when not needed
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ warn_required_dynamic_aliases = true
warn_untyped_fields = true

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

[tool.ruff.lint]
select = [
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ class PaginatedItems(TypedDict):
"id": "6X7rM8997g3RQmvh",
"content": "A comment",
"posted_uid": "34567",
"posted_at": "2019-09-22T07:00:00.00000Z",
"posted_at": "2019-09-22T07:00:00.000000Z",
"task_id": "6X7rM8997g3RQmvh",
"project_id": "6X7rfEVP8hvv25ZQ",
"attachment": DEFAULT_ATTACHMENT_RESPONSE,
Expand Down
8 changes: 7 additions & 1 deletion tests/test_api_completed_tasks.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
from __future__ import annotations

from datetime import UTC, datetime
import sys
from datetime import datetime, timezone
from typing import TYPE_CHECKING, Any

if sys.version_info >= (3, 11):
from datetime import UTC
else:
UTC = timezone.utc

import pytest
import responses

Expand Down
8 changes: 7 additions & 1 deletion tests/test_api_tasks.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
from __future__ import annotations

from datetime import UTC, datetime
import sys
from datetime import datetime, timezone
from typing import TYPE_CHECKING, Any

if sys.version_info >= (3, 11):
from datetime import UTC
else:
UTC = timezone.utc

import pytest
import responses

Expand Down
16 changes: 13 additions & 3 deletions todoist_api_python/_core/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
from __future__ import annotations

import asyncio
from collections.abc import AsyncGenerator, Callable, Iterator
from datetime import UTC, date, datetime
from typing import TypeVar, cast
import sys
from datetime import date, datetime, timezone
from typing import TYPE_CHECKING, TypeVar, cast

if TYPE_CHECKING:
from collections.abc import AsyncGenerator, Callable, Iterator

if sys.version_info >= (3, 11):
from datetime import UTC
else:
UTC = timezone.utc

T = TypeVar("T")

Expand Down
12 changes: 8 additions & 4 deletions todoist_api_python/api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from __future__ import annotations

import sys
from collections.abc import Callable, Iterator
from typing import TYPE_CHECKING, Annotated, Any, Literal, Self, TypeVar
from typing import TYPE_CHECKING, Annotated, Any, Literal, TypeVar
from weakref import finalize

import requests
Expand Down Expand Up @@ -41,6 +42,11 @@
from datetime import date, datetime
from types import TracebackType

if sys.version_info >= (3, 11):
from typing import Self
else:
Self = TypeVar("Self", bound="TodoistAPI")


LanguageCode = Annotated[str, Predicate(lambda x: len(x) == 2)] # noqa: PLR2004
ColorString = Annotated[
Expand Down Expand Up @@ -103,8 +109,7 @@ def __enter__(self) -> Self:
The with statement will bind this method's return value to the target(s)
specified in the as clause of the statement, if any.

:return: The TodoistAPI instance.
:rtype: Self
:return: This TodoistAPI instance.
"""
return self

Expand Down Expand Up @@ -463,7 +468,6 @@ def uncomplete_task(self, task_id: str) -> bool:
:param task_id: The ID of the task to reopen.
:return: True if the task was uncompleted successfully,
False otherwise (possibly raise `HTTPError` instead).
:rtype: bool
:raises requests.exceptions.HTTPError: If the API request fails.
"""
endpoint = get_api_url(f"{TASKS_PATH}/{task_id}/reopen")
Expand Down
11 changes: 8 additions & 3 deletions todoist_api_python/api_async.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Annotated, Literal, Self
import sys
from typing import TYPE_CHECKING, Annotated, Literal, TypeVar

from annotated_types import Ge, Le, MaxLen, MinLen

Expand Down Expand Up @@ -30,6 +31,11 @@
ViewStyle,
)

if sys.version_info >= (3, 11):
from typing import Self
else:
Self = TypeVar("Self", bound="TodoistAPIAsync")


class TodoistAPIAsync:
"""
Expand Down Expand Up @@ -58,7 +64,7 @@ async def __aenter__(self) -> Self:
The with statement will bind this method's return value to the target(s)
specified in the as clause of the statement, if any.

:return: The TodoistAPIAsync instance.
:return: This TodoistAPIAsync instance.
"""
return self

Expand Down Expand Up @@ -332,7 +338,6 @@ async def uncomplete_task(self, task_id: str) -> bool:
:param task_id: The ID of the task to reopen.
:return: True if the task was uncompleted successfully,
False otherwise (possibly raise `HTTPError` instead).
:rtype: bool
:raises requests.exceptions.HTTPError: If the API request fails.
"""
return await run_async(lambda: self._api.uncomplete_task(task_id))
Expand Down
2 changes: 1 addition & 1 deletion todoist_api_python/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
ViewStyle = Literal["list", "board", "calendar"]
DurationUnit = Literal["minute", "day"]
ApiDate = UTCDateTimePattern["%FT%T.%fZ"] # type: ignore[valid-type]
ApiDue = Union[ # noqa: UP007 # https://github.com/rnag/dataclass-wizard/issues/189
ApiDue = Union[ # https://github.com/rnag/dataclass-wizard/issues/189
DatePattern["%F"], DateTimePattern["%FT%T"], UTCDateTimePattern["%FT%TZ"] # type: ignore[valid-type] # noqa: F722
]

Expand Down