From 9aa4c0e56bebd774fb2720c2e3140d6ef308f49c Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 8 Apr 2024 21:57:37 +0000 Subject: [PATCH] refactor(deltachat-rpc-client): use `list`, `set` and `tuple` instead of `typing` `typing.List` is deprecated according to https://docs.python.org/3/library/typing.html#typing.List Similar for `Set` and `Dict`. `from __future__ import annotations` is for compatibility with Python 3.7. --- .../src/deltachat_rpc_client/account.py | 24 ++++++++++--------- .../src/deltachat_rpc_client/chat.py | 18 +++++++------- .../src/deltachat_rpc_client/client.py | 11 ++++----- .../src/deltachat_rpc_client/deltachat.py | 8 ++++--- .../src/deltachat_rpc_client/direct_imap.py | 11 +++++---- .../src/deltachat_rpc_client/events.py | 8 ++++--- .../src/deltachat_rpc_client/pytestplugin.py | 6 +++-- .../src/deltachat_rpc_client/rpc.py | 10 ++++---- 8 files changed, 54 insertions(+), 42 deletions(-) diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/account.py b/deltachat-rpc-client/src/deltachat_rpc_client/account.py index d0f87ee2fb..dbdb1dbfa3 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/account.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/account.py @@ -1,5 +1,7 @@ +from __future__ import annotations + from dataclasses import dataclass -from typing import TYPE_CHECKING, List, Optional, Tuple, Union +from typing import TYPE_CHECKING, Optional, Union from warnings import warn from ._utils import AttrDict, futuremethod @@ -126,7 +128,7 @@ def get_contact_by_addr(self, address: str) -> Optional[Contact]: contact_id = self._rpc.lookup_contact_id_by_addr(self.id, address) return contact_id and Contact(self, contact_id) - def get_blocked_contacts(self) -> List[AttrDict]: + def get_blocked_contacts(self) -> list[AttrDict]: """Return a list with snapshots of all blocked contacts.""" contacts = self._rpc.get_blocked_contacts(self.id) return [AttrDict(contact=Contact(self, contact["id"]), **contact) for contact in contacts] @@ -151,7 +153,7 @@ def get_contacts( with_self: bool = False, verified_only: bool = False, snapshot: bool = False, - ) -> Union[List[Contact], List[AttrDict]]: + ) -> Union[list[Contact], list[AttrDict]]: """Get a filtered list of contacts. :param query: if a string is specified, only return contacts @@ -186,7 +188,7 @@ def get_chatlist( no_specials: bool = False, alldone_hint: bool = False, snapshot: bool = False, - ) -> Union[List[Chat], List[AttrDict]]: + ) -> Union[list[Chat], list[AttrDict]]: """Return list of chats. :param query: if a string is specified only chats matching this query are returned. @@ -244,7 +246,7 @@ def secure_join(self, qrdata: str) -> Chat: """ return Chat(self, self._rpc.secure_join(self.id, qrdata)) - def get_qr_code(self) -> Tuple[str, str]: + def get_qr_code(self) -> tuple[str, str]: """Get Setup-Contact QR Code text and SVG data. this data needs to be transferred to another Delta Chat account @@ -256,15 +258,15 @@ def get_message_by_id(self, msg_id: int) -> Message: """Return the Message instance with the given ID.""" return Message(self, msg_id) - def mark_seen_messages(self, messages: List[Message]) -> None: + def mark_seen_messages(self, messages: list[Message]) -> None: """Mark the given set of messages as seen.""" self._rpc.markseen_msgs(self.id, [msg.id for msg in messages]) - def delete_messages(self, messages: List[Message]) -> None: + def delete_messages(self, messages: list[Message]) -> None: """Delete messages (local and remote).""" self._rpc.delete_messages(self.id, [msg.id for msg in messages]) - def get_fresh_messages(self) -> List[Message]: + def get_fresh_messages(self) -> list[Message]: """Return the list of fresh messages, newest messages first. This call is intended for displaying notifications. @@ -274,12 +276,12 @@ def get_fresh_messages(self) -> List[Message]: fresh_msg_ids = self._rpc.get_fresh_msgs(self.id) return [Message(self, msg_id) for msg_id in fresh_msg_ids] - def get_next_messages(self) -> List[Message]: + def get_next_messages(self) -> list[Message]: """Return a list of next messages.""" next_msg_ids = self._rpc.get_next_msgs(self.id) return [Message(self, msg_id) for msg_id in next_msg_ids] - def wait_next_messages(self) -> List[Message]: + def wait_next_messages(self) -> list[Message]: """Wait for new messages and return a list of them.""" next_msg_ids = self._rpc.wait_next_msgs(self.id) return [Message(self, msg_id) for msg_id in next_msg_ids] @@ -309,7 +311,7 @@ def wait_for_reactions_changed(self): if event.kind == EventType.REACTIONS_CHANGED: return event - def get_fresh_messages_in_arrival_order(self) -> List[Message]: + def get_fresh_messages_in_arrival_order(self) -> list[Message]: """Return fresh messages list sorted in the order of their arrival, with ascending IDs.""" warn( "get_fresh_messages_in_arrival_order is deprecated, use get_next_messages instead.", diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/chat.py b/deltachat-rpc-client/src/deltachat_rpc_client/chat.py index 7bcaba48f6..e547c17a4b 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/chat.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/chat.py @@ -1,6 +1,8 @@ +from __future__ import annotations + import calendar from dataclasses import dataclass -from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union +from typing import TYPE_CHECKING, Optional, Union from ._utils import AttrDict from .const import ChatVisibility, ViewType @@ -93,7 +95,7 @@ def get_encryption_info(self) -> str: """Return encryption info for this chat.""" return self._rpc.get_chat_encryption_info(self.account.id, self.id) - def get_qr_code(self) -> Tuple[str, str]: + def get_qr_code(self) -> tuple[str, str]: """Get Join-Group QR code text and SVG data.""" return self._rpc.get_chat_securejoin_qr_code_svg(self.account.id, self.id) @@ -117,7 +119,7 @@ def send_message( html: Optional[str] = None, viewtype: Optional[ViewType] = None, file: Optional[str] = None, - location: Optional[Tuple[float, float]] = None, + location: Optional[tuple[float, float]] = None, override_sender_name: Optional[str] = None, quoted_msg: Optional[Union[int, Message]] = None, ) -> Message: @@ -156,7 +158,7 @@ def send_sticker(self, path: str) -> Message: msg_id = self._rpc.send_sticker(self.account.id, self.id, path) return Message(self.account, msg_id) - def forward_messages(self, messages: List[Message]) -> None: + def forward_messages(self, messages: list[Message]) -> None: """Forward a list of messages to this chat.""" msg_ids = [msg.id for msg in messages] self._rpc.forward_messages(self.account.id, msg_ids, self.id) @@ -188,7 +190,7 @@ def get_draft(self) -> Optional[AttrDict]: snapshot["message"] = Message(self.account, snapshot.id) return snapshot - def get_messages(self, info_only: bool = False, add_daymarker: bool = False) -> List[Message]: + def get_messages(self, info_only: bool = False, add_daymarker: bool = False) -> list[Message]: """get the list of messages in this chat.""" msgs = self._rpc.get_message_ids(self.account.id, self.id, info_only, add_daymarker) return [Message(self.account, msg_id) for msg_id in msgs] @@ -223,7 +225,7 @@ def remove_contact(self, *contact: Union[int, str, Contact]) -> None: contact_id = cnt self._rpc.remove_contact_from_chat(self.account.id, self.id, contact_id) - def get_contacts(self) -> List[Contact]: + def get_contacts(self) -> list[Contact]: """Get the contacts belonging to this chat. For single/direct chats self-address is not included. @@ -247,7 +249,7 @@ def get_locations( contact: Optional[Contact] = None, timestamp_from: Optional["datetime"] = None, timestamp_to: Optional["datetime"] = None, - ) -> List[AttrDict]: + ) -> list[AttrDict]: """Get list of location snapshots for the given contact in the given timespan.""" time_from = calendar.timegm(timestamp_from.utctimetuple()) if timestamp_from else 0 time_to = calendar.timegm(timestamp_to.utctimetuple()) if timestamp_to else 0 @@ -255,7 +257,7 @@ def get_locations( result = self._rpc.get_locations(self.account.id, self.id, contact_id, time_from, time_to) locations = [] - contacts: Dict[int, Contact] = {} + contacts: dict[int, Contact] = {} for loc in result: location = AttrDict(loc) location["chat"] = self diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/client.py b/deltachat-rpc-client/src/deltachat_rpc_client/client.py index 85cc18dee1..cceda316eb 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/client.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/client.py @@ -1,14 +1,13 @@ """Event loop implementations offering high level event handling/hooking.""" +from __future__ import annotations + import logging from typing import ( TYPE_CHECKING, Callable, - Dict, Iterable, Optional, - Set, - Tuple, Type, Union, ) @@ -39,16 +38,16 @@ class Client: def __init__( self, account: "Account", - hooks: Optional[Iterable[Tuple[Callable, Union[type, EventFilter]]]] = None, + hooks: Optional[Iterable[tuple[Callable, Union[type, EventFilter]]]] = None, logger: Optional[logging.Logger] = None, ) -> None: self.account = account self.logger = logger or logging - self._hooks: Dict[type, Set[tuple]] = {} + self._hooks: dict[type, set[tuple]] = {} self._should_process_messages = 0 self.add_hooks(hooks or []) - def add_hooks(self, hooks: Iterable[Tuple[Callable, Union[type, EventFilter]]]) -> None: + def add_hooks(self, hooks: Iterable[tuple[Callable, Union[type, EventFilter]]]) -> None: for hook, event in hooks: self.add_hook(hook, event) diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/deltachat.py b/deltachat-rpc-client/src/deltachat_rpc_client/deltachat.py index ec3ed2d761..c972a865e2 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/deltachat.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/deltachat.py @@ -1,4 +1,6 @@ -from typing import TYPE_CHECKING, Dict, List +from __future__ import annotations + +from typing import TYPE_CHECKING from ._utils import AttrDict from .account import Account @@ -21,7 +23,7 @@ def add_account(self) -> Account: account_id = self.rpc.add_account() return Account(self, account_id) - def get_all_accounts(self) -> List[Account]: + def get_all_accounts(self) -> list[Account]: """Return a list of all available accounts.""" account_ids = self.rpc.get_all_account_ids() return [Account(self, account_id) for account_id in account_ids] @@ -44,6 +46,6 @@ def get_system_info(self) -> AttrDict: """Get information about the Delta Chat core in this system.""" return AttrDict(self.rpc.get_system_info()) - def set_translations(self, translations: Dict[str, str]) -> None: + def set_translations(self, translations: dict[str, str]) -> None: """Set stock translation strings.""" self.rpc.set_stock_strings(translations) diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/direct_imap.py b/deltachat-rpc-client/src/deltachat_rpc_client/direct_imap.py index b476c6d443..7d384784d6 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/direct_imap.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/direct_imap.py @@ -2,12 +2,13 @@ Internal Python-level IMAP handling used by the tests. """ +from __future__ import annotations + import imaplib import io import pathlib import ssl from contextlib import contextmanager -from typing import List from imap_tools import ( AND, @@ -87,7 +88,7 @@ def select_config_folder(self, config_name: str): return self.select_folder(foldername) return None - def list_folders(self) -> List[str]: + def list_folders(self) -> list[str]: """return list of all existing folder names.""" assert not self._idling return [folder.name for folder in self.conn.folder.list()] @@ -102,11 +103,11 @@ def delete(self, uid_list: str, expunge=True): if expunge: self.conn.expunge() - def get_all_messages(self) -> List[MailMessage]: + def get_all_messages(self) -> list[MailMessage]: assert not self._idling return list(self.conn.fetch()) - def get_unread_messages(self) -> List[str]: + def get_unread_messages(self) -> list[str]: assert not self._idling return [msg.uid for msg in self.conn.fetch(AND(seen=False))] @@ -198,7 +199,7 @@ def __init__(self, direct_imap) -> None: self.direct_imap.conn.fetch("1:*") self.direct_imap.conn.idle.start() - def check(self, timeout=None) -> List[bytes]: + def check(self, timeout=None) -> list[bytes]: """(blocking) wait for next idle message from server.""" self.log("imap-direct: calling idle_check") res = self.direct_imap.conn.idle.poll(timeout=timeout) diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/events.py b/deltachat-rpc-client/src/deltachat_rpc_client/events.py index 8d20f74545..ca46f5b77d 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/events.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/events.py @@ -1,8 +1,10 @@ """High-level classes for event processing and filtering.""" +from __future__ import annotations + import re from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Callable, Iterable, Iterator, Optional, Set, Tuple, Union +from typing import TYPE_CHECKING, Callable, Iterable, Iterator, Optional, Union from .const import EventType @@ -263,9 +265,9 @@ class HookCollection: """ def __init__(self) -> None: - self._hooks: Set[Tuple[Callable, Union[type, EventFilter]]] = set() + self._hooks: set[tuple[Callable, Union[type, EventFilter]]] = set() - def __iter__(self) -> Iterator[Tuple[Callable, Union[type, EventFilter]]]: + def __iter__(self) -> Iterator[tuple[Callable, Union[type, EventFilter]]]: return iter(self._hooks) def on(self, event: Union[type, EventFilter]) -> Callable: # noqa diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/pytestplugin.py b/deltachat-rpc-client/src/deltachat_rpc_client/pytestplugin.py index 7d0ce5a4f4..dbc1bb274a 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/pytestplugin.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/pytestplugin.py @@ -1,6 +1,8 @@ +from __future__ import annotations + import os import random -from typing import AsyncGenerator, List, Optional +from typing import AsyncGenerator, Optional import pytest @@ -57,7 +59,7 @@ def get_online_account(self): account.bring_online() return account - def get_online_accounts(self, num: int) -> List[Account]: + def get_online_accounts(self, num: int) -> list[Account]: futures = [self.get_online_account.future() for _ in range(num)] return [f() for f in futures] diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/rpc.py b/deltachat-rpc-client/src/deltachat_rpc_client/rpc.py index 34d0df3d62..da95d42b81 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/rpc.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/rpc.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import itertools import json import logging @@ -6,7 +8,7 @@ import sys from queue import Queue from threading import Event, Thread -from typing import Any, Dict, Iterator, Optional +from typing import Any, Iterator, Optional class JsonRpcError(Exception): @@ -67,11 +69,11 @@ def __init__(self, accounts_dir: Optional[str] = None, **kwargs): self._kwargs = kwargs self.process: subprocess.Popen self.id_iterator: Iterator[int] - self.event_queues: Dict[int, Queue] + self.event_queues: dict[int, Queue] # Map from request ID to `threading.Event`. - self.request_events: Dict[int, Event] + self.request_events: dict[int, Event] # Map from request ID to the result. - self.request_results: Dict[int, Any] + self.request_results: dict[int, Any] self.request_queue: Queue[Any] self.closing: bool self.reader_thread: Thread