diff --git a/src/__init__.py b/src/__init__.py index f1f2ab989..38949d646 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -7186,6 +7186,7 @@ def _parse_da(self): def _validate(self): """Validate the class entries. """ + CheckParent(self) # ensure page still exists if (self.rect.is_infinite or self.rect.is_empty ): @@ -7305,6 +7306,7 @@ def button_states(self): @property def next(self): + CheckParent(self) # ensure page still exists return self._annot.next def on_state(self): @@ -17996,9 +17998,13 @@ def CheckMorph(o: typing.Any) -> bool: def CheckParent(o: typing.Any): + try: + check = str(o.parent) # will raise if no parent or weakref is dead + if check == "None": + raise ValueError(f"orphaned object: parent is None") + except ReferenceError, ValueError: + raise ValueError(f"orphaned object: parent is dead") return - if not hasattr(o, "parent") or o.parent is None: - raise ValueError(f"orphaned object {type(o)=}: parent is None") def CheckQuad(q: typing.Any) -> bool: diff --git a/tests/test_parent.py b/tests/test_parent.py new file mode 100644 index 000000000..01fed19de --- /dev/null +++ b/tests/test_parent.py @@ -0,0 +1,16 @@ +import pymupdf + + +def test_parent(): + """Test invalidating parent on page re-assignment.""" + doc = pymupdf.open() + page = doc.new_page() + a = page.add_highlight_annot(page.rect) # insert annotation on page 0 + page = doc.new_page() # make a new page, should orphanate annotation + try: + print(a) # should raise + error = False + except ValueError as e: + assert str(e) == "orphaned object: parent is dead" + error = True + assert error