PyPDFForm 2.2.5__tar.gz → 2.2.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of PyPDFForm might be problematic. Click here for more details.
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PKG-INFO +1 -1
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/__init__.py +1 -1
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/constants.py +2 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/filler.py +30 -10
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/patterns.py +14 -9
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/template.py +4 -5
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/utils.py +5 -2
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/wrapper.py +7 -3
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm.egg-info/PKG-INFO +1 -1
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_adobe_mode.py +65 -4
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_dropdown_simple.py +1 -1
- {pypdfform-2.2.5 → pypdfform-2.2.7}/LICENSE +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/adapter.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/coordinate.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/font.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/image.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/middleware/__init__.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/middleware/base.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/middleware/checkbox.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/middleware/dropdown.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/middleware/image.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/middleware/radio.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/middleware/signature.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/middleware/text.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/watermark.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/widgets/__init__.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/widgets/base.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/widgets/bedrock.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/widgets/checkbox.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/widgets/dropdown.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/widgets/image.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/widgets/radio.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/widgets/signature.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm/widgets/text.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm.egg-info/SOURCES.txt +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm.egg-info/dependency_links.txt +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm.egg-info/requires.txt +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/PyPDFForm.egg-info/top_level.txt +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/README.md +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/pyproject.toml +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/setup.cfg +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_create_widget.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_dropdown.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_fill_max_length_text_field.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_fill_max_length_text_field_simple.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_fill_method.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_functional.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_functional_simple.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_paragraph.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_paragraph_simple.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_preview.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_signature.py +0 -0
- {pypdfform-2.2.5 → pypdfform-2.2.7}/tests/test_use_full_widget_name.py +0 -0
|
@@ -50,6 +50,7 @@ Ff = "/Ff"
|
|
|
50
50
|
Tx = "/Tx"
|
|
51
51
|
V = "/V"
|
|
52
52
|
AP = "/AP"
|
|
53
|
+
I = "/I" # noqa: E741
|
|
53
54
|
N = "/N"
|
|
54
55
|
Sig = "/Sig"
|
|
55
56
|
DA = "/DA"
|
|
@@ -75,6 +76,7 @@ Off = "/Off"
|
|
|
75
76
|
# For Adobe Acrobat
|
|
76
77
|
AcroForm = "/AcroForm"
|
|
77
78
|
Root = "/Root"
|
|
79
|
+
Fields = "/Fields"
|
|
78
80
|
NeedAppearances = "/NeedAppearances"
|
|
79
81
|
|
|
80
82
|
# Field flag bits
|
|
@@ -16,10 +16,11 @@ from io import BytesIO
|
|
|
16
16
|
from typing import Dict, Tuple, Union, cast
|
|
17
17
|
|
|
18
18
|
from pypdf import PdfReader, PdfWriter
|
|
19
|
-
from pypdf.generic import BooleanObject, DictionaryObject,
|
|
19
|
+
from pypdf.generic import (ArrayObject, BooleanObject, DictionaryObject,
|
|
20
|
+
IndirectObject, NameObject)
|
|
20
21
|
|
|
21
22
|
from .constants import (BUTTON_STYLES, DEFAULT_RADIO_STYLE, WIDGET_TYPES,
|
|
22
|
-
AcroForm, Annots, NeedAppearances, Root, U)
|
|
23
|
+
AcroForm, Annots, Fields, NeedAppearances, Root, U)
|
|
23
24
|
from .coordinate import (get_draw_border_coordinates,
|
|
24
25
|
get_draw_checkbox_radio_coordinates,
|
|
25
26
|
get_draw_image_coordinates_resolutions,
|
|
@@ -37,7 +38,7 @@ from .patterns import (WIDGET_KEY_PATTERNS, simple_flatten_generic,
|
|
|
37
38
|
simple_flatten_radio, simple_update_checkbox_value,
|
|
38
39
|
simple_update_dropdown_value, simple_update_radio_value,
|
|
39
40
|
simple_update_text_value)
|
|
40
|
-
from .template import get_widgets_by_page
|
|
41
|
+
from .template import get_widget_full_key, get_widgets_by_page
|
|
41
42
|
from .utils import (checkbox_radio_to_draw, extract_widget_property,
|
|
42
43
|
stream_to_io)
|
|
43
44
|
from .watermark import create_watermarks_and_draw, merge_watermarks_with_pdf
|
|
@@ -219,6 +220,7 @@ def get_drawn_stream(to_draw: dict, stream: bytes, action: str) -> bytes:
|
|
|
219
220
|
def fill(
|
|
220
221
|
template_stream: bytes,
|
|
221
222
|
widgets: Dict[str, WIDGET_TYPES],
|
|
223
|
+
use_full_widget_name: bool,
|
|
222
224
|
) -> bytes:
|
|
223
225
|
"""Fills a PDF form using watermark technique for complex rendering.
|
|
224
226
|
|
|
@@ -230,6 +232,7 @@ def fill(
|
|
|
230
232
|
Args:
|
|
231
233
|
template_stream: Input PDF form as bytes
|
|
232
234
|
widgets: Dictionary mapping field names to widget middleware
|
|
235
|
+
use_full_widget_name: If True, uses the full widget name as the key in the widgets dictionary
|
|
233
236
|
|
|
234
237
|
Returns:
|
|
235
238
|
bytes: Filled PDF form as bytes
|
|
@@ -252,6 +255,8 @@ def fill(
|
|
|
252
255
|
line_borders_to_draw[page] = []
|
|
253
256
|
for widget_dict in widget_dicts:
|
|
254
257
|
key = extract_widget_property(widget_dict, WIDGET_KEY_PATTERNS, None, str)
|
|
258
|
+
if use_full_widget_name:
|
|
259
|
+
key = get_widget_full_key(widget_dict)
|
|
255
260
|
text_needs_to_be_drawn = False
|
|
256
261
|
to_draw = x = y = None
|
|
257
262
|
|
|
@@ -305,19 +310,34 @@ def fill(
|
|
|
305
310
|
return result
|
|
306
311
|
|
|
307
312
|
|
|
308
|
-
def enable_adobe_mode(
|
|
309
|
-
"""Configures PDF for Adobe Acrobat compatibility
|
|
313
|
+
def enable_adobe_mode(reader: PdfReader, writer: PdfWriter, adobe_mode: bool) -> None:
|
|
314
|
+
"""Configures the PDF for Adobe Acrobat compatibility by setting the NeedAppearances flag
|
|
315
|
+
and ensuring the AcroForm structure is properly initialized.
|
|
310
316
|
|
|
311
317
|
Args:
|
|
312
|
-
|
|
313
|
-
|
|
318
|
+
reader: PdfReader instance of the PDF
|
|
319
|
+
writer: PdfWriter instance to configure
|
|
320
|
+
adobe_mode: If True, enables Adobe Acrobat compatibility mode
|
|
314
321
|
"""
|
|
315
322
|
|
|
316
|
-
if adobe_mode
|
|
317
|
-
|
|
323
|
+
if not adobe_mode:
|
|
324
|
+
return
|
|
325
|
+
|
|
326
|
+
# https://stackoverflow.com/questions/47288578/pdf-form-filled-with-pypdf2-does-not-show-in-print
|
|
327
|
+
if AcroForm in reader.trailer[Root]:
|
|
328
|
+
reader.trailer[Root][AcroForm].update(
|
|
318
329
|
{NameObject(NeedAppearances): BooleanObject(True)}
|
|
319
330
|
)
|
|
320
331
|
|
|
332
|
+
if AcroForm not in writer.root_object:
|
|
333
|
+
writer.root_object.update(
|
|
334
|
+
{NameObject(AcroForm): IndirectObject(len(writer.root_object), 0, writer)}
|
|
335
|
+
)
|
|
336
|
+
writer.root_object[AcroForm][NameObject(NeedAppearances)] = BooleanObject( # noqa
|
|
337
|
+
True
|
|
338
|
+
)
|
|
339
|
+
writer.root_object[AcroForm][NameObject(Fields)] = ArrayObject() # noqa
|
|
340
|
+
|
|
321
341
|
|
|
322
342
|
def simple_fill(
|
|
323
343
|
template: bytes,
|
|
@@ -343,8 +363,8 @@ def simple_fill(
|
|
|
343
363
|
"""
|
|
344
364
|
|
|
345
365
|
pdf = PdfReader(stream_to_io(template))
|
|
346
|
-
enable_adobe_mode(pdf, adobe_mode)
|
|
347
366
|
out = PdfWriter()
|
|
367
|
+
enable_adobe_mode(pdf, out, adobe_mode)
|
|
348
368
|
out.append(pdf)
|
|
349
369
|
|
|
350
370
|
radio_button_tracker = {}
|
|
@@ -15,13 +15,13 @@ The module also contains utility functions for common PDF form operations
|
|
|
15
15
|
like updating field values and flattening form fields.
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
from pypdf.generic import (DictionaryObject, NameObject,
|
|
19
|
-
TextStringObject)
|
|
18
|
+
from pypdf.generic import (ArrayObject, DictionaryObject, NameObject,
|
|
19
|
+
NumberObject, TextStringObject)
|
|
20
20
|
|
|
21
21
|
from .constants import (AP, AS, BC, BG, BS, CA, DA, DV, FT,
|
|
22
22
|
IMAGE_FIELD_IDENTIFIER, JS, MK, MULTILINE, READ_ONLY,
|
|
23
|
-
TU, A, Btn, Ch, D, Ff, N, Off, Opt, Parent, Q, S,
|
|
24
|
-
T, Tx, V, W, Yes)
|
|
23
|
+
TU, A, Btn, Ch, D, Ff, I, N, Off, Opt, Parent, Q, S,
|
|
24
|
+
Sig, T, Tx, V, W, Yes)
|
|
25
25
|
from .middleware.checkbox import Checkbox
|
|
26
26
|
from .middleware.dropdown import Dropdown
|
|
27
27
|
from .middleware.image import Image
|
|
@@ -160,13 +160,17 @@ def simple_update_radio_value(annot: DictionaryObject) -> None:
|
|
|
160
160
|
"""Update radio button annotation values to selected state.
|
|
161
161
|
|
|
162
162
|
Modifies the appearance state (AS) of a radio button annotation and updates
|
|
163
|
-
the parent's value (V) to reflect the selected state.
|
|
164
|
-
|
|
163
|
+
the parent's value (V) to reflect the selected state. Removes 'Opt' entry
|
|
164
|
+
from parent dictionary if present. Uses the annotation's appearance
|
|
165
|
+
dictionary (AP/N) to determine valid states.
|
|
165
166
|
|
|
166
167
|
Args:
|
|
167
168
|
annot: PDF radio button annotation dictionary to modify
|
|
168
169
|
"""
|
|
169
170
|
|
|
171
|
+
if Opt in annot[Parent]:
|
|
172
|
+
del annot[Parent][Opt] # noqa
|
|
173
|
+
|
|
170
174
|
for each in annot[AP][N]: # noqa
|
|
171
175
|
if str(each) != Off:
|
|
172
176
|
annot[NameObject(AS)] = NameObject(each)
|
|
@@ -177,9 +181,9 @@ def simple_update_radio_value(annot: DictionaryObject) -> None:
|
|
|
177
181
|
def simple_update_dropdown_value(annot: DictionaryObject, widget: Dropdown) -> None:
|
|
178
182
|
"""Update dropdown annotation values based on widget selection.
|
|
179
183
|
|
|
180
|
-
Modifies the value (V)
|
|
181
|
-
reflect the currently selected choice from the widget.
|
|
182
|
-
standalone dropdowns and those with parent annotations.
|
|
184
|
+
Modifies the value (V), appearance (AP), and index (I) of a dropdown
|
|
185
|
+
annotation to reflect the currently selected choice from the widget.
|
|
186
|
+
Handles both standalone dropdowns and those with parent annotations.
|
|
183
187
|
|
|
184
188
|
Args:
|
|
185
189
|
annot: PDF dropdown annotation dictionary to modify
|
|
@@ -194,6 +198,7 @@ def simple_update_dropdown_value(annot: DictionaryObject, widget: Dropdown) -> N
|
|
|
194
198
|
else:
|
|
195
199
|
annot[NameObject(V)] = TextStringObject(widget.choices[widget.value])
|
|
196
200
|
annot[NameObject(AP)] = TextStringObject(widget.choices[widget.value])
|
|
201
|
+
annot[NameObject(I)] = ArrayObject([NumberObject(widget.value)])
|
|
197
202
|
|
|
198
203
|
|
|
199
204
|
def simple_update_text_value(annot: DictionaryObject, widget: Text) -> None:
|
|
@@ -246,15 +246,14 @@ def get_widgets_by_page(pdf: bytes) -> Dict[int, List[dict]]:
|
|
|
246
246
|
return result
|
|
247
247
|
|
|
248
248
|
|
|
249
|
-
def get_widget_full_key(widget: dict) ->
|
|
249
|
+
def get_widget_full_key(widget: dict) -> str:
|
|
250
250
|
"""Constructs a widget's full hierarchical key including parent names.
|
|
251
251
|
|
|
252
252
|
Args:
|
|
253
253
|
widget: PDF widget dictionary
|
|
254
254
|
|
|
255
255
|
Returns:
|
|
256
|
-
|
|
257
|
-
otherwise None
|
|
256
|
+
str: Full key in format "parent.child" if parent exists, otherwise the widget's key
|
|
258
257
|
"""
|
|
259
258
|
|
|
260
259
|
key = extract_widget_property(widget, WIDGET_KEY_PATTERNS, None, str)
|
|
@@ -264,9 +263,9 @@ def get_widget_full_key(widget: dict) -> Union[str, None]:
|
|
|
264
263
|
and T in widget[Parent].get_object()
|
|
265
264
|
and widget[Parent].get_object()[T] != key
|
|
266
265
|
):
|
|
267
|
-
|
|
266
|
+
key = f"{get_widget_full_key(widget[Parent].get_object())}.{key}"
|
|
268
267
|
|
|
269
|
-
return
|
|
268
|
+
return key
|
|
270
269
|
|
|
271
270
|
|
|
272
271
|
def construct_widget(widget: dict, key: str) -> Union[WIDGET_TYPES, None]:
|
|
@@ -104,10 +104,13 @@ def checkbox_radio_to_draw(
|
|
|
104
104
|
return new_widget
|
|
105
105
|
|
|
106
106
|
|
|
107
|
-
def preview_widget_to_draw(
|
|
107
|
+
def preview_widget_to_draw(
|
|
108
|
+
widget_name: str, widget: WIDGET_TYPES, with_preview_text: bool
|
|
109
|
+
) -> Text:
|
|
108
110
|
"""Creates preview version of a widget showing field name/location.
|
|
109
111
|
|
|
110
112
|
Args:
|
|
113
|
+
widget_name: Name of the widget to generate preview for
|
|
111
114
|
widget: Widget to generate preview for
|
|
112
115
|
with_preview_text: Whether to include field name in preview
|
|
113
116
|
|
|
@@ -117,7 +120,7 @@ def preview_widget_to_draw(widget: WIDGET_TYPES, with_preview_text: bool) -> Tex
|
|
|
117
120
|
|
|
118
121
|
new_widget = Text(
|
|
119
122
|
name=widget.name,
|
|
120
|
-
value="{" + f" {
|
|
123
|
+
value="{" + f" {widget_name} " + "}" if with_preview_text else None,
|
|
121
124
|
)
|
|
122
125
|
new_widget.font = DEFAULT_FONT
|
|
123
126
|
new_widget.font_size = DEFAULT_FONT_SIZE
|
|
@@ -362,9 +362,10 @@ class PdfWrapper(FormWrapper):
|
|
|
362
362
|
fill(
|
|
363
363
|
self.stream,
|
|
364
364
|
{
|
|
365
|
-
key: preview_widget_to_draw(value, True)
|
|
365
|
+
key: preview_widget_to_draw(key, value, True)
|
|
366
366
|
for key, value in self.widgets.items()
|
|
367
367
|
},
|
|
368
|
+
getattr(self, "use_full_widget_name"),
|
|
368
369
|
)
|
|
369
370
|
)
|
|
370
371
|
|
|
@@ -391,9 +392,10 @@ class PdfWrapper(FormWrapper):
|
|
|
391
392
|
fill(
|
|
392
393
|
self.stream,
|
|
393
394
|
{
|
|
394
|
-
key: preview_widget_to_draw(value, False)
|
|
395
|
+
key: preview_widget_to_draw(key, value, False)
|
|
395
396
|
for key, value in self.widgets.items()
|
|
396
397
|
},
|
|
398
|
+
getattr(self, "use_full_widget_name"),
|
|
397
399
|
)
|
|
398
400
|
),
|
|
399
401
|
color,
|
|
@@ -434,7 +436,9 @@ class PdfWrapper(FormWrapper):
|
|
|
434
436
|
if self.read():
|
|
435
437
|
self.widgets = set_character_x_paddings(self.stream, self.widgets)
|
|
436
438
|
|
|
437
|
-
self.stream = remove_all_widgets(
|
|
439
|
+
self.stream = remove_all_widgets(
|
|
440
|
+
fill(self.stream, self.widgets, getattr(self, "use_full_widget_name"))
|
|
441
|
+
)
|
|
438
442
|
|
|
439
443
|
return self
|
|
440
444
|
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
|
|
5
|
-
from PyPDFForm import FormWrapper
|
|
5
|
+
from PyPDFForm import FormWrapper, PdfWrapper
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
def
|
|
8
|
+
def test_dropdown_two(sample_template_with_dropdown, pdf_samples, request):
|
|
9
9
|
expected_path = os.path.join(
|
|
10
|
-
pdf_samples, "adobe_mode", "dropdown", "
|
|
10
|
+
pdf_samples, "adobe_mode", "dropdown", "dropdown_two.pdf"
|
|
11
11
|
)
|
|
12
12
|
with open(expected_path, "rb+") as f:
|
|
13
13
|
obj = FormWrapper(sample_template_with_dropdown).fill(
|
|
@@ -19,7 +19,7 @@ def test_dropdown_one(sample_template_with_dropdown, pdf_samples, request):
|
|
|
19
19
|
"check_2": True,
|
|
20
20
|
"check_3": True,
|
|
21
21
|
"radio_1": 1,
|
|
22
|
-
"dropdown_1":
|
|
22
|
+
"dropdown_1": 1,
|
|
23
23
|
},
|
|
24
24
|
adobe_mode=True,
|
|
25
25
|
)
|
|
@@ -95,3 +95,64 @@ def test_issue_613(pdf_samples, request):
|
|
|
95
95
|
|
|
96
96
|
assert len(obj.read()) == len(expected)
|
|
97
97
|
assert obj.stream == expected
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def test_sample_template_libary(pdf_samples, request):
|
|
101
|
+
expected_path = os.path.join(
|
|
102
|
+
pdf_samples, "adobe_mode", "test_sample_template_libary.pdf"
|
|
103
|
+
)
|
|
104
|
+
template = (
|
|
105
|
+
PdfWrapper(os.path.join(pdf_samples, "dummy.pdf"))
|
|
106
|
+
.create_widget(
|
|
107
|
+
widget_type="text",
|
|
108
|
+
name="new_text_field_widget",
|
|
109
|
+
page_number=1,
|
|
110
|
+
x=60,
|
|
111
|
+
y=710,
|
|
112
|
+
)
|
|
113
|
+
.create_widget(
|
|
114
|
+
widget_type="checkbox",
|
|
115
|
+
name="new_checkbox_widget",
|
|
116
|
+
page_number=1,
|
|
117
|
+
x=100,
|
|
118
|
+
y=600,
|
|
119
|
+
)
|
|
120
|
+
.create_widget(
|
|
121
|
+
widget_type="radio",
|
|
122
|
+
name="new_radio_group",
|
|
123
|
+
page_number=1,
|
|
124
|
+
x=[50, 100, 150],
|
|
125
|
+
y=[50, 100, 150],
|
|
126
|
+
)
|
|
127
|
+
.create_widget(
|
|
128
|
+
widget_type="dropdown",
|
|
129
|
+
name="new_dropdown_widget",
|
|
130
|
+
page_number=1,
|
|
131
|
+
x=300,
|
|
132
|
+
y=710,
|
|
133
|
+
options=[
|
|
134
|
+
"foo",
|
|
135
|
+
"bar",
|
|
136
|
+
"foobar",
|
|
137
|
+
],
|
|
138
|
+
)
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
with open(expected_path, "rb+") as f:
|
|
142
|
+
obj = FormWrapper(template.read()).fill(
|
|
143
|
+
{
|
|
144
|
+
"new_text_field_widget": "test text",
|
|
145
|
+
"new_checkbox_widget": True,
|
|
146
|
+
"new_radio_group": 1,
|
|
147
|
+
"new_dropdown_widget": 2,
|
|
148
|
+
},
|
|
149
|
+
adobe_mode=True,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
request.config.results["expected_path"] = expected_path
|
|
153
|
+
request.config.results["stream"] = obj.read()
|
|
154
|
+
|
|
155
|
+
expected = f.read()
|
|
156
|
+
|
|
157
|
+
assert len(obj.read()) == len(expected)
|
|
158
|
+
assert obj.stream == expected
|
|
@@ -75,7 +75,7 @@ def test_dropdown_two(sample_template_with_dropdown, pdf_samples, request):
|
|
|
75
75
|
|
|
76
76
|
def test_dropdown_two_flatten(sample_template_with_dropdown, pdf_samples, request):
|
|
77
77
|
expected_path = os.path.join(
|
|
78
|
-
pdf_samples, "simple", "dropdown", "
|
|
78
|
+
pdf_samples, "simple", "dropdown", "dropdown_two_flatten.pdf"
|
|
79
79
|
)
|
|
80
80
|
with open(expected_path, "rb+") as f:
|
|
81
81
|
obj = FormWrapper(sample_template_with_dropdown).fill(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|