PyPDFForm 5.5.4__tar.gz → 5.6.0__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.
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PKG-INFO +2 -2
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/__init__.py +1 -1
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/cli/root.py +9 -4
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/filler.py +11 -11
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/hooks.py +8 -7
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/middleware/base.py +1 -1
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/utils.py +1 -1
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/wrapper.py +9 -2
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm.egg-info/PKG-INFO +2 -2
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm.egg-info/requires.txt +1 -1
- {pypdfform-5.5.4 → pypdfform-5.6.0}/pyproject.toml +1 -1
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_create_widget.py +6 -6
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_dropdown.py +12 -12
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_extract_middleware_attributes.py +2 -2
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_fill_max_length_text_field.py +4 -3
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_functional.py +26 -18
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_paragraph.py +3 -3
- {pypdfform-5.5.4 → pypdfform-5.6.0}/LICENSE +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/cli/__init__.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/cli/common.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/cli/create.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/cli/entry.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/cli/inspect.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/cli/remove.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/cli/schemas/__init__.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/cli/schemas/create.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/cli/schemas/update.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/cli/update.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/__init__.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/adapter.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/annotations/__init__.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/annotations/base.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/annotations/link.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/annotations/stamp.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/annotations/text.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/annotations/text_markup.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/assets/__init__.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/assets/blank.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/constants.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/coordinate.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/deprecation.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/egress.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/font.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/image.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/middleware/__init__.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/middleware/checkbox.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/middleware/dropdown.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/middleware/image.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/middleware/radio.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/middleware/signature.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/middleware/text.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/patterns.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/raw/__init__.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/raw/circle.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/raw/ellipse.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/raw/image.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/raw/line.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/raw/rect.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/raw/text.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/template.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/types.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/watermark.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/widgets/__init__.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/widgets/base.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/widgets/checkbox.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/widgets/dropdown.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/widgets/image.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/widgets/radio.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/widgets/signature.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm/lib/widgets/text.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm.egg-info/SOURCES.txt +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm.egg-info/dependency_links.txt +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm.egg-info/entry_points.txt +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/PyPDFForm.egg-info/top_level.txt +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/README.md +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/setup.cfg +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_bulk_create_fields.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_draw_elements.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_font_widths.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_generate_appearance_streams.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_js.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_need_appearances.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_signature.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_use_full_widget_name.py +0 -0
- {pypdfform-5.5.4 → pypdfform-5.6.0}/tests/test_widget_attr_trigger.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyPDFForm
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.6.0
|
|
4
4
|
Summary: The Python library & CLI for PDF forms.
|
|
5
5
|
Author: Jinge Li
|
|
6
6
|
License-Expression: MIT
|
|
@@ -24,7 +24,7 @@ Classifier: Topic :: Utilities
|
|
|
24
24
|
Requires-Python: >=3.10
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: LICENSE
|
|
27
|
-
Requires-Dist: cryptography<
|
|
27
|
+
Requires-Dist: cryptography<51.0.0,>=50.0.0
|
|
28
28
|
Requires-Dist: fonttools<5.0.0,>=4.63.0
|
|
29
29
|
Requires-Dist: pikepdf<11.0.0,>=10.7.2
|
|
30
30
|
Requires-Dist: pillow<13.0.0,>=12.2.0
|
|
@@ -165,8 +165,12 @@ def fill(
|
|
|
165
165
|
output: OPTIONAL_OUTPUT_PDF = None,
|
|
166
166
|
flatten: Annotated[
|
|
167
167
|
bool,
|
|
168
|
-
typer.Option("--flatten", help="
|
|
168
|
+
typer.Option("--flatten", help="Deprecated alias for --readonly.", hidden=True),
|
|
169
169
|
] = None,
|
|
170
|
+
readonly: Annotated[
|
|
171
|
+
bool,
|
|
172
|
+
typer.Option("--readonly", help="Make form fields read-only when filling."),
|
|
173
|
+
] = False,
|
|
170
174
|
) -> None:
|
|
171
175
|
"""
|
|
172
176
|
Fill an existing PDF form from a data file or command-line options.
|
|
@@ -187,8 +191,9 @@ def fill(
|
|
|
187
191
|
options in ``ctx.args``. Defaults to None.
|
|
188
192
|
output (Path, optional): Output PDF path. If omitted, the input PDF is
|
|
189
193
|
overwritten. Defaults to None.
|
|
190
|
-
flatten (bool, optional):
|
|
191
|
-
|
|
194
|
+
flatten (bool, optional): Deprecated alias for `readonly`. Defaults to None.
|
|
195
|
+
readonly (bool): Whether to make form fields read-only when filling.
|
|
196
|
+
Defaults to False. Either `readonly` or `flatten` enables read-only fields.
|
|
192
197
|
"""
|
|
193
198
|
obj = PdfWrapper(str(pdf), **ctx.obj)
|
|
194
199
|
|
|
@@ -226,4 +231,4 @@ def fill(
|
|
|
226
231
|
)
|
|
227
232
|
input_data[k] = input_data[k]["path"]
|
|
228
233
|
|
|
229
|
-
obj.fill(input_data, flatten=flatten).write(output or pdf)
|
|
234
|
+
obj.fill(input_data, readonly=readonly, flatten=flatten).write(output or pdf)
|
|
@@ -5,7 +5,7 @@ Module containing functions to fill PDF forms.
|
|
|
5
5
|
This module provides the core functionality for filling PDF forms programmatically.
|
|
6
6
|
It includes functions for handling various form field types, such as text fields,
|
|
7
7
|
checkboxes, radio buttons, dropdowns, images, and signatures. The module also
|
|
8
|
-
supports
|
|
8
|
+
supports making the filled form read-only to prevent further modifications.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
from io import BytesIO
|
|
@@ -15,7 +15,7 @@ from pypdf import PdfWriter
|
|
|
15
15
|
from pypdf.generic import DictionaryObject
|
|
16
16
|
|
|
17
17
|
from .constants import Annots
|
|
18
|
-
from .hooks import
|
|
18
|
+
from .hooks import update_field_readonly
|
|
19
19
|
from .image import get_draw_image_resolutions, get_image_dimensions
|
|
20
20
|
from .middleware import WIDGET_TYPES
|
|
21
21
|
from .middleware.checkbox import Checkbox
|
|
@@ -84,12 +84,12 @@ def update_widget(
|
|
|
84
84
|
radio_button_tracker: Dict[str, int],
|
|
85
85
|
images_to_draw_page: list,
|
|
86
86
|
need_appearances: bool,
|
|
87
|
-
|
|
87
|
+
readonly: bool,
|
|
88
88
|
) -> bool:
|
|
89
89
|
"""Updates a single widget's value and handles its properties.
|
|
90
90
|
|
|
91
91
|
This function updates the value of a single PDF form widget based on its type. It sets
|
|
92
|
-
the read-only flag first when
|
|
92
|
+
the read-only flag first when requested, skips value updates when the
|
|
93
93
|
middleware value is ``None``, tracks radio option indices within each group, and
|
|
94
94
|
prepares images or signatures for later drawing instead of writing image data directly
|
|
95
95
|
into the annotation.
|
|
@@ -101,13 +101,13 @@ def update_widget(
|
|
|
101
101
|
radio_button_tracker (Dict[str, int]): A tracker for radio button groups to manage their indices.
|
|
102
102
|
images_to_draw_page (list): A list to store image data for the current page.
|
|
103
103
|
need_appearances (bool): If True, skips updating appearance streams for certain fields.
|
|
104
|
-
|
|
104
|
+
readonly (bool): Whether to make the widget read-only to prevent further editing.
|
|
105
105
|
|
|
106
106
|
Returns:
|
|
107
107
|
bool: True if an image or signature was prepared for drawing, False otherwise.
|
|
108
108
|
"""
|
|
109
|
-
if
|
|
110
|
-
|
|
109
|
+
if readonly:
|
|
110
|
+
update_field_readonly(annot, True)
|
|
111
111
|
if widget.value is None:
|
|
112
112
|
return False
|
|
113
113
|
|
|
@@ -137,7 +137,7 @@ def handle_image_drawing(
|
|
|
137
137
|
"""Merges prepared images and signatures with the filled PDF.
|
|
138
138
|
|
|
139
139
|
This function takes the filled PDF and a dictionary of images to draw (from signatures
|
|
140
|
-
or image fields),
|
|
140
|
+
or image fields), combines that page-indexed structure into watermark drawing
|
|
141
141
|
instructions, and merges those image watermarks into the PDF.
|
|
142
142
|
|
|
143
143
|
Args:
|
|
@@ -161,7 +161,7 @@ def fill(
|
|
|
161
161
|
widgets: Dict[str, WIDGET_TYPES],
|
|
162
162
|
need_appearances: bool,
|
|
163
163
|
use_full_widget_name: bool,
|
|
164
|
-
|
|
164
|
+
readonly: bool = False,
|
|
165
165
|
) -> tuple:
|
|
166
166
|
"""Fills a PDF template with the given widgets.
|
|
167
167
|
|
|
@@ -181,7 +181,7 @@ def fill(
|
|
|
181
181
|
behavior for certain fields.
|
|
182
182
|
use_full_widget_name (bool): Whether to use the full widget name when looking up widgets
|
|
183
183
|
in the `widgets` dictionary.
|
|
184
|
-
|
|
184
|
+
readonly (bool): Whether to make form fields read-only. Defaults to False.
|
|
185
185
|
|
|
186
186
|
Returns:
|
|
187
187
|
tuple: A tuple containing the filled PDF as bytes and the image-drawn
|
|
@@ -211,7 +211,7 @@ def fill(
|
|
|
211
211
|
radio_button_tracker,
|
|
212
212
|
images_to_draw[page_num + 1],
|
|
213
213
|
need_appearances,
|
|
214
|
-
|
|
214
|
+
readonly,
|
|
215
215
|
)
|
|
216
216
|
|
|
217
217
|
with BytesIO() as f:
|
|
@@ -4,9 +4,10 @@ This module defines widget hooks that allow for dynamic modification of PDF form
|
|
|
4
4
|
|
|
5
5
|
It provides functions to trigger these hooks, enabling changes to text field properties
|
|
6
6
|
like font, font size, color, alignment, and multiline settings, as well as the size
|
|
7
|
-
of checkbox and radio button widgets. It also provides functions for
|
|
8
|
-
generic and radio button widgets. These hooks are triggered during
|
|
9
|
-
filling process, allowing for customization of the form's appearance
|
|
7
|
+
of checkbox and radio button widgets. It also provides functions for changing the
|
|
8
|
+
editability of generic and radio button widgets. These hooks are triggered during
|
|
9
|
+
the PDF form filling process, allowing for customization of the form's appearance
|
|
10
|
+
and behavior.
|
|
10
11
|
"""
|
|
11
12
|
|
|
12
13
|
import sys
|
|
@@ -362,10 +363,10 @@ def update_dropdown_choices(annot: DictionaryObject, val: list) -> None:
|
|
|
362
363
|
)
|
|
363
364
|
|
|
364
365
|
|
|
365
|
-
def
|
|
366
|
+
def update_field_readonly(annot: DictionaryObject, val: bool) -> None:
|
|
366
367
|
"""
|
|
367
|
-
|
|
368
|
-
making it
|
|
368
|
+
Sets or unsets the ReadOnly flag on a form field annotation,
|
|
369
|
+
making it read-only or editable based on the `val` parameter.
|
|
369
370
|
|
|
370
371
|
This function modifies the Ff (flags) entry in the annotation dictionary to
|
|
371
372
|
set or unset the ReadOnly flag, preventing or allowing the user from
|
|
@@ -373,7 +374,7 @@ def flatten_field(annot: DictionaryObject, val: bool) -> None:
|
|
|
373
374
|
|
|
374
375
|
Args:
|
|
375
376
|
annot (DictionaryObject): The annotation dictionary.
|
|
376
|
-
val (bool): True to
|
|
377
|
+
val (bool): True to make the field read-only, False to make it editable.
|
|
377
378
|
"""
|
|
378
379
|
_update_field_flag(annot, READ_ONLY, val)
|
|
379
380
|
|
|
@@ -42,7 +42,7 @@ class Widget:
|
|
|
42
42
|
"y": "update_field_y",
|
|
43
43
|
"width": "update_field_width",
|
|
44
44
|
"height": "update_field_height",
|
|
45
|
-
"readonly": "
|
|
45
|
+
"readonly": "update_field_readonly",
|
|
46
46
|
"required": "update_field_required",
|
|
47
47
|
"hidden": "update_field_hidden",
|
|
48
48
|
"tooltip": "update_field_tooltip",
|
|
@@ -31,7 +31,7 @@ from .constants import (
|
|
|
31
31
|
|
|
32
32
|
def remove_all_widgets(pdf: bytes) -> bytes:
|
|
33
33
|
"""
|
|
34
|
-
Removes all widgets (form fields) from a PDF
|
|
34
|
+
Removes all widgets (form fields) from a PDF.
|
|
35
35
|
|
|
36
36
|
This function takes a PDF as a bytes stream, removes all of its interactive
|
|
37
37
|
form field annotations from each page, and returns the modified PDF as a
|
|
@@ -676,12 +676,19 @@ class PdfWrapper:
|
|
|
676
676
|
are form field names and values are the data to fill the fields with.
|
|
677
677
|
Values can be strings, booleans, integers, file-like objects, or bytes.
|
|
678
678
|
**kwargs: Additional keyword arguments:
|
|
679
|
-
- `
|
|
679
|
+
- `readonly` (bool): Whether to make form fields read-only when filling (default: False).
|
|
680
|
+
- `flatten` (bool): Deprecated alias for `readonly` (default: False).
|
|
681
|
+
Emits a deprecation warning when True. Fields become read-only
|
|
682
|
+
if either option is True; False does not make existing read-only fields editable.
|
|
680
683
|
|
|
681
684
|
Returns:
|
|
682
685
|
PdfWrapper: The `PdfWrapper` object, allowing for method chaining.
|
|
683
686
|
"""
|
|
684
687
|
|
|
688
|
+
flatten = kwargs.get("flatten", False)
|
|
689
|
+
if flatten:
|
|
690
|
+
deprecation_notice("fill.readonly", "flatten").emit_notice(self, "fill")
|
|
691
|
+
|
|
685
692
|
for key, value in data.items():
|
|
686
693
|
if key in self.widgets:
|
|
687
694
|
self.widgets[key].value = value
|
|
@@ -691,7 +698,7 @@ class PdfWrapper:
|
|
|
691
698
|
self.widgets,
|
|
692
699
|
need_appearances=getattr(self, "need_appearances"),
|
|
693
700
|
use_full_widget_name=getattr(self, "use_full_widget_name"),
|
|
694
|
-
|
|
701
|
+
readonly=kwargs.get("readonly", False) or flatten,
|
|
695
702
|
)
|
|
696
703
|
|
|
697
704
|
if image_drawn_stream is not None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyPDFForm
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.6.0
|
|
4
4
|
Summary: The Python library & CLI for PDF forms.
|
|
5
5
|
Author: Jinge Li
|
|
6
6
|
License-Expression: MIT
|
|
@@ -24,7 +24,7 @@ Classifier: Topic :: Utilities
|
|
|
24
24
|
Requires-Python: >=3.10
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: LICENSE
|
|
27
|
-
Requires-Dist: cryptography<
|
|
27
|
+
Requires-Dist: cryptography<51.0.0,>=50.0.0
|
|
28
28
|
Requires-Dist: fonttools<5.0.0,>=4.63.0
|
|
29
29
|
Requires-Dist: pikepdf<11.0.0,>=10.7.2
|
|
30
30
|
Requires-Dist: pillow<13.0.0,>=12.2.0
|
|
@@ -311,13 +311,13 @@ def test_create_checkbox_persist_old_widgets_fill(
|
|
|
311
311
|
|
|
312
312
|
|
|
313
313
|
@pytest.mark.requires_zlib_over_zlib_ng
|
|
314
|
-
def
|
|
314
|
+
def test_create_widget_sejda_fill_readonly_before(sejda_template, pdf_samples, request):
|
|
315
315
|
expected_path = os.path.join(
|
|
316
|
-
pdf_samples, "widget", "
|
|
316
|
+
pdf_samples, "widget", "test_create_widget_sejda_fill_readonly_before.pdf"
|
|
317
317
|
)
|
|
318
318
|
with open(expected_path, "rb+") as f:
|
|
319
319
|
obj = PdfWrapper(sejda_template)
|
|
320
|
-
obj.fill(obj.sample_data,
|
|
320
|
+
obj.fill(obj.sample_data, readonly=True).bulk_create_fields(
|
|
321
321
|
[
|
|
322
322
|
Fields.TextField(
|
|
323
323
|
name="new_text_field_widget",
|
|
@@ -345,9 +345,9 @@ def test_create_widget_sejda_fill_flatten_before(sejda_template, pdf_samples, re
|
|
|
345
345
|
|
|
346
346
|
|
|
347
347
|
@pytest.mark.requires_zlib_over_zlib_ng
|
|
348
|
-
def
|
|
348
|
+
def test_create_widget_sejda_fill_readonly_after(sejda_template, pdf_samples, request):
|
|
349
349
|
expected_path = os.path.join(
|
|
350
|
-
pdf_samples, "widget", "
|
|
350
|
+
pdf_samples, "widget", "test_create_widget_sejda_fill_readonly_after.pdf"
|
|
351
351
|
)
|
|
352
352
|
with open(expected_path, "rb+") as f:
|
|
353
353
|
obj = PdfWrapper(sejda_template)
|
|
@@ -366,7 +366,7 @@ def test_create_widget_sejda_fill_flatten_after(sejda_template, pdf_samples, req
|
|
|
366
366
|
font_color=(0, 0, 1),
|
|
367
367
|
)
|
|
368
368
|
]
|
|
369
|
-
).fill(obj.sample_data,
|
|
369
|
+
).fill(obj.sample_data, readonly=True)
|
|
370
370
|
assert obj.schema["properties"]["new_text_field_widget"]["type"] == "string"
|
|
371
371
|
|
|
372
372
|
request.config.results["expected_path"] = expected_path
|
|
@@ -37,9 +37,9 @@ def test_dropdown_not_specified(sample_template_with_dropdown):
|
|
|
37
37
|
)
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
def
|
|
40
|
+
def test_dropdown_one_readonly(sample_template_with_dropdown, pdf_samples, request):
|
|
41
41
|
expected_path = os.path.join(
|
|
42
|
-
pdf_samples, "dropdown", "
|
|
42
|
+
pdf_samples, "dropdown", "test_dropdown_one_readonly.pdf"
|
|
43
43
|
)
|
|
44
44
|
with open(expected_path, "rb+") as f:
|
|
45
45
|
obj = PdfWrapper(sample_template_with_dropdown).fill(
|
|
@@ -53,7 +53,7 @@ def test_dropdown_one_flatten(sample_template_with_dropdown, pdf_samples, reques
|
|
|
53
53
|
"radio_1": 1,
|
|
54
54
|
"dropdown_1": 0,
|
|
55
55
|
},
|
|
56
|
-
|
|
56
|
+
readonly=True,
|
|
57
57
|
)
|
|
58
58
|
|
|
59
59
|
request.config.results["expected_path"] = expected_path
|
|
@@ -87,11 +87,11 @@ def test_dropdown_alignment(dropdown_alignment, pdf_samples, request):
|
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
@pytest.mark.requires_zlib_over_zlib_ng
|
|
90
|
-
def
|
|
90
|
+
def test_dropdown_alignment_readonly_then_editable(
|
|
91
91
|
dropdown_alignment, pdf_samples, request
|
|
92
92
|
):
|
|
93
93
|
expected_path = os.path.join(
|
|
94
|
-
pdf_samples, "dropdown", "
|
|
94
|
+
pdf_samples, "dropdown", "test_dropdown_alignment_readonly_then_editable.pdf"
|
|
95
95
|
)
|
|
96
96
|
with open(expected_path, "rb+") as f:
|
|
97
97
|
obj = PdfWrapper(dropdown_alignment).fill(
|
|
@@ -100,7 +100,7 @@ def test_dropdown_alignment_flatten_then_unflatten(
|
|
|
100
100
|
"dropdown_center": 1,
|
|
101
101
|
"dropdown_right": 2,
|
|
102
102
|
},
|
|
103
|
-
|
|
103
|
+
readonly=True,
|
|
104
104
|
)
|
|
105
105
|
obj.widgets["dropdown_center"].readonly = False
|
|
106
106
|
|
|
@@ -138,11 +138,11 @@ def test_dropdown_alignment_sejda(dropdown_alignment_sejda, pdf_samples, request
|
|
|
138
138
|
assert obj.read() == expected
|
|
139
139
|
|
|
140
140
|
|
|
141
|
-
def
|
|
141
|
+
def test_dropdown_alignment_sejda_readonly(
|
|
142
142
|
dropdown_alignment_sejda, pdf_samples, request
|
|
143
143
|
):
|
|
144
144
|
expected_path = os.path.join(
|
|
145
|
-
pdf_samples, "dropdown", "
|
|
145
|
+
pdf_samples, "dropdown", "test_dropdown_alignment_sejda_readonly.pdf"
|
|
146
146
|
)
|
|
147
147
|
with open(
|
|
148
148
|
expected_path,
|
|
@@ -154,7 +154,7 @@ def test_dropdown_alignment_sejda_flatten(
|
|
|
154
154
|
"dropdown_center": 1,
|
|
155
155
|
"dropdown_right": 2,
|
|
156
156
|
},
|
|
157
|
-
|
|
157
|
+
readonly=True,
|
|
158
158
|
)
|
|
159
159
|
|
|
160
160
|
request.config.results["expected_path"] = expected_path
|
|
@@ -166,13 +166,13 @@ def test_dropdown_alignment_sejda_flatten(
|
|
|
166
166
|
assert obj.read() == expected
|
|
167
167
|
|
|
168
168
|
|
|
169
|
-
def
|
|
169
|
+
def test_dropdown_alignment_sejda_readonly_then_editable(
|
|
170
170
|
dropdown_alignment_sejda, pdf_samples, request
|
|
171
171
|
):
|
|
172
172
|
expected_path = os.path.join(
|
|
173
173
|
pdf_samples,
|
|
174
174
|
"dropdown",
|
|
175
|
-
"
|
|
175
|
+
"test_dropdown_alignment_sejda_readonly_then_editable.pdf",
|
|
176
176
|
)
|
|
177
177
|
with open(
|
|
178
178
|
expected_path,
|
|
@@ -184,7 +184,7 @@ def test_dropdown_alignment_sejda_flatten_then_unflatten(
|
|
|
184
184
|
"dropdown_center": 1,
|
|
185
185
|
"dropdown_right": 2,
|
|
186
186
|
},
|
|
187
|
-
|
|
187
|
+
readonly=True,
|
|
188
188
|
)
|
|
189
189
|
obj.widgets["dropdown_center"].readonly = False
|
|
190
190
|
|
|
@@ -73,7 +73,7 @@ def test_addition_operator_3_times_values(template_stream, data_dict):
|
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
def test_field_readonly(pdf_samples):
|
|
76
|
-
obj = PdfWrapper(os.path.join(pdf_samples, "
|
|
76
|
+
obj = PdfWrapper(os.path.join(pdf_samples, "test_fill_readonly_then_editable.pdf"))
|
|
77
77
|
|
|
78
78
|
for k, v in obj.widgets.items():
|
|
79
79
|
if k in ["test_2", "check_3"]:
|
|
@@ -83,7 +83,7 @@ def test_field_readonly(pdf_samples):
|
|
|
83
83
|
|
|
84
84
|
|
|
85
85
|
def test_field_readonly_sejda(pdf_samples):
|
|
86
|
-
obj = PdfWrapper(os.path.join(pdf_samples, "
|
|
86
|
+
obj = PdfWrapper(os.path.join(pdf_samples, "test_fill_sejda_readonly.pdf"))
|
|
87
87
|
|
|
88
88
|
for v in obj.widgets.values():
|
|
89
89
|
assert v.readonly
|
|
@@ -63,11 +63,12 @@ def test_fill_comb_text_field_all_chars(
|
|
|
63
63
|
assert obj.read() == expected
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
def
|
|
66
|
+
def test_fill_comb_text_field_all_chars_readonly(
|
|
67
67
|
sample_template_with_comb_text_field, max_length_expected_directory, request
|
|
68
68
|
):
|
|
69
69
|
expected_path = os.path.join(
|
|
70
|
-
max_length_expected_directory,
|
|
70
|
+
max_length_expected_directory,
|
|
71
|
+
"test_fill_comb_text_field_all_chars_readonly.pdf",
|
|
71
72
|
)
|
|
72
73
|
with open(
|
|
73
74
|
expected_path,
|
|
@@ -81,7 +82,7 @@ def test_fill_comb_text_field_all_chars_flatten(
|
|
|
81
82
|
"Awesomeness": True,
|
|
82
83
|
"Gender": 0,
|
|
83
84
|
},
|
|
84
|
-
|
|
85
|
+
readonly=True,
|
|
85
86
|
)
|
|
86
87
|
|
|
87
88
|
request.config.results["expected_path"] = expected_path
|
|
@@ -102,6 +102,14 @@ def test_deprecation_warning_direct_call_with_replace():
|
|
|
102
102
|
assert obj.my_method(use_legacy=True) == "result"
|
|
103
103
|
|
|
104
104
|
|
|
105
|
+
def test_flatten_deprecating(template_stream):
|
|
106
|
+
with pytest.warns(
|
|
107
|
+
DeprecationWarning,
|
|
108
|
+
match="PdfWrapper.fill.flatten will be deprecated soon. Use PdfWrapper.fill.readonly instead.",
|
|
109
|
+
):
|
|
110
|
+
assert PdfWrapper(template_stream).fill({"test": "test"}, flatten=True)
|
|
111
|
+
|
|
112
|
+
|
|
105
113
|
def test_base_schema_definition():
|
|
106
114
|
assert Widget("foo").schema_definition == {}
|
|
107
115
|
|
|
@@ -121,10 +129,10 @@ def test_write_io(template_stream):
|
|
|
121
129
|
assert PdfWrapper(buff.read()).widgets.keys() == obj.widgets.keys()
|
|
122
130
|
|
|
123
131
|
|
|
124
|
-
def
|
|
125
|
-
expected_path = os.path.join(pdf_samples, "
|
|
132
|
+
def test_fill_readonly_then_editable(template_stream, pdf_samples, data_dict, request):
|
|
133
|
+
expected_path = os.path.join(pdf_samples, "test_fill_readonly_then_editable.pdf")
|
|
126
134
|
with open(expected_path, "rb+") as f:
|
|
127
|
-
obj = PdfWrapper(template_stream).fill(data_dict,
|
|
135
|
+
obj = PdfWrapper(template_stream).fill(data_dict, readonly=True)
|
|
128
136
|
obj.widgets["test_2"].readonly = False
|
|
129
137
|
obj.widgets["check_3"].readonly = False
|
|
130
138
|
|
|
@@ -178,11 +186,11 @@ def test_fill_with_customized_widgets(
|
|
|
178
186
|
|
|
179
187
|
|
|
180
188
|
@pytest.mark.requires_zlib_over_zlib_ng
|
|
181
|
-
def
|
|
189
|
+
def test_fill_with_customized_widgets_readonly(
|
|
182
190
|
template_stream, pdf_samples, sample_font_stream, data_dict, request
|
|
183
191
|
):
|
|
184
192
|
expected_path = os.path.join(
|
|
185
|
-
pdf_samples, "
|
|
193
|
+
pdf_samples, "test_fill_with_customized_widgets_readonly.pdf"
|
|
186
194
|
)
|
|
187
195
|
with open(
|
|
188
196
|
expected_path,
|
|
@@ -198,7 +206,7 @@ def test_fill_with_customized_widgets_flatten(
|
|
|
198
206
|
obj.widgets["test_2"].font_color = (0, 1, 0)
|
|
199
207
|
obj.fill(
|
|
200
208
|
data_dict,
|
|
201
|
-
|
|
209
|
+
readonly=True,
|
|
202
210
|
)
|
|
203
211
|
|
|
204
212
|
request.config.results["expected_path"] = expected_path
|
|
@@ -230,10 +238,10 @@ def test_fill_with_varied_int_values(template_stream, pdf_samples, request):
|
|
|
230
238
|
assert obj.read() == expected
|
|
231
239
|
|
|
232
240
|
|
|
233
|
-
def
|
|
241
|
+
def test_fill_radiobutton_readonly(
|
|
234
242
|
template_with_radiobutton_stream, pdf_samples, request
|
|
235
243
|
):
|
|
236
|
-
expected_path = os.path.join(pdf_samples, "
|
|
244
|
+
expected_path = os.path.join(pdf_samples, "test_fill_radiobutton_readonly.pdf")
|
|
237
245
|
with open(
|
|
238
246
|
expected_path,
|
|
239
247
|
"rb+",
|
|
@@ -244,7 +252,7 @@ def test_fill_radiobutton_flatten(
|
|
|
244
252
|
"radio_2": 1,
|
|
245
253
|
"radio_3": 2,
|
|
246
254
|
},
|
|
247
|
-
|
|
255
|
+
readonly=True,
|
|
248
256
|
)
|
|
249
257
|
|
|
250
258
|
request.config.results["expected_path"] = expected_path
|
|
@@ -256,11 +264,11 @@ def test_fill_radiobutton_flatten(
|
|
|
256
264
|
assert obj.read() == expected
|
|
257
265
|
|
|
258
266
|
|
|
259
|
-
def
|
|
267
|
+
def test_fill_radiobutton_readonly_then_editable(
|
|
260
268
|
template_with_radiobutton_stream, pdf_samples, request
|
|
261
269
|
):
|
|
262
270
|
expected_path = os.path.join(
|
|
263
|
-
pdf_samples, "
|
|
271
|
+
pdf_samples, "test_fill_radiobutton_readonly_then_editable.pdf"
|
|
264
272
|
)
|
|
265
273
|
with open(
|
|
266
274
|
expected_path,
|
|
@@ -272,7 +280,7 @@ def test_fill_radiobutton_flatten_then_unflatten(
|
|
|
272
280
|
"radio_2": 1,
|
|
273
281
|
"radio_3": 2,
|
|
274
282
|
},
|
|
275
|
-
|
|
283
|
+
readonly=True,
|
|
276
284
|
)
|
|
277
285
|
obj.widgets["radio_2"].readonly = False
|
|
278
286
|
|
|
@@ -302,15 +310,15 @@ def test_fill_sejda(sejda_template, pdf_samples, sejda_data, request):
|
|
|
302
310
|
assert obj.read() == expected
|
|
303
311
|
|
|
304
312
|
|
|
305
|
-
def
|
|
306
|
-
expected_path = os.path.join(pdf_samples, "
|
|
313
|
+
def test_fill_sejda_readonly(sejda_template, pdf_samples, sejda_data, request):
|
|
314
|
+
expected_path = os.path.join(pdf_samples, "test_fill_sejda_readonly.pdf")
|
|
307
315
|
with open(
|
|
308
316
|
expected_path,
|
|
309
317
|
"rb+",
|
|
310
318
|
) as f:
|
|
311
319
|
obj = PdfWrapper(sejda_template).fill(
|
|
312
320
|
sejda_data,
|
|
313
|
-
|
|
321
|
+
readonly=True,
|
|
314
322
|
)
|
|
315
323
|
|
|
316
324
|
request.config.results["expected_path"] = expected_path
|
|
@@ -322,11 +330,11 @@ def test_fill_sejda_flatten(sejda_template, pdf_samples, sejda_data, request):
|
|
|
322
330
|
assert obj.read() == expected
|
|
323
331
|
|
|
324
332
|
|
|
325
|
-
def
|
|
333
|
+
def test_fill_sejda_readonly_then_editable(
|
|
326
334
|
sejda_template, pdf_samples, sejda_data, request
|
|
327
335
|
):
|
|
328
336
|
expected_path = os.path.join(
|
|
329
|
-
pdf_samples, "
|
|
337
|
+
pdf_samples, "test_fill_sejda_readonly_then_editable.pdf"
|
|
330
338
|
)
|
|
331
339
|
with open(
|
|
332
340
|
expected_path,
|
|
@@ -334,7 +342,7 @@ def test_fill_sejda_flatten_then_unflatten(
|
|
|
334
342
|
) as f:
|
|
335
343
|
obj = PdfWrapper(sejda_template).fill(
|
|
336
344
|
sejda_data,
|
|
337
|
-
|
|
345
|
+
readonly=True,
|
|
338
346
|
)
|
|
339
347
|
obj.widgets["buyer_name"].readonly = False
|
|
340
348
|
obj.widgets["at_future_date"].readonly = False
|
|
@@ -25,16 +25,16 @@ def test_fill_sejda_complex(
|
|
|
25
25
|
assert obj.read() == expected
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def
|
|
28
|
+
def test_fill_sejda_complex_readonly(
|
|
29
29
|
sejda_template_complex, sejda_complex_data, pdf_samples, request
|
|
30
30
|
):
|
|
31
31
|
expected_path = os.path.join(
|
|
32
|
-
pdf_samples, "paragraph", "
|
|
32
|
+
pdf_samples, "paragraph", "test_fill_sejda_complex_readonly.pdf"
|
|
33
33
|
)
|
|
34
34
|
with open(expected_path, "rb+") as f:
|
|
35
35
|
obj = PdfWrapper(sejda_template_complex).fill(
|
|
36
36
|
sejda_complex_data,
|
|
37
|
-
|
|
37
|
+
readonly=True,
|
|
38
38
|
)
|
|
39
39
|
|
|
40
40
|
request.config.results["expected_path"] = expected_path
|
|
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
|
|
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
|