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

BUG: Make reader.get_fields also return dropdowns with options #1114

Merged
merged 10 commits into from
Jul 21, 2022
15 changes: 12 additions & 3 deletions PyPDF2/_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@
from .constants import CatalogDictionary as CD
from .constants import Core as CO
from .constants import DocumentInformationAttributes as DI
from .constants import FieldDictionaryAttributes, GoToActionArguments
from .constants import (
FieldDictionaryAttributes,
GoToActionArguments,
CheckboxRadioButtonAttributes,
)
from .constants import PageAttributes as PG
from .constants import PagesAttributes as PA
from .constants import TrailerKeys as TK
Expand Down Expand Up @@ -478,6 +482,7 @@ def get_fields(
``None`` if form data could not be located.
"""
field_attributes = FieldDictionaryAttributes.attributes_dict()
field_attributes.update(CheckboxRadioButtonAttributes.attributes_dict())
if retval is None:
retval = {}
catalog = cast(DictionaryObject, self.trailer[TK.ROOT])
Expand All @@ -488,7 +493,6 @@ def get_fields(
return None
if tree is None:
return retval

self._check_kids(tree, retval, fileobj)
for attr in field_attributes:
if attr in tree:
Expand Down Expand Up @@ -548,7 +552,12 @@ def _check_kids(
self.get_fields(kid.get_object(), retval, fileobj)

def _write_field(self, fileobj: Any, field: Any, field_attributes: Any) -> None:
for attr in FieldDictionaryAttributes.attributes():
field_attributes_tuple = FieldDictionaryAttributes.attributes()
field_attributes_tuple = (
field_attributes_tuple + CheckboxRadioButtonAttributes.attributes()
)

for attr in field_attributes_tuple:
if attr in (
FieldDictionaryAttributes.Kids,
FieldDictionaryAttributes.AA,
Expand Down
17 changes: 17 additions & 0 deletions PyPDF2/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,22 @@ def attributes_dict(cls) -> Dict[str, str]:
}


class CheckboxRadioButtonAttributes:
"""TABLE 8.76 Field flags common to all field types"""

Opt = "/Opt" # Options, Optional

@classmethod
def attributes(cls) -> Tuple[str, ...]:
return (cls.Opt,)

@classmethod
def attributes_dict(cls) -> Dict[str, str]:
return {
cls.Opt: "Options",
}


class FieldFlag(IntFlag):
"""TABLE 8.70 Field flags common to all field types"""

Expand Down Expand Up @@ -411,6 +427,7 @@ class CatalogDictionary:
CatalogAttributes,
CatalogDictionary,
CcittFaxDecodeParameters,
CheckboxRadioButtonAttributes,
ColorSpaces,
Core,
DocumentInformationAttributes,
Expand Down
7 changes: 4 additions & 3 deletions PyPDF2/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
skip_over_comment,
str_,
)
from .constants import FieldDictionaryAttributes
from .constants import CheckboxRadioButtonAttributes, FieldDictionaryAttributes
from .constants import FilterTypes as FT
from .constants import StreamAttributes as SA
from .constants import TypArguments as TA
Expand Down Expand Up @@ -1618,8 +1618,9 @@ class Field(TreeObject):

def __init__(self, data: Dict[str, Any]) -> None:
DictionaryObject.__init__(self)

for attr in FieldDictionaryAttributes.attributes():
Field_attributes = FieldDictionaryAttributes.attributes()
Field_attributes = Field_attributes + CheckboxRadioButtonAttributes.attributes()
for attr in Field_attributes:
try:
self[NameObject(attr)] = data[attr]
except KeyError:
Expand Down
Binary file added resources/libreoffice-form.pdf
Binary file not shown.
5 changes: 5 additions & 0 deletions tests/test_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Bookmark,
BooleanObject,
ByteStringObject,
CheckboxRadioButtonAttributes,
Destination,
DictionaryObject,
FloatObject,
Expand Down Expand Up @@ -491,3 +492,7 @@ def test_issue_997():

# cleanup
os.remove(merged_filename)


def test_CheckboxRadioButtonAttributes_opt():
assert "/Opt" in CheckboxRadioButtonAttributes.attributes_dict()
7 changes: 7 additions & 0 deletions tests/test_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
sys.path.append(PROJECT_ROOT)


def test_dropdown_items():
with open(os.path.join(RESOURCE_ROOT, "libreoffice-form.pdf"), "rb") as inputfile:
reader = PdfReader(inputfile)
fields = reader.get_fields()
assert "/Opt" in fields["Nationality"].keys()


def test_PdfReaderFileLoad():
"""
Test loading and parsing of a file. Extract text of the file and compare to expected
Expand Down