From db47ad686d6ca934379d58e5e3e5cafd48bb1f07 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Thu, 11 Sep 2025 20:16:05 +0200 Subject: [PATCH] chore: Implement Annotation sort and equality dunders --- papis_extract/annotation.py | 35 +++++++++++++++++++++++++++++++++++ tests/test_annotation.py | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/papis_extract/annotation.py b/papis_extract/annotation.py index d3dadb9..212f103 100644 --- a/papis_extract/annotation.py +++ b/papis_extract/annotation.py @@ -1,4 +1,6 @@ import math +from functools import total_ordering +from types import NotImplementedType from typing import Any, cast import chevron @@ -20,6 +22,7 @@ COLORS: dict[str, tuple[float, float, float]] = { } +@total_ordering class Annotation: """A PDF annotation object. @@ -144,3 +147,35 @@ class Annotation: def __repr__(self) -> str: return f"Annotation(type={self.type}, file='{self.file}', color={self.color}, tag='{self.tag}', page={self.page}, content='{self.content}', note='{self.note}', minimum_similarity_color={self.minimum_similarity_color})" + + def __eq__(self, other: object) -> bool | NotImplementedType: + if not isinstance(other, Annotation): + return NotImplemented + + return ( + self.content.lower(), + self.note.lower(), + self.type, + self.file, + self.color, + self.tag, + self.page, + ) == ( + other.content.lower(), + other.note.lower(), + other.type, + other.file, + other.color, + other.tag, + other.page, + ) + + def __lt__(self, other: object) -> bool: + if not hasattr(other, "page"): + return NotImplemented + + other = cast("Annotation", other) + selfpage = self.page if self.page != 0 else float("inf") + otherpage = other.page if other.page != 0 else float("inf") + + return selfpage < otherpage diff --git a/tests/test_annotation.py b/tests/test_annotation.py index 6d177a5..efc2403 100644 --- a/tests/test_annotation.py +++ b/tests/test_annotation.py @@ -4,12 +4,42 @@ from papis.document import Document from papis_extract.annotation import Annotation -def test_value_comparison_works(): +def test_value_inequality_comparison(): sut = Annotation("myfile", content="Here be content!", note="and a note") - other = Annotation("myfile", content="Here be different content!", note="but still a note") + other = Annotation( + "myfile", content="Here be different content!", note="but still a note" + ) assert sut != other +def test_oder_lt_comparison(): + sut = Annotation("myfile", content="Here be content!", note="and a note", page=2) + other = Annotation( + "myfile", content="Here be different content!", note="but still a note", page=10 + ) + assert sut < other + + +def test_oder_ge_comparison(): + big = Annotation("mf", content="ct", note="nt", page=10) + small = Annotation("mf", content="ct", note="nt", page=2) + alsosmall = Annotation("mf", content="ct", note="nt", page=2) + assert big >= small + assert small >= alsosmall + + +def test_oder_gt_comparison_single_nopage(): + zeropage = Annotation("mf", content="ct", note="nt", page=0) + small = Annotation("mf", content="ct", note="nt", page=2) + assert zeropage > small + + +def test_oder_le_comparison_all_nopage(): + zeropage = Annotation("mf", content="ct", note="nt", page=0) + small = Annotation("mf", content="ct", note="nt", page=0) + assert zeropage <= small + + @pytest.mark.parametrize( "fmt_string,expected", [