2025-05-24: V3 Announcements

This article provides important information about the upcoming v3.0.0 release.

TL; DR

PyPDFForm v3.0.0 is scheduled for release on June 24, 2025. This major release includes changes that will break compatibility with older code. To avoid issues, pin your version to <=2.5.0 as soon as possible.

Here's a list of the changes:

  • FormWrapper has been removed. Its features have been moved to PdfWrapper. The fill method of PdfWrapper will now work the same way it did in FormWrapper.
  • The way to enable adobe_mode when filling has changed. Instead of passing adobe_mode as an argument to the fill method, you now pass it when creating a PdfWrapper object.
  • Setting font properties for the entire document (e.g., PdfWrapper("sample_template.pdf", global_font_size=20)) is no longer supported. You must now set font properties for each individual widget.
  • register_font is now a method of the PdfWrapper object, not a general class method.
  • PdfWrapper.preview is removed.
  • You can no longer change the button_style of existing checkboxes or radio buttons. (Setting the button_style when you create them is still supported.)
  • Render widgets flag render_widgets is removed.

Why these changes?

When I started this project about five years ago, I didn't have as much experience as I do now. I ran into some technical problems during the initial proof of concept. One problem was that filled text fields in Adobe Acrobat sometimes only appeared when the field was selected.

Because of this behavior in Adobe Acrobat, and because I wanted to support as many PDF viewers as possible, I decided to use a "watermark" approach. Instead of directly changing the form field data, this approach gathers information about each field, such as its location, font, size, and color. Then, it removes all the original form fields, creates a watermark of the PDF, draws the filled content onto the watermark, and combines the watermark with the original PDF. Even though this removes the original fields and makes the filled content look "flattened", it ensures that the filled PDFs only contain basic PDF data and can be viewed in any PDF application. The project has grown since then, adding features like custom form field styles and even the ability to create form fields. As of version 2.5.0, the PdfWrapper still uses this watermark method as its core.

About a year ago, with the help of the community, I was finally able to solve the text field issue in Adobe Acrobat that had been present since the beginning of the project. This made it possible to directly modify the form field data when filling a PDF, which has several benefits: the form fields can remain editable after filling, there's no need for complicated calculations to determine coordinates and resolutions, and merging watermarks with the original PDF is no longer necessary, which greatly improves performance. However, the project had already developed significantly, and some features that relied on the watermark approach, such as changing font properties, couldn't be easily adapted to the new method, at least not initially. Therefore, instead of completely abandoning the watermark approach, I decided to create a new, simpler set of APIs that would support this new way of filling forms. This resulted in the FormWrapper.

The FormWrapper turned out to be a good addition, attracting even more users because it could truly "fill" a PDF form as if it were done by hand. Since then, PdfWrapper and FormWrapper have existed side-by-side. However, recent developments have made it necessary to introduce even more significant and fundamental changes to the project. First, I've noticed that many users, even when using features from PdfWrapper like creating or renaming widgets, prefer to use FormWrapper for the final step of filling the PDF. In these situations, I've had to advise them to first perform the necessary actions with PdfWrapper, extract the stream from the PdfWrapper object, and then use that as input for FormWrapper to complete the filling process. This workflow doesn't seem very intuitive. Second, I've developed some extremely complex calculations to determine how form field data should be drawn when using the watermark method. However, I've reached a point where I can't figure out how to support landscape PDFs due to orientation issues. This makes abandoning the watermark approach even more desirable. Finally, my recent research has revealed clearer ways to implement features that were previously only achievable through the watermark method by directly manipulating form field data.

Considering everything mentioned above, I believe it's time to introduce the next major version of PyPDFForm: v3.0.0.

What are the changes?

In short, the goal of v3.0.0 can be summed up to:

  • Merge FormWrapper into PdfWrapper.
  • Reimplement most, if not all, PdfWrapper features, especially the fill method, by directly manipulating form field data.
  • Preserve as much backward compatibility as possible.

Let's talk more about backward compatibility. With changes as significant as those in this release, it's impossible to maintain complete backward compatibility. For instance, even if you use the fill method in the same way as before, the filled PDF forms will now be editable because the watermark method is no longer used.

So, when I say I've tried to preserve as much backward compatibility as possible, I mean I've minimized the number of API changes. The appearance of your generated PDFs will be slightly different compared to the watermark approach, but you'll still be able to use most of PyPDFForm's APIs in the same way as before the release.

However, some unavoidable changes will break backward compatibility. This is why this release is a major version update, as defined by Semantic Versioning. I'll do my best to explain these changes and the reasons behind them in the list below:

  • As mentioned earlier, FormWrapper has been merged into PdfWrapper and completely removed. FormWrapper only provided basic PDF form filling features. After the merge, the fill method of PdfWrapper will function identically to how it did in FormWrapper.
  • The adobe_mode parameter has been moved from the fill method to the PdfWrapper object's constructor. This change is necessary because most PdfWrapper features now directly manipulate form field data and need to support Adobe Acrobat. Therefore, the setting applies to the entire object rather than just the filling method.
  • Previously, font properties could be set globally for each object using parameters like global_font, global_font_size, and global_font_color when creating the object. This is no longer possible. Font properties must now be set for each individual widget. Setting font properties globally made sense when they all needed to be applied to the same watermarks. Now that the project directly manipulates form fields, it's more logical to set them at the widget level.
  • register_font is now a method that belongs to each PdfWrapper object, rather than a general class method. This change should have been made earlier, and it's becoming more obvious with this release, as each registered font should only be used for a single PDF form.
  • The preview feature has been removed. It was initially an experimental feature and has proven to create messy, unreadable previews for PDFs with many fields. There are better ways to inspect a PDF form, such as using schema and sample_data.
  • Modifying the button_style of existing checkboxes or radio buttons by directly manipulating form field data is difficult, as it involves complex stream creation that I'm currently unable to implement. Therefore, this feature has been removed for now but may be added back in the future. Note that this change doesn't affect the ability to set the button_style when creating checkboxes or radio buttons.
  • render_widgets has been removed. This feature was originally added to maintain backward compatibility when the watermark approach first began supporting the rendering of widget borders and backgrounds. Since the watermark approach is no longer used, this feature is unnecessary.

What do you need to do?

First, I strongly recommend that you pin your PyPDFForm dependency version to <=2.5.0 as soon as possible, unless you're certain that these changes won't cause any problems for you.

After pinning your version, you have a couple of options:

  • If any of the backward-incompatible changes affect your code, update your code accordingly, using the information provided above.
  • If you prefer the old watermark approach, you can keep your version pinned to <=2.5.0 indefinitely, as those older versions will remain available.

Otherwise, once the release is made, you should have no problem upgrading to v3.0.0 and any future patches after the release.

When will this happen?

This announcement was written and should be published on May 24, 2025. After publication, the community will have one month to review this information and make any necessary adjustments.

Therefore, unless there's significant opposition from the community, PyPDFForm v3.0.0 will be released on June 24, 2025.