From 9571a622ed63e5cbb3360dc1ad04d89a95ac3102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Thu, 27 Feb 2025 22:59:18 +0100 Subject: [PATCH] [openpgp] Improve type annotations --- openpgp/backend/base.py | 4 +--- openpgp/backend/gpgme.py | 26 ++++++++++++++++---------- openpgp/backend/gpgme_types.py | 16 ---------------- openpgp/backend/pygpg.py | 5 +++++ openpgp/backend/sql.py | 2 +- openpgp/gtk/wizard.py | 2 +- typings/gpg/core.pyi | 7 +++++-- typings/gpg/results.pyi | 32 ++++++++++++++++++++++++++++---- 8 files changed, 57 insertions(+), 37 deletions(-) diff --git a/openpgp/backend/base.py b/openpgp/backend/base.py index b3ec109..33be377 100644 --- a/openpgp/backend/base.py +++ b/openpgp/backend/base.py @@ -16,7 +16,6 @@ from __future__ import annotations -from typing import Any from typing import TYPE_CHECKING from collections.abc import Sequence @@ -29,8 +28,7 @@ if TYPE_CHECKING: class BaseKeyringItem: - def __init__(self, key: Any) -> None: - self._key = key + def __init__(self) -> None: self._uid = self._get_uid() @property diff --git a/openpgp/backend/gpgme.py b/openpgp/backend/gpgme.py index d7a85ca..b34061f 100644 --- a/openpgp/backend/gpgme.py +++ b/openpgp/backend/gpgme.py @@ -18,6 +18,7 @@ from typing import Any from typing import cast import logging +from collections.abc import Iterator from collections.abc import Sequence from pathlib import Path @@ -37,6 +38,9 @@ log = logging.getLogger("gajim.p.openpgp.gpgme") class KeyringItem(BaseKeyringItem): + def __init__(self, key: Key) -> None: + self._key = key + BaseKeyringItem.__init__(self) def _get_uid(self) -> str | None: for uid in self._key.uids: @@ -98,7 +102,7 @@ class GPGMe(BasePGPBackend): def get_keys(self) -> Sequence[KeyringItem]: keys: list[KeyringItem] = [] with self._get_context() as context: - for key in context.keylist(secret=False): + for key in cast(Iterator[Key], context.keylist(secret=False)): keyring_item = KeyringItem(key) if not keyring_item.is_xmpp_key: log.warning("Key not suited for xmpp: %s", key.fpr) @@ -133,7 +137,7 @@ class GPGMe(BasePGPBackend): recipients: list[Any] = [] with self._get_context() as context: for key in keys: - key = context.get_key(key.fingerprint) + key = cast(Key | None, context.get_key(key.fingerprint)) if key is not None: recipients.append(key) @@ -155,16 +159,18 @@ class GPGMe(BasePGPBackend): except Exception as error: raise DecryptionFailed("Decryption failed: %s" % error) - plaintext, result, verify_result = result - plaintext = plaintext.decode() + plaintext, result, verify_result = result + plaintext = plaintext.decode() - fingerprints = [sig.fpr for sig in verify_result.signatures] - if not fingerprints or len(fingerprints) > 1: - log.error(result) - log.error(verify_result) - raise DecryptionFailed("Verification failed") + fingerprints = [sig.fpr for sig in verify_result.signatures] + if not fingerprints or len(fingerprints) > 1: + log.error(result) + log.error(verify_result) + raise DecryptionFailed("Verification failed") - return plaintext, fingerprints[0] + return plaintext, fingerprints[0] + + raise RuntimeError def import_key(self, data: bytes, jid: JID) -> KeyringItem | None: log.info("Import key from %s", jid) diff --git a/openpgp/backend/gpgme_types.py b/openpgp/backend/gpgme_types.py index 3b6d745..c78c01f 100644 --- a/openpgp/backend/gpgme_types.py +++ b/openpgp/backend/gpgme_types.py @@ -1,19 +1,3 @@ -# Copyright (C) 2025 Philipp Hörist -# -# This file is part of the OpenPGP Gajim Plugin. -# -# OpenPGP Gajim Plugin is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published -# by the Free Software Foundation; version 3 only. -# -# OpenPGP Gajim Plugin is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with OpenPGP Gajim Plugin. If not, see . - from __future__ import annotations from typing import Any diff --git a/openpgp/backend/pygpg.py b/openpgp/backend/pygpg.py index 974bda0..ba9e982 100644 --- a/openpgp/backend/pygpg.py +++ b/openpgp/backend/pygpg.py @@ -14,6 +14,8 @@ # You should have received a copy of the GNU General Public License # along with OpenPGP Gajim Plugin. If not, see . +from typing import Any + import logging from collections.abc import Sequence from pathlib import Path @@ -35,6 +37,9 @@ if log.getEffectiveLevel() == logging.DEBUG: class KeyringItem(BaseKeyringItem): + def __init__(self, key: dict[Any, Any]) -> None: + self._key = key + BaseKeyringItem.__init__(self) @property def keyid(self) -> str: diff --git a/openpgp/backend/sql.py b/openpgp/backend/sql.py index 60d0fb6..91387fc 100644 --- a/openpgp/backend/sql.py +++ b/openpgp/backend/sql.py @@ -105,7 +105,7 @@ class Storage: ) -> None: sql = """REPLACE INTO contacts(jid, fingerprint, active, trust, timestamp) - VALUES(?, ?, ?, ?, ?, ?)""" + VALUES(?, ?, ?, ?, ?)""" for values in db_values: log.info("Store key: %s", values) self._con.execute(sql, values) diff --git a/openpgp/gtk/wizard.py b/openpgp/gtk/wizard.py index 24ee425..158aedc 100644 --- a/openpgp/gtk/wizard.py +++ b/openpgp/gtk/wizard.py @@ -71,7 +71,7 @@ class KeyWizard(Gtk.Assistant): self.connect("cancel", self._on_cancel) self.connect("close", self._on_cancel) - self._remove_sidebar() + # self._remove_sidebar() self.show() def _add_page(self, page: Gtk.Box) -> None: diff --git a/typings/gpg/core.pyi b/typings/gpg/core.pyi index e2459a2..a7d371a 100644 --- a/typings/gpg/core.pyi +++ b/typings/gpg/core.pyi @@ -2,8 +2,11 @@ from typing import Any from collections.abc import Iterator +from gpg.results import DecryptResult from gpg.results import EncryptResult +from gpg.results import Key from gpg.results import SignResult +from gpg.results import VerifyResult class GpgmeWrapper(object): ... @@ -24,7 +27,7 @@ class Context(GpgmeWrapper): def encrypt( self, plaintext: bytes, - recipients: list[str] = [], + recipients: list[Any] = [], sign: bool = ..., sink: Any | None = ..., passphrase: str | None = ..., @@ -41,7 +44,7 @@ class Context(GpgmeWrapper): passphrase: str | None = ..., verify: bool = ..., filter_signatures: bool = ..., - ) -> tuple[bytes, str, str]: ... + ) -> tuple[bytes, DecryptResult, VerifyResult]: ... def key_import(self, data: bytes) -> str: ... def key_export_minimal(self, pattern: Any | None = ...) -> bytes | None: ... def keylist( diff --git a/typings/gpg/results.pyi b/typings/gpg/results.pyi index 61f32aa..9fc5e84 100644 --- a/typings/gpg/results.pyi +++ b/typings/gpg/results.pyi @@ -6,10 +6,19 @@ class InvalidKey(Result): ... class EncryptResult(Result): invalid_recipients: list[Any] -class Recipient(Result): ... +class Recipient(Result): + keyid: str + pubkey_algo: int + status: int class DecryptResult(Result): - recipients: Recipient + file_name: str | None + is_de_vs: bool + is_mime: int + legacy_cipher_nomdc: int + recipients: list[Recipient] + symkey_algo: str + wrong_key_usage: bool class NewSignature(Result): ... @@ -21,10 +30,25 @@ class Notation(Result): ... class Signature(Result): _type = dict(wrong_key_usage=bool, chain_model=bool, is_de_vs=bool) - notations: Notation + notations: list[Notation] + chain_model: bool + exp_timestamp: int + fpr: str + hash_algo: int + is_de_vs: bool + pka_trust: int + pubkey_algo: int + status: int + summary: int + timestamp: int + validity: int + validity_reason: int + wrong_key_usage: bool class VerifyResult(Result): - signatures: Signature + file_name: str | None + is_mime: int + signatures: list[Signature] class ImportStatus(Result): ...