]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Chore: Enable ruff FBT (#8645)
authorSebastian Steinbeißer <33968289+gothicVI@users.noreply.github.com>
Fri, 7 Feb 2025 17:12:03 +0000 (18:12 +0100)
committerGitHub <noreply@github.com>
Fri, 7 Feb 2025 17:12:03 +0000 (09:12 -0800)
27 files changed:
.ruff.toml
src/documents/bulk_download.py
src/documents/bulk_edit.py
src/documents/file_handling.py
src/documents/filters.py
src/documents/index.py
src/documents/management/commands/convert_mariadb_uuid.py
src/documents/management/commands/document_consumer.py
src/documents/migrations/1012_fix_archive_files.py
src/documents/models.py
src/documents/parsers.py
src/documents/permissions.py
src/documents/sanity_checker.py
src/documents/signals/handlers.py
src/documents/tasks.py
src/documents/tests/test_api_filter_by_custom_fields.py
src/documents/tests/test_bulk_edit.py
src/documents/tests/test_consumer.py
src/documents/tests/test_delayedquery.py
src/documents/tests/test_management_consumer.py
src/documents/tests/test_management_exporter.py
src/documents/tests/test_matchables.py
src/documents/views.py
src/paperless/views.py
src/paperless_mail/mail.py
src/paperless_mail/tests/test_mail.py
src/paperless_tesseract/parsers.py

index d9ca6b321413d789f05dcdf6653a455dfb6ccfe3..a29b471c527587fb2f9bcb1dd6782ae441772118 100644 (file)
@@ -32,6 +32,7 @@ extend-select = [
   "RUF",   # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
   "FLY",   # https://docs.astral.sh/ruff/rules/#flynt-fly
   "PTH",   # https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth
+  "FBT",   # https://docs.astral.sh/ruff/rules/#flake8-boolean-trap-fbt
 ]
 ignore = ["DJ001", "SIM105", "RUF012"]
 
index 25dfb5a14f8ea85d8c1bf452364ad2e3809793b7..5bdc3e74a3e21720888442f5a23f138d6e3b4479 100644 (file)
@@ -10,7 +10,7 @@ if TYPE_CHECKING:
 
 
 class BulkArchiveStrategy:
-    def __init__(self, zipf: ZipFile, follow_formatting: bool = False) -> None:
+    def __init__(self, zipf: ZipFile, *, follow_formatting: bool = False) -> None:
         self.zipf: ZipFile = zipf
         if follow_formatting:
             self.make_unique_filename: Callable[..., Path | str] = (
@@ -22,6 +22,7 @@ class BulkArchiveStrategy:
     def _filename_only(
         self,
         doc: Document,
+        *,
         archive: bool = False,
         folder: str = "",
     ) -> str:
@@ -33,7 +34,10 @@ class BulkArchiveStrategy:
         """
         counter = 0
         while True:
-            filename: str = folder + doc.get_public_filename(archive, counter)
+            filename: str = folder + doc.get_public_filename(
+                archive=archive,
+                counter=counter,
+            )
             if filename in self.zipf.namelist():
                 counter += 1
             else:
@@ -42,6 +46,7 @@ class BulkArchiveStrategy:
     def _formatted_filepath(
         self,
         doc: Document,
+        *,
         archive: bool = False,
         folder: str = "",
     ) -> Path:
index 0aadcc2950ca6fd1e889cb3848e1f46db6fb31a4..f6adfc8a978f9f160ba205a1a4e57d1c98578fb3 100644 (file)
@@ -245,6 +245,7 @@ def reprocess(doc_ids: list[int]) -> Literal["OK"]:
 def set_permissions(
     doc_ids: list[int],
     set_permissions,
+    *,
     owner=None,
     merge=False,
 ) -> Literal["OK"]:
@@ -309,6 +310,7 @@ def rotate(doc_ids: list[int], degrees: int) -> Literal["OK"]:
 
 def merge(
     doc_ids: list[int],
+    *,
     metadata_document_id: int | None = None,
     delete_originals: bool = False,
     user: User | None = None,
@@ -387,6 +389,7 @@ def merge(
 def split(
     doc_ids: list[int],
     pages: list[list[int]],
+    *,
     delete_originals: bool = False,
     user: User | None = None,
 ) -> Literal["OK"]:
index 4198ecabbb1047d814184a1c62433c03eeb23d09..3d1a643dfebcb8c919add324282d8c48301ac368 100644 (file)
@@ -43,7 +43,7 @@ def delete_empty_directories(directory, root):
         directory = os.path.normpath(os.path.dirname(directory))
 
 
-def generate_unique_filename(doc, archive_filename=False):
+def generate_unique_filename(doc, *, archive_filename=False):
     """
     Generates a unique filename for doc in settings.ORIGINALS_DIR.
 
@@ -77,7 +77,7 @@ def generate_unique_filename(doc, archive_filename=False):
     while True:
         new_filename = generate_filename(
             doc,
-            counter,
+            counter=counter,
             archive_filename=archive_filename,
         )
         if new_filename == old_filename:
@@ -92,6 +92,7 @@ def generate_unique_filename(doc, archive_filename=False):
 
 def generate_filename(
     doc: Document,
+    *,
     counter=0,
     append_gpg=True,
     archive_filename=False,
index 142f3f519f3b24003ec57324306f3b57c44e1350..fab029312f2955f60f3c3129b3f07aa5cbeb669a 100644 (file)
@@ -97,7 +97,7 @@ class StoragePathFilterSet(FilterSet):
 
 
 class ObjectFilter(Filter):
-    def __init__(self, exclude=False, in_list=False, field_name=""):
+    def __init__(self, *, exclude=False, in_list=False, field_name=""):
         super().__init__()
         self.exclude = exclude
         self.in_list = in_list
index 4c5afb5054b025d21e13f8e21182b175a6f60662..4b11325ff20665785e874f9143e0eb59b78878cd 100644 (file)
@@ -85,7 +85,7 @@ def get_schema() -> Schema:
     )
 
 
-def open_index(recreate=False) -> FileIndex:
+def open_index(*, recreate=False) -> FileIndex:
     try:
         if exists_in(settings.INDEX_DIR) and not recreate:
             return open_dir(settings.INDEX_DIR, schema=get_schema())
@@ -101,7 +101,7 @@ def open_index(recreate=False) -> FileIndex:
 
 
 @contextmanager
-def open_index_writer(optimize=False) -> AsyncWriter:
+def open_index_writer(*, optimize=False) -> AsyncWriter:
     writer = AsyncWriter(open_index())
 
     try:
@@ -425,7 +425,7 @@ def autocomplete(
 
 
 def get_permissions_criterias(user: User | None = None) -> list:
-    user_criterias = [query.Term("has_owner", False)]
+    user_criterias = [query.Term("has_owner", text=False)]
     if user is not None:
         if user.is_superuser:  # superusers see all docs
             user_criterias = []
index 4000e67cb894d9dd518b9378c75c705bf89069a7..76ccf9e76284edb25a42411f915fb76764257a04 100644 (file)
@@ -9,7 +9,7 @@ class Command(BaseCommand):
     # This code is taken almost entirely from https://github.com/wagtail/wagtail/pull/11912 with all credit to the original author.
     help = "Converts UUID columns from char type to the native UUID type used in MariaDB 10.7+ and Django 5.0+."
 
-    def convert_field(self, model, field_name, null=False):
+    def convert_field(self, model, field_name, *, null=False):
         if model._meta.get_field(field_name).model != model:  # pragma: no cover
             # Field is inherited from a parent model
             return
index 6b2706733ebb5624c8b17a5448eeda75204a01e5..36dcc7706215fcfbf7504f32aa932bc6255bd9b8 100644 (file)
@@ -248,15 +248,15 @@ class Command(BaseCommand):
             return
 
         if settings.CONSUMER_POLLING == 0 and INotify:
-            self.handle_inotify(directory, recursive, options["testing"])
+            self.handle_inotify(directory, recursive, is_testing=options["testing"])
         else:
             if INotify is None and settings.CONSUMER_POLLING == 0:  # pragma: no cover
                 logger.warning("Using polling as INotify import failed")
-            self.handle_polling(directory, recursive, options["testing"])
+            self.handle_polling(directory, recursive, is_testing=options["testing"])
 
         logger.debug("Consumer exiting.")
 
-    def handle_polling(self, directory, recursive, is_testing: bool):
+    def handle_polling(self, directory, recursive, *, is_testing: bool):
         logger.info(f"Polling directory for changes: {directory}")
 
         timeout = None
@@ -283,7 +283,7 @@ class Command(BaseCommand):
                 observer.stop()
             observer.join()
 
-    def handle_inotify(self, directory, recursive, is_testing: bool):
+    def handle_inotify(self, directory, recursive, *, is_testing: bool):
         logger.info(f"Using inotify to watch directory for changes: {directory}")
 
         timeout_ms = None
index 1d12c439ba89774f366ec3df53ac9765c71bf093..46951471e114ee1e98ffd91291864320c3bf0b2a 100644 (file)
@@ -84,7 +84,7 @@ def source_path(doc):
     return os.path.join(settings.ORIGINALS_DIR, fname)
 
 
-def generate_unique_filename(doc, archive_filename=False):
+def generate_unique_filename(doc, *, archive_filename=False):
     if archive_filename:
         old_filename = doc.archive_filename
         root = settings.ARCHIVE_DIR
@@ -97,7 +97,7 @@ def generate_unique_filename(doc, archive_filename=False):
     while True:
         new_filename = generate_filename(
             doc,
-            counter,
+            counter=counter,
             archive_filename=archive_filename,
         )
         if new_filename == old_filename:
@@ -110,7 +110,7 @@ def generate_unique_filename(doc, archive_filename=False):
             return new_filename
 
 
-def generate_filename(doc, counter=0, append_gpg=True, archive_filename=False):
+def generate_filename(doc, *, counter=0, append_gpg=True, archive_filename=False):
     path = ""
 
     try:
index e7d866e2428d4c39f8e50edfa71deceb6e7ef56e..25e3c62fd0efdc5e0b5a6a3130edbdefa9e93226 100644 (file)
@@ -337,7 +337,7 @@ class Document(SoftDeleteModel, ModelWithOwner):
     def archive_file(self):
         return open(self.archive_path, "rb")
 
-    def get_public_filename(self, archive=False, counter=0, suffix=None) -> str:
+    def get_public_filename(self, *, archive=False, counter=0, suffix=None) -> str:
         """
         Returns a sanitized filename for the document, not including any paths.
         """
index d840817e4f5ba8091a9695205246ac1c0c74de9e..28d903fdd6e2ef07c8f760a11da4ebd62ca785bd 100644 (file)
@@ -133,6 +133,7 @@ def get_parser_class_for_mime_type(mime_type: str) -> type["DocumentParser"] | N
 def run_convert(
     input_file,
     output_file,
+    *,
     density=None,
     scale=None,
     alpha=None,
index 464916ad4fc398dfc71afc14a3fab3d2a196be03..4380c6994a5e8e7c94c7ff2848b93459556de2f3 100644 (file)
@@ -58,7 +58,7 @@ def get_groups_with_only_permission(obj, codename):
     return Group.objects.filter(id__in=group_object_perm_group_ids).distinct()
 
 
-def set_permissions_for_object(permissions: list[str], object, merge: bool = False):
+def set_permissions_for_object(permissions: list[str], object, *, merge: bool = False):
     """
     Set permissions for an object. The permissions are given as a list of strings
     in the format "action_modelname", e.g. "view_document".
index 9d44ff345de3c925ef0a20055df249c85a9d382c..28d2024e7238fec9999f1dbfb07f068d50236c95 100644 (file)
@@ -57,7 +57,7 @@ class SanityCheckFailedException(Exception):
     pass
 
 
-def check_sanity(progress=False) -> SanityCheckMessages:
+def check_sanity(*, progress=False) -> SanityCheckMessages:
     messages = SanityCheckMessages()
 
     present_files = {
index 4885910fdf300c6a86a992c2e4b6cadba6ab629c..1c4d366948b7d184674b9be18e8466eb9b456bb1 100644 (file)
@@ -85,6 +85,7 @@ def _suggestion_printer(
 def set_correspondent(
     sender,
     document: Document,
+    *,
     logging_group=None,
     classifier: DocumentClassifier | None = None,
     replace=False,
@@ -140,6 +141,7 @@ def set_correspondent(
 def set_document_type(
     sender,
     document: Document,
+    *,
     logging_group=None,
     classifier: DocumentClassifier | None = None,
     replace=False,
@@ -196,6 +198,7 @@ def set_document_type(
 def set_tags(
     sender,
     document: Document,
+    *,
     logging_group=None,
     classifier: DocumentClassifier | None = None,
     replace=False,
@@ -251,6 +254,7 @@ def set_tags(
 def set_storage_path(
     sender,
     document: Document,
+    *,
     logging_group=None,
     classifier: DocumentClassifier | None = None,
     replace=False,
index 8b0cbf24954636175e5c172e757d60ca81a57707..d8539d1ab25f42374c66cfdbf92f698c1b3a8be5 100644 (file)
@@ -63,7 +63,7 @@ def index_optimize():
     writer.commit(optimize=True)
 
 
-def index_reindex(progress_bar_disable=False):
+def index_reindex(*, progress_bar_disable=False):
     documents = Document.objects.all()
 
     ix = index.open_index(recreate=True)
index deb97bf29fbf40c1e5329b748fc40800b576f3a1..70d43dfde3c92f5bd5ca4317f0ee9a1060d1c9c0 100644 (file)
@@ -165,6 +165,7 @@ class TestCustomFieldsSearch(DirectoriesMixin, APITestCase):
         self,
         query: list,
         reference_predicate: Callable[[DocumentWrapper], bool],
+        *,
         match_nothing_ok=False,
     ):
         """
index 7fde5f8ee48ea4cd7f19672fe4808463a4df8982..4a7145d34e2fb313b502e8c72358d41d038ccee1 100644 (file)
@@ -535,7 +535,12 @@ class TestPDFActions(DirectoriesMixin, TestCase):
         metadata_document_id = self.doc1.id
         user = User.objects.create(username="test_user")
 
-        result = bulk_edit.merge(doc_ids, None, False, user)
+        result = bulk_edit.merge(
+            doc_ids,
+            metadata_document_id=None,
+            delete_originals=False,
+            user=user,
+        )
 
         expected_filename = (
             f"{'_'.join([str(doc_id) for doc_id in doc_ids])[:100]}_merged.pdf"
@@ -638,7 +643,7 @@ class TestPDFActions(DirectoriesMixin, TestCase):
         doc_ids = [self.doc2.id]
         pages = [[1, 2], [3]]
         user = User.objects.create(username="test_user")
-        result = bulk_edit.split(doc_ids, pages, False, user)
+        result = bulk_edit.split(doc_ids, pages, delete_originals=False, user=user)
         self.assertEqual(mock_consume_file.call_count, 2)
         consume_file_args, _ = mock_consume_file.call_args
         self.assertEqual(consume_file_args[1].title, "B (split 2)")
index aa452e15b8e875a63df30ae63a5b60bf305dba73..a862d7fa0b738f5b1db6e5eb19b56e2a498afad3 100644 (file)
@@ -233,7 +233,7 @@ class FaultyGenericExceptionParser(_BaseTestParser):
         raise Exception("Generic exception.")
 
 
-def fake_magic_from_file(file, mime=False):
+def fake_magic_from_file(file, *, mime=False):
     if mime:
         if file.name.startswith("invalid_pdf"):
             return "application/octet-stream"
index 1895bd6c69440c221fd9489a8b6c1dabc26828b0..3ee4fb15d9b14004013c7dd632a0498420ce174d 100644 (file)
@@ -10,7 +10,7 @@ class TestDelayedQuery(TestCase):
         super().setUp()
         # all tests run without permission criteria, so has_no_owner query will always
         # be appended.
-        self.has_no_owner = query.Or([query.Term("has_owner", False)])
+        self.has_no_owner = query.Or([query.Term("has_owner", text=False)])
 
     def _get_testset__id__in(self, param, field):
         return (
@@ -43,12 +43,12 @@ class TestDelayedQuery(TestCase):
     def test_get_permission_criteria(self):
         # tests contains tuples of user instances and the expected filter
         tests = (
-            (None, [query.Term("has_owner", False)]),
+            (None, [query.Term("has_owner", text=False)]),
             (User(42, username="foo", is_superuser=True), []),
             (
                 User(42, username="foo", is_superuser=False),
                 [
-                    query.Term("has_owner", False),
+                    query.Term("has_owner", text=False),
                     query.Term("owner_id", 42),
                     query.Term("viewer_id", "42"),
                 ],
index 7e2707403aaf05d1f927f1939f425844e59dd319..808216d3d608f83fc5a11628ad01e9e0261f06a7 100644 (file)
@@ -93,7 +93,7 @@ class ConsumerThreadMixin(DocumentConsumeDelayMixin):
         else:
             print("Consumed a perfectly valid file.")  # noqa: T201
 
-    def slow_write_file(self, target, incomplete=False):
+    def slow_write_file(self, target, *, incomplete=False):
         with open(self.sample_file, "rb") as f:
             pdf_bytes = f.read()
 
index 0a79b6cd7c901a09b9512d5b6350aa871c5b1b5c..eec2fcd4b5ae3f74590a472b224467a4ac849c18 100644 (file)
@@ -188,7 +188,7 @@ class TestExportImport(
 
         return manifest
 
-    def test_exporter(self, use_filename_format=False):
+    def test_exporter(self, *, use_filename_format=False):
         shutil.rmtree(os.path.join(self.dirs.media_dir, "documents"))
         shutil.copytree(
             os.path.join(os.path.dirname(__file__), "samples", "documents"),
index 9ca23e53d28864664f8869e58b22e8a0afa17d87..180cf77ed3a59b8dee4062744e3ef4eb5e514474 100644 (file)
@@ -23,6 +23,7 @@ class _TestMatchingBase(TestCase):
         match_algorithm: str,
         should_match: Iterable[str],
         no_match: Iterable[str],
+        *,
         case_sensitive: bool = False,
     ):
         for klass in (Tag, Correspondent, DocumentType):
index 24578179abffd9b0d89b54ee8d8a4aa3ce839a49..f23c1b95308a8cf0d6c2aa68232c3a33c14c7392 100644 (file)
@@ -1608,7 +1608,7 @@ class BulkDownloadView(GenericAPIView):
             strategy_class = ArchiveOnlyStrategy
 
         with zipfile.ZipFile(temp.name, "w", compression) as zipf:
-            strategy = strategy_class(zipf, follow_filename_format)
+            strategy = strategy_class(zipf, follow_formatting=follow_filename_format)
             for document in documents:
                 strategy.add_document(document)
 
@@ -1872,7 +1872,7 @@ class SharedLinkView(View):
         )
 
 
-def serve_file(doc: Document, use_archive: bool, disposition: str):
+def serve_file(*, doc: Document, use_archive: bool, disposition: str):
     if use_archive:
         file_handle = doc.archive_file
         filename = doc.get_public_filename(archive=True)
index bcabd182f0c0bfcc7e70fdb6486e931e9bbc6785..6d297c49bdeeecfbd1444c7cb7a1912909b13df8 100644 (file)
@@ -148,7 +148,7 @@ class UserViewSet(ModelViewSet):
         ).first()
         if authenticator is not None:
             delete_and_cleanup(request, authenticator)
-            return Response(True)
+            return Response(data=True)
         else:
             return HttpResponseNotFound("TOTP not found")
 
@@ -262,7 +262,7 @@ class TOTPView(GenericAPIView):
         ).first()
         if authenticator is not None:
             delete_and_cleanup(request, authenticator)
-            return Response(True)
+            return Response(data=True)
         else:
             return HttpResponseNotFound("TOTP not found")
 
index e25c4f227f3b9994a8ff03b6cebac14712d448a7..cf35ea6cbbf031c3bd4cb4aa2f5b7d6a42416b08 100644 (file)
@@ -121,7 +121,7 @@ class MarkReadMailAction(BaseMailAction):
         return {"seen": False}
 
     def post_consume(self, M: MailBox, message_uid: str, parameter: str):
-        M.flag(message_uid, [MailMessageFlags.SEEN], True)
+        M.flag(message_uid, [MailMessageFlags.SEEN], value=True)
 
 
 class MoveMailAction(BaseMailAction):
@@ -142,7 +142,7 @@ class FlagMailAction(BaseMailAction):
         return {"flagged": False}
 
     def post_consume(self, M: MailBox, message_uid: str, parameter: str):
-        M.flag(message_uid, [MailMessageFlags.FLAGGED], True)
+        M.flag(message_uid, [MailMessageFlags.FLAGGED], value=True)
 
 
 class TagMailAction(BaseMailAction):
@@ -150,7 +150,7 @@ class TagMailAction(BaseMailAction):
     A mail action that tags mails after processing.
     """
 
-    def __init__(self, parameter: str, supports_gmail_labels: bool):
+    def __init__(self, parameter: str, *, supports_gmail_labels: bool):
         # The custom tag should look like "apple:<color>"
         if "apple:" in parameter.lower():
             _, self.color = parameter.split(":")
@@ -188,19 +188,19 @@ class TagMailAction(BaseMailAction):
             M.flag(
                 message_uid,
                 set(itertools.chain(*APPLE_MAIL_TAG_COLORS.values())),
-                False,
+                value=False,
             )
 
             # Set new $MailFlagBits
-            M.flag(message_uid, APPLE_MAIL_TAG_COLORS.get(self.color), True)
+            M.flag(message_uid, APPLE_MAIL_TAG_COLORS.get(self.color), value=True)
 
             # Set the general \Flagged
             # This defaults to the "red" flag in AppleMail and
             # "stars" in Thunderbird or GMail
-            M.flag(message_uid, [MailMessageFlags.FLAGGED], True)
+            M.flag(message_uid, [MailMessageFlags.FLAGGED], value=True)
 
         elif self.keyword:
-            M.flag(message_uid, [self.keyword], True)
+            M.flag(message_uid, [self.keyword], value=True)
 
         else:
             raise MailError("No keyword specified.")
@@ -268,7 +268,7 @@ def apply_mail_action(
             mailbox_login(M, account)
             M.folder.set(rule.folder)
 
-            action = get_rule_action(rule, supports_gmail_labels)
+            action = get_rule_action(rule, supports_gmail_labels=supports_gmail_labels)
             try:
                 action.post_consume(M, message_uid, rule.action_parameter)
             except errors.ImapToolsError:
@@ -356,7 +356,7 @@ def queue_consumption_tasks(
     ).delay()
 
 
-def get_rule_action(rule: MailRule, supports_gmail_labels: bool) -> BaseMailAction:
+def get_rule_action(rule: MailRule, *, supports_gmail_labels: bool) -> BaseMailAction:
     """
     Returns a BaseMailAction instance for the given rule.
     """
@@ -370,12 +370,15 @@ def get_rule_action(rule: MailRule, supports_gmail_labels: bool) -> BaseMailActi
     elif rule.action == MailRule.MailAction.MARK_READ:
         return MarkReadMailAction()
     elif rule.action == MailRule.MailAction.TAG:
-        return TagMailAction(rule.action_parameter, supports_gmail_labels)
+        return TagMailAction(
+            rule.action_parameter,
+            supports_gmail_labels=supports_gmail_labels,
+        )
     else:
         raise NotImplementedError("Unknown action.")  # pragma: no cover
 
 
-def make_criterias(rule: MailRule, supports_gmail_labels: bool):
+def make_criterias(rule: MailRule, *, supports_gmail_labels: bool):
     """
     Returns criteria to be applied to MailBox.fetch for the given rule.
     """
@@ -393,7 +396,10 @@ def make_criterias(rule: MailRule, supports_gmail_labels: bool):
     if rule.filter_body:
         criterias["body"] = rule.filter_body
 
-    rule_query = get_rule_action(rule, supports_gmail_labels).get_criteria()
+    rule_query = get_rule_action(
+        rule,
+        supports_gmail_labels=supports_gmail_labels,
+    ).get_criteria()
     if isinstance(rule_query, dict):
         if len(rule_query) or len(criterias):
             return AND(**rule_query, **criterias)
@@ -563,7 +569,7 @@ class MailAccountHandler(LoggingMixin):
                         total_processed_files += self._handle_mail_rule(
                             M,
                             rule,
-                            supports_gmail_labels,
+                            supports_gmail_labels=supports_gmail_labels,
                         )
                     except Exception as e:
                         self.log.exception(
@@ -588,6 +594,7 @@ class MailAccountHandler(LoggingMixin):
         self,
         M: MailBox,
         rule: MailRule,
+        *,
         supports_gmail_labels: bool,
     ):
         folders = [rule.folder]
@@ -616,7 +623,7 @@ class MailAccountHandler(LoggingMixin):
                 f"does not exist in account {rule.account}",
             ) from err
 
-        criterias = make_criterias(rule, supports_gmail_labels)
+        criterias = make_criterias(rule, supports_gmail_labels=supports_gmail_labels)
 
         self.log.debug(
             f"Rule {rule}: Searching folder with criteria {criterias}",
index 2311c30099844162937dbfe0aef60231b3dfbce0..a73f9cf34e532600004c55c04d26a852cfc68c1a 100644 (file)
@@ -124,7 +124,7 @@ class BogusMailBox(AbstractContextManager):
         if username != self.USERNAME or access_token != self.ACCESS_TOKEN:
             raise MailboxLoginError("BAD", "OK")
 
-    def fetch(self, criteria, mark_seen, charset="", bulk=True):
+    def fetch(self, criteria, mark_seen, charset="", *, bulk=True):
         msg = self.messages
 
         criteria = str(criteria).strip("()").split(" ")
@@ -190,7 +190,7 @@ class BogusMailBox(AbstractContextManager):
             raise Exception
 
 
-def fake_magic_from_buffer(buffer, mime=False):
+def fake_magic_from_buffer(buffer, *, mime=False):
     if mime:
         if "PDF" in str(buffer):
             return "application/pdf"
@@ -206,6 +206,7 @@ class MessageBuilder:
 
     def create_message(
         self,
+        *,
         attachments: int | list[_AttachmentDef] = 1,
         body: str = "",
         subject: str = "the subject",
@@ -783,12 +784,18 @@ class TestMail(
         )
 
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
-        self.assertEqual(len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", False)), 2)
+        self.assertEqual(
+            len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", mark_seen=False)),
+            2,
+        )
 
         self.mail_account_handler.handle_mail_account(account)
         self.mailMocker.apply_mail_actions()
 
-        self.assertEqual(len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", False)), 0)
+        self.assertEqual(
+            len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", mark_seen=False)),
+            0,
+        )
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
 
     def test_handle_mail_account_delete(self):
@@ -853,7 +860,7 @@ class TestMail(
 
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
         self.assertEqual(
-            len(self.mailMocker.bogus_mailbox.fetch("UNFLAGGED", False)),
+            len(self.mailMocker.bogus_mailbox.fetch("UNFLAGGED", mark_seen=False)),
             2,
         )
 
@@ -861,7 +868,7 @@ class TestMail(
         self.mailMocker.apply_mail_actions()
 
         self.assertEqual(
-            len(self.mailMocker.bogus_mailbox.fetch("UNFLAGGED", False)),
+            len(self.mailMocker.bogus_mailbox.fetch("UNFLAGGED", mark_seen=False)),
             1,
         )
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
@@ -934,7 +941,12 @@ class TestMail(
 
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
         self.assertEqual(
-            len(self.mailMocker.bogus_mailbox.fetch("UNKEYWORD processed", False)),
+            len(
+                self.mailMocker.bogus_mailbox.fetch(
+                    "UNKEYWORD processed",
+                    mark_seen=False,
+                ),
+            ),
             2,
         )
 
@@ -943,7 +955,12 @@ class TestMail(
 
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
         self.assertEqual(
-            len(self.mailMocker.bogus_mailbox.fetch("UNKEYWORD processed", False)),
+            len(
+                self.mailMocker.bogus_mailbox.fetch(
+                    "UNKEYWORD processed",
+                    mark_seen=False,
+                ),
+            ),
             0,
         )
 
@@ -967,12 +984,18 @@ class TestMail(
 
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
         criteria = NOT(gmail_label="processed")
-        self.assertEqual(len(self.mailMocker.bogus_mailbox.fetch(criteria, False)), 2)
+        self.assertEqual(
+            len(self.mailMocker.bogus_mailbox.fetch(criteria, mark_seen=False)),
+            2,
+        )
 
         self.mail_account_handler.handle_mail_account(account)
         self.mailMocker.apply_mail_actions()
 
-        self.assertEqual(len(self.mailMocker.bogus_mailbox.fetch(criteria, False)), 0)
+        self.assertEqual(
+            len(self.mailMocker.bogus_mailbox.fetch(criteria, mark_seen=False)),
+            0,
+        )
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
 
     def test_tag_mail_action_applemail_wrong_input(self):
@@ -980,7 +1003,7 @@ class TestMail(
             MailError,
             TagMailAction,
             "apple:black",
-            False,
+            supports_gmail_labels=False,
         )
 
     def test_handle_mail_account_tag_applemail(self):
@@ -1002,7 +1025,7 @@ class TestMail(
 
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
         self.assertEqual(
-            len(self.mailMocker.bogus_mailbox.fetch("UNFLAGGED", False)),
+            len(self.mailMocker.bogus_mailbox.fetch("UNFLAGGED", mark_seen=False)),
             2,
         )
 
@@ -1010,7 +1033,7 @@ class TestMail(
         self.mailMocker.apply_mail_actions()
 
         self.assertEqual(
-            len(self.mailMocker.bogus_mailbox.fetch("UNFLAGGED", False)),
+            len(self.mailMocker.bogus_mailbox.fetch("UNFLAGGED", mark_seen=False)),
             0,
         )
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
@@ -1324,13 +1347,19 @@ class TestMail(
 
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
         self.mailMocker._queue_consumption_tasks_mock.assert_not_called()
-        self.assertEqual(len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", False)), 2)
+        self.assertEqual(
+            len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", mark_seen=False)),
+            2,
+        )
 
         self.mail_account_handler.handle_mail_account(account)
         self.mailMocker.apply_mail_actions()
 
         self.assertEqual(self.mailMocker._queue_consumption_tasks_mock.call_count, 2)
-        self.assertEqual(len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", False)), 0)
+        self.assertEqual(
+            len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", mark_seen=False)),
+            0,
+        )
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
 
     def test_auth_plain_fallback_fails_still(self):
@@ -1390,13 +1419,19 @@ class TestMail(
 
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
         self.assertEqual(self.mailMocker._queue_consumption_tasks_mock.call_count, 0)
-        self.assertEqual(len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", False)), 2)
+        self.assertEqual(
+            len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", mark_seen=False)),
+            2,
+        )
 
         self.mail_account_handler.handle_mail_account(account)
         self.mailMocker.apply_mail_actions()
 
         self.assertEqual(self.mailMocker._queue_consumption_tasks_mock.call_count, 2)
-        self.assertEqual(len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", False)), 0)
+        self.assertEqual(
+            len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", mark_seen=False)),
+            0,
+        )
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
 
     def test_disabled_rule(self):
@@ -1425,12 +1460,15 @@ class TestMail(
         self.mailMocker.apply_mail_actions()
 
         self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
-        self.assertEqual(len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", False)), 2)
+        self.assertEqual(
+            len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", mark_seen=False)),
+            2,
+        )
 
         self.mail_account_handler.handle_mail_account(account)
         self.mailMocker.apply_mail_actions()
         self.assertEqual(
-            len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", False)),
+            len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", mark_seen=False)),
             2,
         )  # still 2
 
index e7968a61ef544a7ba39fd4a91225e4506b8e26ef..a8be899f586ef79d6549f3574db94ae87affc461 100644 (file)
@@ -214,6 +214,7 @@ class RasterisedDocumentParser(DocumentParser):
         mime_type,
         output_file,
         sidecar_file,
+        *,
         safe_fallback=False,
     ):
         if TYPE_CHECKING: