PyPDFForm 2.3.2__py3-none-any.whl → 2.4.0__py3-none-any.whl

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/__init__.py CHANGED
@@ -5,7 +5,7 @@ This package provides tools for filling PDF forms, drawing text and images,
5
5
  and manipulating PDF form elements programmatically.
6
6
  """
7
7
 
8
- __version__ = "2.3.2"
8
+ __version__ = "2.4.0"
9
9
 
10
10
  from .wrapper import FormWrapper, PdfWrapper
11
11
 
PyPDFForm/filler.py CHANGED
@@ -34,13 +34,12 @@ from .middleware.image import Image
34
34
  from .middleware.radio import Radio
35
35
  from .middleware.signature import Signature
36
36
  from .middleware.text import Text
37
- from .patterns import (WIDGET_KEY_PATTERNS, simple_flatten_generic,
38
- simple_flatten_radio, simple_update_checkbox_value,
37
+ from .patterns import (simple_flatten_generic, simple_flatten_radio,
38
+ simple_update_checkbox_value,
39
39
  simple_update_dropdown_value, simple_update_radio_value,
40
40
  simple_update_text_value)
41
- from .template import get_widget_full_key, get_widgets_by_page
42
- from .utils import (checkbox_radio_to_draw, extract_widget_property,
43
- stream_to_io)
41
+ from .template import get_widget_key, get_widgets_by_page
42
+ from .utils import checkbox_radio_to_draw, stream_to_io
44
43
  from .watermark import create_watermarks_and_draw, merge_watermarks_with_pdf
45
44
 
46
45
 
@@ -254,9 +253,7 @@ def fill(
254
253
  ellipse_borders_to_draw[page] = []
255
254
  line_borders_to_draw[page] = []
256
255
  for widget_dict in widget_dicts:
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)
256
+ key = get_widget_key(widget_dict, use_full_widget_name)
260
257
  text_needs_to_be_drawn = False
261
258
  to_draw = x = y = None
262
259
 
@@ -340,6 +337,7 @@ def enable_adobe_mode(reader: PdfReader, writer: PdfWriter, adobe_mode: bool) ->
340
337
  def simple_fill(
341
338
  template: bytes,
342
339
  widgets: Dict[str, WIDGET_TYPES],
340
+ use_full_widget_name: bool,
343
341
  flatten: bool = False,
344
342
  adobe_mode: bool = False,
345
343
  ) -> bytes:
@@ -353,6 +351,7 @@ def simple_fill(
353
351
  Args:
354
352
  template: Input PDF form as bytes
355
353
  widgets: Dictionary mapping field names to widget middleware
354
+ use_full_widget_name: If True, uses the full widget name as the key in the widgets dictionary
356
355
  flatten: If True, makes form fields read-only
357
356
  adobe_mode: If True, enables Adobe Acrobat compatibility
358
357
 
@@ -370,9 +369,7 @@ def simple_fill(
370
369
  for page in out.pages:
371
370
  for annot in page.get(Annots, []):
372
371
  annot = cast(DictionaryObject, annot.get_object())
373
- key = extract_widget_property(
374
- annot.get_object(), WIDGET_KEY_PATTERNS, None, str
375
- )
372
+ key = get_widget_key(annot.get_object(), use_full_widget_name)
376
373
 
377
374
  widget = widgets.get(key)
378
375
  if widget is None or widget.value is None:
@@ -40,7 +40,6 @@ class Widget:
40
40
 
41
41
  super().__init__()
42
42
  self._name = name
43
- self.full_name = None
44
43
  self._value = value
45
44
  self.desc = None
46
45
  self.border_color = None
PyPDFForm/template.py CHANGED
@@ -60,9 +60,7 @@ def set_character_x_paddings(
60
60
 
61
61
  for _widgets in get_widgets_by_page(pdf_stream).values():
62
62
  for widget in _widgets:
63
- key = extract_widget_property(widget, WIDGET_KEY_PATTERNS, None, str)
64
- if use_full_widget_name:
65
- key = get_widget_full_key(widget)
63
+ key = get_widget_key(widget, use_full_widget_name)
66
64
  _widget = widgets[key]
67
65
 
68
66
  if isinstance(_widget, Text) and _widget.comb is True:
@@ -91,11 +89,9 @@ def build_widgets(
91
89
 
92
90
  for widgets in get_widgets_by_page(pdf_stream).values():
93
91
  for widget in widgets:
94
- key = extract_widget_property(widget, WIDGET_KEY_PATTERNS, None, str)
92
+ key = get_widget_key(widget, use_full_widget_name)
95
93
  _widget = construct_widget(widget, key)
96
94
  if _widget is not None:
97
- if use_full_widget_name:
98
- _widget.full_name = get_widget_full_key(widget)
99
95
 
100
96
  _widget.render_widget = render_widgets
101
97
  _widget.desc = extract_widget_property(
@@ -141,8 +137,7 @@ def build_widgets(
141
137
  continue
142
138
 
143
139
  results[key] = _widget
144
- if _widget.full_name is not None and use_full_widget_name:
145
- results[_widget.full_name] = results[key]
140
+
146
141
  return results
147
142
 
148
143
 
@@ -201,9 +196,7 @@ def update_text_field_attributes(
201
196
 
202
197
  for _widgets in get_widgets_by_page(template_stream).values():
203
198
  for _widget in _widgets:
204
- key = extract_widget_property(_widget, WIDGET_KEY_PATTERNS, None, str)
205
- if use_full_widget_name:
206
- key = get_widget_full_key(_widget)
199
+ key = get_widget_key(_widget, use_full_widget_name)
207
200
 
208
201
  if isinstance(widgets[key], Text):
209
202
  should_adjust_font_size = False
@@ -267,24 +260,32 @@ def get_widgets_by_page(pdf: bytes) -> Dict[int, List[dict]]:
267
260
  return result
268
261
 
269
262
 
270
- def get_widget_full_key(widget: dict) -> str:
271
- """Constructs a widget's full hierarchical key including parent names.
263
+ def get_widget_key(widget: dict, use_full_widget_name: bool) -> str:
264
+ """Constructs a widget's key, optionally including parent names based on `use_full_widget_name`.
265
+
266
+ This function recursively builds the full key by appending parent names if `use_full_widget_name` is True.
267
+ If `use_full_widget_name` is False, it returns the widget's key directly.
272
268
 
273
269
  Args:
274
- widget: PDF widget dictionary
270
+ widget (dict): PDF widget dictionary.
271
+ use_full_widget_name (bool): Whether to include parent widget names in the key.
275
272
 
276
273
  Returns:
277
- str: Full key in format "parent.child" if parent exists, otherwise the widget's key
274
+ str: Full key in format "parent.child" if parent exists and `use_full_widget_name` is True, otherwise the widget's key.
278
275
  """
279
276
 
280
277
  key = extract_widget_property(widget, WIDGET_KEY_PATTERNS, None, str)
278
+ if not use_full_widget_name:
279
+ return key
281
280
 
282
281
  if (
283
282
  Parent in widget
284
283
  and T in widget[Parent].get_object()
285
284
  and widget[Parent].get_object()[T] != key
286
285
  ):
287
- key = f"{get_widget_full_key(widget[Parent].get_object())}.{key}"
286
+ key = (
287
+ f"{get_widget_key(widget[Parent].get_object(), use_full_widget_name)}.{key}"
288
+ )
288
289
 
289
290
  return key
290
291
 
@@ -592,9 +593,7 @@ def update_widget_keys(
592
593
  for page in out.pages:
593
594
  for annot in page.get(Annots, []):
594
595
  annot = cast(DictionaryObject, annot.get_object())
595
- key = extract_widget_property(
596
- annot.get_object(), WIDGET_KEY_PATTERNS, None, str
597
- )
596
+ key = get_widget_key(annot.get_object(), False)
598
597
 
599
598
  widget = widgets.get(key)
600
599
  if widget is None:
PyPDFForm/watermark.py CHANGED
@@ -18,8 +18,8 @@ from reportlab.lib.utils import ImageReader
18
18
  from reportlab.pdfgen.canvas import Canvas
19
19
 
20
20
  from .constants import Annots
21
- from .patterns import WIDGET_KEY_PATTERNS
22
- from .utils import extract_widget_property, stream_to_io
21
+ from .template import get_widget_key
22
+ from .utils import stream_to_io
23
23
 
24
24
 
25
25
  def draw_text(canvas: Canvas, **kwargs) -> None:
@@ -381,9 +381,7 @@ def copy_watermark_widgets(
381
381
  for j, page in enumerate(watermark_file.pages):
382
382
  widgets_to_copy_pdf[j] = []
383
383
  for annot in page.get(Annots, []):
384
- key = extract_widget_property(
385
- annot.get_object(), WIDGET_KEY_PATTERNS, None, str
386
- )
384
+ key = get_widget_key(annot.get_object(), False)
387
385
  if (keys is None or key in keys) and (
388
386
  page_num is None or page_num == j
389
387
  ):
PyPDFForm/widgets/base.py CHANGED
@@ -16,8 +16,9 @@ from reportlab.lib.colors import Color
16
16
  from reportlab.pdfgen.canvas import Canvas
17
17
 
18
18
  from ..constants import Annots
19
- from ..patterns import NON_ACRO_FORM_PARAM_TO_FUNC, WIDGET_KEY_PATTERNS
20
- from ..utils import extract_widget_property, stream_to_io
19
+ from ..patterns import NON_ACRO_FORM_PARAM_TO_FUNC
20
+ from ..template import get_widget_key
21
+ from ..utils import stream_to_io
21
22
 
22
23
 
23
24
  class Widget:
@@ -156,9 +157,7 @@ def handle_non_acro_form_params(pdf: bytes, key: str, params: list) -> bytes:
156
157
  for page in out.pages:
157
158
  for annot in page.get(Annots, []):
158
159
  annot = cast(DictionaryObject, annot.get_object())
159
- _key = extract_widget_property(
160
- annot.get_object(), WIDGET_KEY_PATTERNS, None, str
161
- )
160
+ _key = get_widget_key(annot.get_object(), False)
162
161
 
163
162
  if _key == key:
164
163
  for param in params:
@@ -14,8 +14,8 @@ from pypdf.generic import (ArrayObject, FloatObject, NameObject,
14
14
  TextStringObject)
15
15
 
16
16
  from ..constants import Annots, Rect, T
17
- from ..patterns import WIDGET_KEY_PATTERNS
18
- from ..utils import extract_widget_property, stream_to_io
17
+ from ..template import get_widget_key
18
+ from ..utils import stream_to_io
19
19
  from .bedrock import BEDROCK_PDF
20
20
 
21
21
 
@@ -107,9 +107,7 @@ class SignatureWidget:
107
107
 
108
108
  for page in out.pages:
109
109
  for annot in page.get(Annots, []):
110
- key = extract_widget_property(
111
- annot.get_object(), WIDGET_KEY_PATTERNS, None, str
112
- )
110
+ key = get_widget_key(annot.get_object(), False)
113
111
 
114
112
  if key != self.BEDROCK_WIDGET_TO_COPY:
115
113
  continue
PyPDFForm/wrapper.py CHANGED
@@ -62,16 +62,21 @@ class FormWrapper:
62
62
  def __init__(
63
63
  self,
64
64
  template: Union[bytes, str, BinaryIO] = b"",
65
+ **kwargs,
65
66
  ) -> None:
66
67
  """Initializes the base form wrapper with a PDF template.
67
68
 
68
69
  Args:
69
70
  template: PDF form as bytes, file path, or file object. Defaults to
70
71
  empty bytes if not provided.
72
+ **kwargs: Additional options:
73
+ use_full_widget_name: If True, uses complete widget names including
74
+ field hierarchy (default: False)
71
75
 
72
76
  Initializes:
73
77
  - Internal PDF stream from the template
74
78
  - Basic form filling capabilities
79
+ - Widget naming configuration from kwargs
75
80
 
76
81
  Note:
77
82
  This base class is designed to be extended by PdfWrapper which adds
@@ -80,6 +85,7 @@ class FormWrapper:
80
85
 
81
86
  super().__init__()
82
87
  self.stream = fp_or_f_obj_or_stream_to_stream(template)
88
+ self.use_full_widget_name = kwargs.get("use_full_widget_name", False)
83
89
 
84
90
  def read(self) -> bytes:
85
91
  """Returns the raw bytes of the PDF form data.
@@ -102,20 +108,34 @@ class FormWrapper:
102
108
  """Fills form fields in the PDF with provided values.
103
109
 
104
110
  Takes a dictionary of field names to values and updates the corresponding
105
- form fields in the PDF. Only fields that exist in the template PDF will
106
- be filled - unknown field names are silently ignored.
111
+ form fields in the PDF. Supports these value types:
112
+ - Strings for text fields
113
+ - Booleans for checkboxes (True=checked, False=unchecked)
114
+ - Integers for numeric fields and dropdown selections
115
+
116
+ Only fields that exist in the template PDF will be filled - unknown field
117
+ names are silently ignored.
107
118
 
108
119
  Args:
109
- data: Dictionary mapping field names to values (str, bool or int)
120
+ data: Dictionary mapping field names to values. Supported types:
121
+ str: For text fields
122
+ bool: For checkboxes (True=checked)
123
+ int: For numeric fields and dropdown selections
110
124
  **kwargs: Additional options:
111
- flatten: If True, makes form fields read-only after filling
112
- adobe_mode: If True, uses Adobe-compatible filling logic
125
+ flatten (bool): If True, makes form fields read-only after filling
126
+ (default: False)
127
+ adobe_mode (bool): If True, uses Adobe-compatible filling logic
128
+ (default: False)
113
129
 
114
130
  Returns:
115
131
  FormWrapper: Returns self to allow method chaining
116
132
  """
117
133
 
118
- widgets = build_widgets(self.stream, False, False) if self.stream else {}
134
+ widgets = (
135
+ build_widgets(self.stream, self.use_full_widget_name, False)
136
+ if self.stream
137
+ else {}
138
+ )
119
139
 
120
140
  for key, value in data.items():
121
141
  if key in widgets:
@@ -124,6 +144,7 @@ class FormWrapper:
124
144
  self.stream = simple_fill(
125
145
  self.read(),
126
146
  widgets,
147
+ use_full_widget_name=self.use_full_widget_name,
127
148
  flatten=kwargs.get("flatten", False),
128
149
  adobe_mode=kwargs.get("adobe_mode", False),
129
150
  )
@@ -249,13 +270,7 @@ class PdfWrapper(FormWrapper):
249
270
  dict: Field names mapped to their sample values
250
271
  """
251
272
 
252
- result = {}
253
- for key, value in self.widgets.items():
254
- if getattr(self, "use_full_widget_name") and key != value.full_name:
255
- continue
256
- result[key] = value.sample_value
257
-
258
- return result
273
+ return {key: value.sample_value for key, value in self.widgets.items()}
259
274
 
260
275
  @property
261
276
  def version(self) -> Union[str, None]:
@@ -712,13 +727,12 @@ class PdfWrapper(FormWrapper):
712
727
  dict: A JSON Schema dictionary following Draft 7 format
713
728
  """
714
729
 
715
- result = {}
716
- for key, value in self.widgets.items():
717
- if getattr(self, "use_full_widget_name") and key != value.full_name:
718
- continue
719
- result[key] = value.schema_definition
720
-
721
- return {"type": "object", "properties": result}
730
+ return {
731
+ "type": "object",
732
+ "properties": {
733
+ key: value.schema_definition for key, value in self.widgets.items()
734
+ },
735
+ }
722
736
 
723
737
  @classmethod
724
738
  def register_font(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPDFForm
3
- Version: 2.3.2
3
+ Version: 2.4.0
4
4
  Summary: The Python library for PDF forms.
5
5
  Author: Jinge Li
6
6
  License-Expression: MIT
@@ -10,7 +10,6 @@ Classifier: Development Status :: 5 - Production/Stable
10
10
  Classifier: Intended Audience :: Developers
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3 :: Only
13
- Classifier: Programming Language :: Python :: 3.8
14
13
  Classifier: Programming Language :: Python :: 3.9
15
14
  Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
@@ -18,7 +17,7 @@ Classifier: Programming Language :: Python :: 3.12
18
17
  Classifier: Programming Language :: Python :: 3.13
19
18
  Classifier: Operating System :: OS Independent
20
19
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
- Requires-Python: >=3.8
20
+ Requires-Python: >=3.9
22
21
  Description-Content-Type: text/markdown
23
22
  License-File: LICENSE
24
23
  Requires-Dist: cryptography
@@ -1,17 +1,17 @@
1
- PyPDFForm/__init__.py,sha256=-8q8goejLmKZqbaQz1MzZVHcxV6d5qFgHpq0OPXHirw,328
1
+ PyPDFForm/__init__.py,sha256=TrLXIaBX68LQ3KQc6d_tR2c7UnzA3uXZ90KmNZuoiYM,328
2
2
  PyPDFForm/adapter.py,sha256=_5fP5UR-NzjDDayJmBRO36DgbnbUzNbjZtHZtPvSM14,1909
3
3
  PyPDFForm/constants.py,sha256=3ed0j11cWd9Uo4s-XvZwwJojPSz8aqdmZgaEishWjqE,2342
4
4
  PyPDFForm/coordinate.py,sha256=gQI7z-GsdCO33Qny5kXLBs6Y2TW5KO_mJ2in64fvXcg,16412
5
- PyPDFForm/filler.py,sha256=HrvgRrAjai9TFOr-bQBH9dlwmEGQsNZgKpOEFfDsXtg,14215
5
+ PyPDFForm/filler.py,sha256=oCXDzz8paw8-MIQLiTTv5goYlfCfz_EcczCj8K4JB3g,14116
6
6
  PyPDFForm/font.py,sha256=eRbDyQFhXUkHzyZvCtru9Ypg_ukfbBAnSM5xNzPb5ss,7280
7
7
  PyPDFForm/image.py,sha256=aYk7BC-AHiqt73durGIQ3e6gE5Ggbdr8jmkCUaQdsk8,1627
8
8
  PyPDFForm/patterns.py,sha256=VH7cgAFHLKEUIfE1yIlifIJ9mc0Eb2Kqo-krk34HGOY,9316
9
- PyPDFForm/template.py,sha256=geZUB8a_otsHa5Q7dO0JH9md1WFodE7Dl_alBhqiU18,20128
9
+ PyPDFForm/template.py,sha256=N_Pj3SaSKs3sqIuIdtgHPXvxIHLnHeR2M9IwRCWWKoQ,20043
10
10
  PyPDFForm/utils.py,sha256=QxJSG96FHGch863UdBPT8DdTKN9gVzQzA2ezifTm7z4,8575
11
- PyPDFForm/watermark.py,sha256=Zmx4orMrQRMoOWGYo4bvVhxptMXFnCM4RshagTp8LFY,12459
12
- PyPDFForm/wrapper.py,sha256=UxgjdBWgoqALUkCmFUDVJKqIL3uud3ChG_gcieRdGkc,25933
11
+ PyPDFForm/watermark.py,sha256=yvtZKcdPAPprBVEWcFZEnZMJcTwVpQ6u72m0jqYHxx8,12357
12
+ PyPDFForm/wrapper.py,sha256=jiuO-GBqAlQgWfXgPZB4dWpF7_t4UpdMokn9XBDGdEI,26582
13
13
  PyPDFForm/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- PyPDFForm/middleware/base.py,sha256=d4z7M7pm80176cC4H85m3ZRWzAu_Fm1HkwQkmSSi-WE,2832
14
+ PyPDFForm/middleware/base.py,sha256=Ex--sUtQqpjFYWi3oAMqjuay_HYToHFMwRtdgWusckI,2802
15
15
  PyPDFForm/middleware/checkbox.py,sha256=gRGhFySPoIpKBseoiOTS3WggoBBik12dXbZ-LJKzIwM,2611
16
16
  PyPDFForm/middleware/dropdown.py,sha256=McuZl8Pc2IYPkEHRmM1OcEsh9njekySqjqVxRmQKmWU,1773
17
17
  PyPDFForm/middleware/image.py,sha256=HlPUsIktj-NryIkwwdZlilvrd6sZYifs9IuDgTHp7uQ,950
@@ -19,16 +19,16 @@ PyPDFForm/middleware/radio.py,sha256=M4yqHYzHj0jvOGbjYdqeYnNAlYhTF-h47qxqrjXDOoU
19
19
  PyPDFForm/middleware/signature.py,sha256=0gexCQwHCEOrjrgvUXeJJCGo2plfSEbXlykPJJCqpfA,2380
20
20
  PyPDFForm/middleware/text.py,sha256=eAxeVwboPPlnDT4aaOi7UpQ_xPmnlzkIbUOtRm1VMd0,2944
21
21
  PyPDFForm/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- PyPDFForm/widgets/base.py,sha256=cVJzGuZTWE7sWTKlEV4Keh8AGglpQ-i379hEiSHvU18,5402
22
+ PyPDFForm/widgets/base.py,sha256=nzRmZFRXjc4fKySMwVQs6YzPxnhnxcgFWnMUvOySWz4,5330
23
23
  PyPDFForm/widgets/bedrock.py,sha256=j6beU04kaQzpAIFZHI5VJLaDT5RVAAa6LzkU1luJpN8,137660
24
24
  PyPDFForm/widgets/checkbox.py,sha256=_1I5yh1211RgRUyWzd3NNYpI9JchqJNSJWaZAhl2uOo,1248
25
25
  PyPDFForm/widgets/dropdown.py,sha256=zszIT5MI6ggBRUEn7oGBKK0pKmDC9LQw3RnqaKG8ocQ,1764
26
26
  PyPDFForm/widgets/image.py,sha256=6y8Ysmk49USr_qWOXD6KGL6cch516cUIlrxoj0pJy9Q,797
27
27
  PyPDFForm/widgets/radio.py,sha256=ipadJyHbgftDUvjGk15kapzgHPN3HjdF_iB_7amXR6o,2737
28
- PyPDFForm/widgets/signature.py,sha256=8z1sOOgcvhQtLXZ5TeTd59oVtkNGTrgQtZRfuaOWR8w,5099
28
+ PyPDFForm/widgets/signature.py,sha256=FdXzja3RTuyU9iyA5Y1yPb4Gsfe4rYlM4gcwekIuwog,4997
29
29
  PyPDFForm/widgets/text.py,sha256=HP2cPEUAzK5QL3kDfMz7gQcC3svCpmYuyFItBjlrBpI,1233
30
- pypdfform-2.3.2.dist-info/licenses/LICENSE,sha256=43awmYkI6opyTpg19me731iO1WfXZwViqb67oWtCsFY,1065
31
- pypdfform-2.3.2.dist-info/METADATA,sha256=IiQplBGHDSThpZI9ZqOokbyVxbd9zq1Za_JDksfSNzI,4738
32
- pypdfform-2.3.2.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
33
- pypdfform-2.3.2.dist-info/top_level.txt,sha256=GQQKuWqPUjT9YZqwK95NlAQzxjwoQrsxQ8ureM8lWOY,10
34
- pypdfform-2.3.2.dist-info/RECORD,,
30
+ pypdfform-2.4.0.dist-info/licenses/LICENSE,sha256=43awmYkI6opyTpg19me731iO1WfXZwViqb67oWtCsFY,1065
31
+ pypdfform-2.4.0.dist-info/METADATA,sha256=6g0a3hKc0j1JYVkG7kEVK0iBdZc6bKMVyf2LSEt6VgA,4688
32
+ pypdfform-2.4.0.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
33
+ pypdfform-2.4.0.dist-info/top_level.txt,sha256=GQQKuWqPUjT9YZqwK95NlAQzxjwoQrsxQ8ureM8lWOY,10
34
+ pypdfform-2.4.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.4.0)
2
+ Generator: setuptools (80.7.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5