PyPDFForm 3.3.0__tar.gz → 3.3.1__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.

Files changed (51) hide show
  1. {pypdfform-3.3.0 → pypdfform-3.3.1}/PKG-INFO +1 -1
  2. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/__init__.py +1 -1
  3. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/constants.py +4 -0
  4. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/hooks.py +16 -15
  5. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/base.py +36 -0
  6. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/checkbox.py +2 -1
  7. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/text.py +2 -1
  8. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm.egg-info/PKG-INFO +1 -1
  9. {pypdfform-3.3.0 → pypdfform-3.3.1}/pyproject.toml +1 -1
  10. {pypdfform-3.3.0 → pypdfform-3.3.1}/LICENSE +0 -0
  11. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/adapter.py +0 -0
  12. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/coordinate.py +0 -0
  13. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/filler.py +0 -0
  14. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/font.py +0 -0
  15. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/image.py +0 -0
  16. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/__init__.py +0 -0
  17. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/base.py +0 -0
  18. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/checkbox.py +0 -0
  19. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/dropdown.py +0 -0
  20. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/image.py +0 -0
  21. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/radio.py +0 -0
  22. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/signature.py +0 -0
  23. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/text.py +0 -0
  24. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/patterns.py +0 -0
  25. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/template.py +0 -0
  26. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/utils.py +0 -0
  27. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/watermark.py +0 -0
  28. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/__init__.py +0 -0
  29. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/bedrock.py +0 -0
  30. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/dropdown.py +0 -0
  31. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/image.py +0 -0
  32. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/radio.py +0 -0
  33. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/signature.py +0 -0
  34. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/wrapper.py +0 -0
  35. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm.egg-info/SOURCES.txt +0 -0
  36. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm.egg-info/dependency_links.txt +0 -0
  37. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm.egg-info/requires.txt +0 -0
  38. {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm.egg-info/top_level.txt +0 -0
  39. {pypdfform-3.3.0 → pypdfform-3.3.1}/README.md +0 -0
  40. {pypdfform-3.3.0 → pypdfform-3.3.1}/setup.cfg +0 -0
  41. {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_adobe_mode.py +0 -0
  42. {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_create_widget.py +0 -0
  43. {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_dropdown.py +0 -0
  44. {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_extract_values.py +0 -0
  45. {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_fill_max_length_text_field.py +0 -0
  46. {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_fill_method.py +0 -0
  47. {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_functional.py +0 -0
  48. {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_paragraph.py +0 -0
  49. {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_signature.py +0 -0
  50. {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_use_full_widget_name.py +0 -0
  51. {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_widget_attr_trigger.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPDFForm
3
- Version: 3.3.0
3
+ Version: 3.3.1
4
4
  Summary: The Python library for PDF forms.
5
5
  Author: Jinge Li
6
6
  License-Expression: MIT
@@ -20,7 +20,7 @@ The library supports various PDF form features, including:
20
20
  PyPDFForm aims to simplify PDF form manipulation, making it accessible to developers of all skill levels.
21
21
  """
22
22
 
23
- __version__ = "3.3.0"
23
+ __version__ = "3.3.1"
24
24
 
25
25
  from .middleware.text import Text # exposing for setting global font attrs
26
26
  from .wrapper import PdfWrapper
@@ -99,6 +99,10 @@ REQUIRED = 1 << 1
99
99
  MULTILINE = 1 << 12
100
100
  COMB = 1 << 24
101
101
 
102
+ # reportlab acroform func
103
+ fieldFlags = "fieldFlags"
104
+ required = "required"
105
+
102
106
  FONT_SIZE_IDENTIFIER = "Tf"
103
107
  FONT_COLOR_IDENTIFIER = " rg"
104
108
  DEFAULT_FONT = "Helvetica"
@@ -359,19 +359,20 @@ def update_field_required(annot: DictionaryObject, val: bool) -> None:
359
359
  annot (DictionaryObject): The annotation dictionary for the form field.
360
360
  val (bool): True to set the field as required, False to make it optional.
361
361
  """
362
- if Parent in annot and Ff not in annot:
363
- annot[NameObject(Parent)][NameObject(Ff)] = NumberObject(
364
- (
365
- int(annot.get(NameObject(Ff), 0)) | REQUIRED
366
- if val
367
- else int(annot.get(NameObject(Ff), 0)) & ~REQUIRED
368
- )
369
- )
370
- else:
371
- annot[NameObject(Ff)] = NumberObject(
372
- (
373
- int(annot.get(NameObject(Ff), 0)) | REQUIRED
374
- if val
375
- else int(annot.get(NameObject(Ff), 0)) & ~REQUIRED
376
- )
362
+ # TODO: add a test case when supporting edit required
363
+ # if Parent in annot and Ff not in annot:
364
+ # annot[NameObject(Parent)][NameObject(Ff)] = NumberObject(
365
+ # (
366
+ # int(annot.get(NameObject(Ff), 0)) | REQUIRED
367
+ # if val
368
+ # else int(annot.get(NameObject(Ff), 0)) & ~REQUIRED
369
+ # )
370
+ # )
371
+ # else:
372
+ annot[NameObject(Ff)] = NumberObject(
373
+ (
374
+ int(annot.get(NameObject(Ff), 0)) | REQUIRED
375
+ if val
376
+ else int(annot.get(NameObject(Ff), 0)) & ~REQUIRED
377
377
  )
378
+ )
@@ -10,6 +10,7 @@ for rendering the widget on a PDF page.
10
10
  # TODO: In `watermarks`, `PdfReader(stream_to_io(stream))` is called, which re-parses the PDF for each widget. If multiple widgets are being processed, consider passing the `PdfReader` object directly to avoid redundant parsing.
11
11
  # TODO: In `watermarks`, the list comprehension `[watermark.read() if i == self.page_number - 1 else b"" for i in range(page_count)]` creates a new `BytesIO` object and reads from it for each widget. If many widgets are created, this could be optimized by creating the `BytesIO` object once and passing it around, or by directly returning the watermark bytes and its page number.
12
12
 
13
+ from inspect import signature
13
14
  from io import BytesIO
14
15
  from typing import List, Union
15
16
 
@@ -17,6 +18,7 @@ from pypdf import PdfReader
17
18
  from reportlab.lib.colors import Color
18
19
  from reportlab.pdfgen.canvas import Canvas
19
20
 
21
+ from ..constants import fieldFlags, required
20
22
  from ..utils import stream_to_io
21
23
 
22
24
 
@@ -95,6 +97,39 @@ class Widget:
95
97
  if each in kwargs:
96
98
  self.hook_params.append((each, kwargs.get(each)))
97
99
 
100
+ def _required_handler(self, canvas: Canvas) -> None:
101
+ """
102
+ Handles the 'Required' flag for the widget's AcroForm field.
103
+
104
+ This method inspects the default flags of the AcroForm function associated
105
+ with the widget and modifies them based on the widget's 'required' parameter.
106
+ If the widget is marked as required, the 'required' flag is added to the
107
+ AcroForm field flags; otherwise, it is removed. This ensures the PDF form
108
+ field's required status is correctly reflected.
109
+
110
+ Args:
111
+ canvas (Canvas): The ReportLab canvas object used for PDF operations.
112
+ """
113
+ default_flags = signature(
114
+ getattr(canvas.acroForm, self.ACRO_FORM_FUNC)
115
+ ).parameters.get(fieldFlags)
116
+ default_flags = (
117
+ default_flags.default.split(" ")
118
+ if default_flags and default_flags.default
119
+ else []
120
+ )
121
+
122
+ if self.acro_form_params.get(required):
123
+ default_flags.append(required)
124
+ else:
125
+ if required in default_flags:
126
+ default_flags.remove(required)
127
+
128
+ default_flags = " ".join(list(set(default_flags)))
129
+ self.acro_form_params[fieldFlags] = default_flags
130
+ if required in self.acro_form_params:
131
+ del self.acro_form_params[required]
132
+
98
133
  def canvas_operations(self, canvas: Canvas) -> None:
99
134
  """
100
135
  Performs canvas operations for the widget.
@@ -141,6 +176,7 @@ class Widget:
141
176
  ),
142
177
  )
143
178
 
179
+ self._required_handler(canvas)
144
180
  self.canvas_operations(canvas)
145
181
 
146
182
  canvas.showPage()
@@ -25,6 +25,7 @@ class CheckBoxWidget(Widget):
25
25
  """
26
26
 
27
27
  USER_PARAMS = [
28
+ ("required", "required"),
28
29
  ("tooltip", "tooltip"),
29
30
  ("button_style", "buttonStyle"),
30
31
  ("tick_color", "textColor"),
@@ -33,5 +34,5 @@ class CheckBoxWidget(Widget):
33
34
  ("border_width", "borderWidth"),
34
35
  ]
35
36
  COLOR_PARAMS = ["tick_color", "bg_color", "border_color"]
36
- ALLOWED_HOOK_PARAMS = ["required", "size"]
37
+ ALLOWED_HOOK_PARAMS = ["size"]
37
38
  ACRO_FORM_FUNC = "checkbox"
@@ -27,6 +27,7 @@ class TextWidget(Widget):
27
27
  """
28
28
 
29
29
  USER_PARAMS = [
30
+ ("required", "required"),
30
31
  ("tooltip", "tooltip"),
31
32
  ("width", "width"),
32
33
  ("height", "height"),
@@ -38,6 +39,6 @@ class TextWidget(Widget):
38
39
  ("max_length", "maxlen"),
39
40
  ]
40
41
  COLOR_PARAMS = ["font_color", "bg_color", "border_color"]
41
- ALLOWED_HOOK_PARAMS = ["required", "alignment", "multiline", "comb", "font"]
42
+ ALLOWED_HOOK_PARAMS = ["alignment", "multiline", "comb", "font"]
42
43
  NONE_DEFAULTS = ["max_length"]
43
44
  ACRO_FORM_FUNC = "textfield"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPDFForm
3
- Version: 3.3.0
3
+ Version: 3.3.1
4
4
  Summary: The Python library for PDF forms.
5
5
  Author: Jinge Li
6
6
  License-Expression: MIT
@@ -106,7 +106,7 @@ select = [
106
106
  "YTT",
107
107
  "W",
108
108
  ]
109
- ignore = ["B009", "E501", "N999", "Q000", "TC006"]
109
+ ignore = ["B009", "E501", "N999", "Q000", "TC006", "N816"]
110
110
 
111
111
  [tool.pyright]
112
112
  typeCheckingMode = "basic"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes