PyPDFForm 5.2.0__tar.gz → 5.2.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.
Files changed (86) hide show
  1. {pypdfform-5.2.0 → pypdfform-5.2.1}/PKG-INFO +2 -2
  2. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/__init__.py +1 -1
  3. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/filler.py +3 -1
  4. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/image.py +6 -9
  5. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/template.py +25 -17
  6. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/watermark.py +16 -7
  7. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/widgets/base.py +25 -7
  8. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/widgets/signature.py +5 -2
  9. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/wrapper.py +25 -5
  10. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm.egg-info/PKG-INFO +2 -2
  11. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm.egg-info/requires.txt +1 -1
  12. {pypdfform-5.2.0 → pypdfform-5.2.1}/pyproject.toml +1 -1
  13. {pypdfform-5.2.0 → pypdfform-5.2.1}/LICENSE +0 -0
  14. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/cli/__init__.py +0 -0
  15. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/cli/common.py +0 -0
  16. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/cli/create.py +0 -0
  17. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/cli/entry.py +0 -0
  18. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/cli/inspect.py +0 -0
  19. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/cli/remove.py +0 -0
  20. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/cli/root.py +0 -0
  21. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/cli/schemas/__init__.py +0 -0
  22. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/cli/schemas/create.py +0 -0
  23. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/cli/schemas/update.py +0 -0
  24. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/cli/update.py +0 -0
  25. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/__init__.py +0 -0
  26. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/adapter.py +0 -0
  27. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/annotations/__init__.py +0 -0
  28. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/annotations/base.py +0 -0
  29. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/annotations/link.py +0 -0
  30. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/annotations/stamp.py +0 -0
  31. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/annotations/text.py +0 -0
  32. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/annotations/text_markup.py +0 -0
  33. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/assets/__init__.py +0 -0
  34. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/assets/bedrock.py +0 -0
  35. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/assets/blank.py +0 -0
  36. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/constants.py +0 -0
  37. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/coordinate.py +0 -0
  38. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/deprecation.py +0 -0
  39. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/egress.py +0 -0
  40. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/font.py +0 -0
  41. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/hooks.py +0 -0
  42. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/middleware/__init__.py +0 -0
  43. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/middleware/base.py +0 -0
  44. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/middleware/checkbox.py +0 -0
  45. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/middleware/dropdown.py +0 -0
  46. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/middleware/image.py +0 -0
  47. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/middleware/radio.py +0 -0
  48. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/middleware/signature.py +0 -0
  49. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/middleware/text.py +0 -0
  50. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/patterns.py +0 -0
  51. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/raw/__init__.py +0 -0
  52. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/raw/circle.py +0 -0
  53. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/raw/ellipse.py +0 -0
  54. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/raw/image.py +0 -0
  55. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/raw/line.py +0 -0
  56. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/raw/rect.py +0 -0
  57. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/raw/text.py +0 -0
  58. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/types.py +0 -0
  59. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/utils.py +0 -0
  60. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/widgets/__init__.py +0 -0
  61. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/widgets/checkbox.py +0 -0
  62. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/widgets/dropdown.py +0 -0
  63. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/widgets/image.py +0 -0
  64. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/widgets/radio.py +0 -0
  65. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm/lib/widgets/text.py +0 -0
  66. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm.egg-info/SOURCES.txt +0 -0
  67. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm.egg-info/dependency_links.txt +0 -0
  68. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm.egg-info/entry_points.txt +0 -0
  69. {pypdfform-5.2.0 → pypdfform-5.2.1}/PyPDFForm.egg-info/top_level.txt +0 -0
  70. {pypdfform-5.2.0 → pypdfform-5.2.1}/README.md +0 -0
  71. {pypdfform-5.2.0 → pypdfform-5.2.1}/setup.cfg +0 -0
  72. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_bulk_create_fields.py +0 -0
  73. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_create_widget.py +0 -0
  74. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_draw_elements.py +0 -0
  75. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_dropdown.py +0 -0
  76. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_extract_middleware_attributes.py +0 -0
  77. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_fill_max_length_text_field.py +0 -0
  78. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_font_widths.py +0 -0
  79. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_functional.py +0 -0
  80. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_generate_appearance_streams.py +0 -0
  81. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_js.py +0 -0
  82. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_need_appearances.py +0 -0
  83. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_paragraph.py +0 -0
  84. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_signature.py +0 -0
  85. {pypdfform-5.2.0 → pypdfform-5.2.1}/tests/test_use_full_widget_name.py +0 -0
  86. {pypdfform-5.2.0 → pypdfform-5.2.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: 5.2.0
3
+ Version: 5.2.1
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<49.0.0,>=48.0.0
27
+ Requires-Dist: cryptography<50.0.0,>=48.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
@@ -18,7 +18,7 @@ from Python code or from the command line.
18
18
 
19
19
  import logging
20
20
 
21
- __version__ = "5.2.0"
21
+ __version__ = "5.2.1"
22
22
 
23
23
  from .lib.annotations import Annotations
24
24
  from .lib.assets.blank import BlankPage
@@ -57,7 +57,9 @@ def signature_image_handler(
57
57
  any_image_to_draw = False
58
58
  if stream is not None:
59
59
  any_image_to_draw = True
60
- image_width, image_height = get_image_dimensions(stream)
60
+ image_width, image_height = (
61
+ get_image_dimensions(stream) if middleware.preserve_aspect_ratio else (0, 0)
62
+ )
61
63
  x, y, width, height = get_draw_image_resolutions(
62
64
  widget, middleware.preserve_aspect_ratio, image_width, image_height
63
65
  )
@@ -7,6 +7,7 @@ calculating the resolutions for drawing an image on a PDF page, taking into
7
7
  account whether to preserve the aspect ratio.
8
8
  """
9
9
 
10
+ from functools import lru_cache
10
11
  from io import BytesIO
11
12
  from typing import Tuple
12
13
 
@@ -50,12 +51,13 @@ def rotate_image(image_stream: bytes, rotation: float | int) -> bytes:
50
51
  return result
51
52
 
52
53
 
54
+ @lru_cache
53
55
  def get_image_dimensions(image_stream: bytes) -> Tuple[float, float]:
54
56
  """
55
57
  Retrieves the width and height of an image from its byte stream.
56
58
 
57
- This function uses the PIL library to open the image from the provided byte stream
58
- and returns its dimensions (width and height) as a tuple of floats.
59
+ This cached function uses the PIL library to open the image from the provided
60
+ byte stream and returns its dimensions (width and height) as a tuple of floats.
59
61
 
60
62
  Args:
61
63
  image_stream (bytes): The image data as bytes.
@@ -63,13 +65,8 @@ def get_image_dimensions(image_stream: bytes) -> Tuple[float, float]:
63
65
  Returns:
64
66
  Tuple[float, float]: The width and height of the image in pixels.
65
67
  """
66
- buff = BytesIO()
67
- buff.write(image_stream)
68
- buff.seek(0)
69
-
70
- image = Image.open(buff)
71
-
72
- return image.size
68
+ with Image.open(BytesIO(image_stream)) as image:
69
+ return image.size
73
70
 
74
71
 
75
72
  def get_draw_image_resolutions(
@@ -449,8 +449,7 @@ def update_widget_keys(
449
449
  out = PdfWriter()
450
450
  out.append(pdf)
451
451
 
452
- for i, old_key in enumerate(old_keys):
453
- _update_single_widget_key(out, widgets, old_key, new_keys[i], indices[i])
452
+ _apply_widget_key_updates(out, widgets, old_keys, new_keys, indices)
454
453
 
455
454
  with BytesIO() as f:
456
455
  out.write(f)
@@ -458,35 +457,44 @@ def update_widget_keys(
458
457
  return f.read()
459
458
 
460
459
 
461
- def _update_single_widget_key(
460
+ def _apply_widget_key_updates(
462
461
  writer: PdfWriter,
463
462
  widgets: Dict[str, WIDGET_TYPES],
464
- old_key: str,
465
- new_key: str,
466
- index: int,
463
+ old_keys: List[str],
464
+ new_keys: List[str],
465
+ indices: List[int],
467
466
  ) -> None:
468
467
  """
469
- Updates a single widget key in a PDF template.
468
+ Applies queued widget key updates to matching annotations.
469
+
470
+ The update queue is converted into a lookup keyed by old widget name, then
471
+ each annotation is checked against that lookup as pages are traversed.
472
+ Non-radio widgets honor the requested occurrence index, while radio widgets
473
+ update every annotation in the radio group.
470
474
 
471
475
  Args:
472
476
  writer (PdfWriter): The PDF writer object.
473
477
  widgets (Dict[str, WIDGET_TYPES]): A dictionary of widgets in the template.
474
- old_key (str): The old widget key to be replaced.
475
- new_key (str): The new widget key to replace the old key.
476
- index (int): The index of the widget to update if multiple widgets have the same name.
478
+ old_keys (List[str]): The old widget keys to replace.
479
+ new_keys (List[str]): The new widget keys to apply.
480
+ indices (List[int]): Widget occurrence indices for duplicate field names.
477
481
  """
478
- tracker = -1
482
+ updates = {old_key: (new_keys[i], indices[i]) for i, old_key in enumerate(old_keys)}
483
+ trackers = {}
484
+
479
485
  for page in writer.pages:
480
486
  for annot in page.get(Annots, []):
481
487
  annot = cast(DictionaryObject, annot.get_object())
482
488
  key = get_widget_key(annot.get_object(), False)
483
489
 
484
- widget = widgets.get(key)
485
- if widget is None or old_key != key:
490
+ if key not in updates:
486
491
  continue
487
492
 
488
- tracker += 1
489
- if not isinstance(widget, Radio) and tracker != index:
490
- continue
493
+ widget = widgets.get(key)
494
+ if widget is not None:
495
+ trackers[key] = trackers.get(key, -1) + 1
496
+ new_key, index = updates[key]
497
+ if not isinstance(widget, Radio) and trackers[key] != index:
498
+ continue
491
499
 
492
- update_annotation_name(annot, new_key)
500
+ update_annotation_name(annot, new_key)
@@ -9,6 +9,7 @@ and to copy specific widgets from the watermarks to the original PDF.
9
9
  """
10
10
 
11
11
  from collections import defaultdict
12
+ from functools import lru_cache
12
13
  from io import BytesIO
13
14
  from typing import Any, Dict, List, Optional
14
15
 
@@ -21,6 +22,20 @@ from .constants import Annots
21
22
  from .patterns import get_widget_key
22
23
 
23
24
 
25
+ @lru_cache(maxsize=128)
26
+ def _get_image_reader(image_stream: bytes) -> ImageReader:
27
+ """
28
+ Creates a cached ReportLab image reader for an image byte stream.
29
+
30
+ Args:
31
+ image_stream (bytes): The image data as a byte stream.
32
+
33
+ Returns:
34
+ ImageReader: The cached ReportLab image reader.
35
+ """
36
+ return ImageReader(BytesIO(image_stream))
37
+
38
+
24
39
  def draw_text(canvas: Canvas, **kwargs) -> None:
25
40
  """
26
41
  Draws a text string on the given canvas using the specified font, size, and color.
@@ -206,12 +221,8 @@ def draw_image(canvas: Canvas, **kwargs) -> None:
206
221
  width = kwargs["width"]
207
222
  height = kwargs["height"]
208
223
 
209
- image_buff = BytesIO()
210
- image_buff.write(image_stream)
211
- image_buff.seek(0)
212
-
213
224
  canvas.drawImage(
214
- ImageReader(image_buff),
225
+ _get_image_reader(image_stream),
215
226
  coordinate_x,
216
227
  coordinate_y,
217
228
  width=width,
@@ -219,8 +230,6 @@ def draw_image(canvas: Canvas, **kwargs) -> None:
219
230
  mask="auto",
220
231
  )
221
232
 
222
- image_buff.close()
223
-
224
233
 
225
234
  def create_watermarks_and_draw(
226
235
  pdf: bytes, to_draw: List[dict], font_mapping: Optional[Dict[str, str]] = None
@@ -15,6 +15,7 @@ Classes:
15
15
  from __future__ import annotations
16
16
 
17
17
  from dataclasses import dataclass
18
+ from functools import lru_cache
18
19
  from inspect import signature
19
20
  from io import BytesIO
20
21
  from typing import List, Optional
@@ -102,6 +103,28 @@ class Widget:
102
103
  if each in kwargs:
103
104
  self.hook_params.append((each, kwargs.get(each)))
104
105
 
106
+ @staticmethod
107
+ @lru_cache
108
+ def _get_default_field_flags(acro_form_class: type, acro_form_func: str) -> tuple:
109
+ """
110
+ Retrieves the default field flags for a ReportLab AcroForm method.
111
+
112
+ Args:
113
+ acro_form_class (type): The ReportLab AcroForm class.
114
+ acro_form_func (str): The AcroForm method name.
115
+
116
+ Returns:
117
+ tuple: The default field flags split into individual flag names.
118
+ """
119
+ default_flags = signature(
120
+ getattr(acro_form_class, acro_form_func)
121
+ ).parameters.get(fieldFlags)
122
+ return (
123
+ tuple(default_flags.default.split(" "))
124
+ if default_flags and default_flags.default
125
+ else ()
126
+ )
127
+
105
128
  def _required_handler(self, canvas: Canvas) -> None:
106
129
  """
107
130
  Handles the 'Required' flag for the widget's AcroForm field.
@@ -115,13 +138,8 @@ class Widget:
115
138
  Args:
116
139
  canvas (Canvas): The ReportLab canvas object used for PDF operations.
117
140
  """
118
- default_flags = signature(
119
- getattr(canvas.acroForm, self.ACRO_FORM_FUNC)
120
- ).parameters.get(fieldFlags)
121
- default_flags = (
122
- default_flags.default.split(" ")
123
- if default_flags and default_flags.default
124
- else []
141
+ default_flags = list(
142
+ self._get_default_field_flags(type(canvas.acroForm), self.ACRO_FORM_FUNC)
125
143
  )
126
144
 
127
145
  if self.acro_form_params.get(required):
@@ -120,6 +120,11 @@ class SignatureWidget:
120
120
  annot_type_to_annot[key] = annot.get_object()
121
121
 
122
122
  for i, p in enumerate(input_pdf.pages):
123
+ page_widgets = page_to_widgets.get(i + 1, [])
124
+ if not page_widgets:
125
+ result.append(b"")
126
+ continue
127
+
123
128
  # pylint: disable=R0801
124
129
  watermark = BytesIO()
125
130
  canvas = Canvas(
@@ -135,8 +140,6 @@ class SignatureWidget:
135
140
 
136
141
  out = PdfWriter(watermark)
137
142
 
138
- page_widgets = page_to_widgets.get(i + 1, [])
139
-
140
143
  widgets_to_copy = []
141
144
  for widget in page_widgets:
142
145
  widget_to_copy = annot_type_to_annot[
@@ -20,7 +20,7 @@ from __future__ import annotations
20
20
 
21
21
  from collections import defaultdict
22
22
  from dataclasses import asdict
23
- from functools import cached_property
23
+ from functools import lru_cache
24
24
  from os import PathLike
25
25
  from typing import (
26
26
  TYPE_CHECKING,
@@ -241,6 +241,27 @@ class PdfWrapper:
241
241
  if self._read():
242
242
  self._available_fonts.update(**get_all_available_fonts(self._read()))
243
243
 
244
+ @staticmethod
245
+ @lru_cache
246
+ def _get_page_streams_with_widgets(stream: bytes) -> tuple[bytes, ...]:
247
+ """
248
+ Extracts page streams while preserving the original page widgets.
249
+
250
+ Args:
251
+ stream (bytes): The PDF stream to split into pages.
252
+
253
+ Returns:
254
+ tuple[bytes, ...]: Single-page PDF streams with widgets preserved.
255
+ """
256
+
257
+ return tuple(
258
+ # Case: Single watermark PDF, extracting a specific page to the first output page.
259
+ copy_watermark_widgets(page_stream, stream, None, i)
260
+ for i, page_stream in enumerate(
261
+ get_page_streams(remove_all_widgets(stream))
262
+ )
263
+ )
264
+
244
265
  def _reregister_font(self) -> PdfWrapper:
245
266
  """
246
267
  Reregisters fonts after PDF content modifications.
@@ -334,7 +355,7 @@ class PdfWrapper:
334
355
 
335
356
  return list(self._available_fonts.keys())
336
357
 
337
- @cached_property
358
+ @property
338
359
  def pages(self) -> Sequence[PdfWrapper]:
339
360
  """
340
361
  Returns a list of `PdfWrapper` objects, each representing a single page in the PDF document.
@@ -347,11 +368,10 @@ class PdfWrapper:
347
368
 
348
369
  result = [
349
370
  self.__class__(
350
- # Case: Single watermark PDF, extracting a specific page to the first output page.
351
- copy_watermark_widgets(each, self._read(), None, i),
371
+ each,
352
372
  **{param: getattr(self, param) for param, _ in self.USER_PARAMS},
353
373
  )
354
- for i, each in enumerate(get_page_streams(remove_all_widgets(self._read())))
374
+ for each in self._get_page_streams_with_widgets(self._read())
355
375
  ]
356
376
 
357
377
  # because copy_watermark_widgets and remove_all_widgets
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPDFForm
3
- Version: 5.2.0
3
+ Version: 5.2.1
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<49.0.0,>=48.0.0
27
+ Requires-Dist: cryptography<50.0.0,>=48.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
@@ -1,4 +1,4 @@
1
- cryptography<49.0.0,>=48.0.0
1
+ cryptography<50.0.0,>=48.0.0
2
2
  fonttools<5.0.0,>=4.63.0
3
3
  pikepdf<11.0.0,>=10.7.2
4
4
  pillow<13.0.0,>=12.2.0
@@ -29,7 +29,7 @@ classifiers = [
29
29
  ]
30
30
  requires-python = ">=3.10"
31
31
  dependencies = [
32
- "cryptography>=48.0.0,<49.0.0",
32
+ "cryptography>=48.0.0,<50.0.0",
33
33
  "fonttools>=4.63.0,<5.0.0",
34
34
  "pikepdf>=10.7.2,<11.0.0",
35
35
  "pillow>=12.2.0,<13.0.0",
File without changes
File without changes
File without changes
File without changes