Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: 'Widget' object has no attribute '_annot' in delete widget #2013

Closed
MallRoy opened this issue Nov 2, 2022 · 5 comments
Closed

Comments

@MallRoy
Copy link

MallRoy commented Nov 2, 2022

Describe the bug

We are trying to detect the signature widget and delete it. When we perform the operation it throws AttributeError: 'Widget' object has no attribute '_annot'
Sample PDF:
signed_sample.pdf

To Reproduce

import fitz

class PdfFunctions:
    def __init__(self, input_path, outputFilePath):
        self.pdfFilePath = input_path
        self.outputFilePath = outputFilePath

    def removesignaturewidget(self):
        doc = fitz.open(self.pdfFilePath)
        for page in doc.pages():     
            for w in page.widgets():
                print(w.xref)
                if (w.field_type == 6):
                    print('exists')
                    page.delete_widget(w)
                    
        doc.save(self.outputFilePath, garbage=3, deflate=True, pretty=True)
        print(self.outputFilePath)
        doc.close()

if __name__ == "__main__":
    filePath = "signed_sample.pdf"
    outputPath = "output.pdf"
    PdfFunction = PdfFunctions(filePath, outputPath)
    PdfFunction.removesignaturewidget()

Expected behavior

The signature widget should be deleted.

Error Screenshots

image

Your configuration (mandatory)

PyMuPDF 1.20.2: Python bindings for the MuPDF 1.20.3 library.
Version date: 2022-08-13 00:00:01.
Built for Python 3.9 on win32 (64-bit).

@JorjMcKie
Copy link
Collaborator

You cannot use page.widgets() in this context, because deleting a widget changes the iterator.
Do this instead:

for page in doc:
    w = page.first_widget
    while w:
        if w.field_type == 6:
            w = page.delete_widget(w)  # delivers None or next after deleted one
        else:
            w = w.next

@MallRoy
Copy link
Author

MallRoy commented Nov 3, 2022

I have tried the above solution. It is throwing the same error.

@JorjMcKie JorjMcKie reopened this Nov 3, 2022
@JorjMcKie
Copy link
Collaborator

I have tried the above solution. It is throwing the same error.

Can't be! I tried it out on an example.
Can you share your example file?

@MallRoy
Copy link
Author

MallRoy commented Nov 3, 2022

import sys
import fitz

class PdfFunctions:
    def __init__(self, input_path, outputFilePath):
        self.pdfFilePath = input_path
        self.outputFilePath = outputFilePath

    def removesignaturewidget(self):
        doc = fitz.open(self.pdfFilePath)
        for page in doc:
                w = page.first_widget
                while w:
                    if w.field_type == 6:
                        w = page.delete_widget(w)  # delivers None or next after deleted one
                    else:
                        w = w.next
            
        doc.save(self.outputFilePath, garbage=3, deflate=True, pretty=True)
        print(self.outputFilePath)
        doc.close()


if __name__ == "__main__":
    filePath = "signed_sample.pdf"
    outputPath = "output.pdf"
    PdfFunction = PdfFunctions(filePath, outputPath)
    PdfFunction.removesignaturewidget()

@JorjMcKie
Copy link
Collaborator

Indeed, there is a bug!
For a hot fix, please change line 1823 in file fitz.py in your Python installation from this:

annot = getattr(self, "_annot")

to this:

annot = getattr(self, "_annot", None)

A final fix will be included in the new version.

julian-smith-artifex-com pushed a commit that referenced this issue Nov 3, 2022
Additional safeguard when field is being deleted via `page.delete_widget()`:
In this case, the underlying annotation may not have been re-established (attribute "_annot"), which will there for be checked.
@MallRoy MallRoy closed this as completed Nov 3, 2022
jamie-lemon pushed a commit that referenced this issue Dec 12, 2022
Additional safeguard when field is being deleted via `page.delete_widget()`:
In this case, the underlying annotation may not have been re-established (attribute "_annot"), which will there for be checked.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants