GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-143214: Add the wrapcol parameter in binascii.b2a_base64() and base64.b64encode() by serhiy-storchaka · Pull Request #143216 · python/cpython

Conversation

@serhiy-storchaka

@serhiy-storchaka serhiy-storchaka commented Dec 27, 2025 •
edited by github-actions Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member
  • Issue: Support multiline output in binascii.b2a_base64() and base64.b64encode() #143214

📚 Documentation preview 📚: https://cpython-previews--143216.org.readthedocs.build/

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@serhiy-storchaka
pythongh-143214: Add the wrapcol parameter in binascii.b2a_base64() a…
b7196ba
…nd base64.b64encode()
@serhiy-storchaka
serhiy-storchaka requested review from a team, AA-Turner, gpshead and picnixz as code owners December 27, 2025 11:55
@bedevere-app bedevere-app Bot mentioned this pull request Dec 27, 2025
Support multiline output in binascii.b2a_base64() and base64.b64encode() #143214
Closed
@bedevere-app bedevere-app Bot added the awaiting core review label Dec 27, 2025
picnixz
picnixz reviewed Dec 27, 2025
View reviewed changes
Comment thread Lib/ssl.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

picnixz
picnixz reviewed Dec 27, 2025
View reviewed changes
Comment thread Modules/binascii.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

@serhiy-storchaka serhiy-storchaka mentioned this pull request Dec 27, 2025
gh-101178: Add Ascii85, Base85, and Z85 support to binascii #102753
Merged
serhiy-storchaka added 2 commits December 27, 2025 14:36
@serhiy-storchaka
Fix errors.
50eb52d
@serhiy-storchaka
Add tests.
7c7f2dc
@serhiy-storchaka

serhiy-storchaka commented Dec 27, 2025

Copy link
Copy Markdown
Member Author

As a side effect -- the calculation of the size for the output buffer is now more accurate. Encoding more than 1GiB is now potentially supported on 32-bit systems (up to 1.5GiB if there is enough memory).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@serhiy-storchaka
Update the name of Hauke Dämpfling.
e429f03
@serhiy-storchaka serhiy-storchaka mentioned this pull request Dec 27, 2025
gh-143103: Added pad parameter to base64.z85encode #143106
Merged
picnixz
picnixz reviewed Dec 27, 2025
View reviewed changes

@picnixz picnixz left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About the warning in memoryobject.c, this was my fault but it's fixed on main and backports are pending.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Doc/whatsnew/3.15.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

cmaloney
cmaloney reviewed Dec 27, 2025
View reviewed changes

@cmaloney cmaloney left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 overall, didn't review the implementation in depth but went through the docs + overall API shape.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Doc/library/base64.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Lib/base64.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

gpshead
gpshead reviewed Dec 27, 2025
View reviewed changes
Comment thread Modules/binascii.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/binascii.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/binascii.c Outdated
goto toolong;
}
if (wrapcol && out_len) {
out_len += (out_len - 1) / wrapcol;

@gpshead gpshead Dec 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to support unreasonable wrapcol values? Values that are not multiples of 4 really do not make sense and feel unlikely to be used for any practical use of base64. As do low values such as 1-3. (small values are inefficient with our post-processing implementation anyways)

Do we know of any practical actual need for odd-multiple wrapping?

If we restrict the allowed wrappings to start with, we could open them up wider later if anyone has a need. I doubt there is demand for such strange for base64's use case wrapping sizes.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@picnixz picnixz Dec 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Odd-wrapping: 4n - 1 to really have a space on the right if there is a hard wrap at 4n. Only for rendering purposes I'd say and likely not useful. But 4n - 2 may also be an option. Or odd-wrapping could be useful.

More generally, email's policy allows to specify its own max line length and we currently have: "maxlen = policy.max_line_length or sys.maxsize". So it's important to support all inputs. However, we can specialize the case sys.maxsize to be equivalent to "no wrapping".

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

gpshead reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@serhiy-storchaka serhiy-storchaka Dec 27, 2025

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered this. We can round wrapcol down to the multiplier of 4 and set some minimal non-zero limit. plistlib does this, with the minimum 16. a85encode() sets the limit to 2 if adobe=True. quopri also needs some minimum (not less than 3, plus an escaped newline).

For Base 4 the reason can be that some third-party decoders can not support groups split between lines. See also #76672. But I am not sure whether we should force this or left on the user responsibility? What should we do for values from 1 to 3? Raise an exception? Round up to 4?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@picnixz picnixz Dec 27, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For 1, 2, 3, if it's not efficient, then so be it. It's the user responsibility at this point. For 1, it's the same as having no wrap and then put \n in between each values. So they could just do their own b"\n.".join(list(encode(s))) in this case which may be faster than encode(s, wrapcol=1). For 2-3, if it works but is not efficient, just leave it as is I guess (though the case n=2 may be interesting and we could try to optimize it, but I don't think people really want to group b64 encoded content by 2; the number of lines is likely to be too large to be visually interesting).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@gpshead gpshead Dec 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noone will intentionally pass such pointless tiny values anyways - it is our choice if we bother to disallow them or not. if we do not I'd suggest a ValueError rather than rounding up so that anyone with an actual need (prediction: nobody) can come file a bug explaining why.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@serhiy-storchaka serhiy-storchaka Dec 28, 2025

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a85encode(data, adobe=True, wrapcol=1) wraps the output in lines of length 2, so <~ and ~> will not split.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Modules/binascii.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/binascii.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/binascii.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

serhiy-storchaka added 5 commits December 27, 2025 21:35
@serhiy-storchaka
Address review comments (signature, docstrings).
46c6a25
@serhiy-storchaka
Add more comments nd tests.
5062ae5
@serhiy-storchaka
Mark CPython specific tests as such.
cd2e330
@serhiy-storchaka
Add more tests for a85encode().
cb4af0e
@serhiy-storchaka
Encode a whole number of bytes per line.
8a3e4e5
@gpshead gpshead mentioned this pull request Dec 29, 2025
Add bm_base64 covering common base64 module APIs python/pyperformance#447
Merged
bitdancer
bitdancer reviewed Dec 30, 2025
View reviewed changes
Comment thread Doc/library/base64.rst Outdated
Comment on lines +67 to +71
If *wrapcol* is non-zero, the output will be represented in lines of
no more than *wrapcol* characters each, separated by a newline
(``b'\n'``) character.
If *wrapcol* is zero (default), the output will be represented as
a single line.

@bitdancer bitdancer Dec 30, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If *wrapcol* is non-zero, the output will be represented in lines of
no more than *wrapcol* characters each, separated by a newline
(``b'\n'``) character.
If *wrapcol* is zero (default), the output will be represented as
a single line.
If *wrapcol* is non-zero, insert a newline (``b'\n'``) character after at most every *wrapcol* characters.
If *wrapcol* is zero (default), do not add any newlines.

I would put this before the 'May assert' line. Same applies to the other cases.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@serhiy-storchaka serhiy-storchaka Dec 31, 2025

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. But does not it create a contradiction in the binascii module?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@bitdancer bitdancer Dec 31, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean? I thought I was just rewording your documentation to use the imperative mode like the first sentence. Or did I get it wrong? Does it add a final newline if wrapcol is 0? In which case it would be "if wrapcol is zero (default), add a single trailing newline."

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@serhiy-storchaka serhiy-storchaka Dec 31, 2025

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It adds a final newline if newline is true (default), independently from wrapcol.

Of course, wrapcol is a new parameter, and we can change its behavior. But there are use cases for all 4 variants, so it is better to make these parameters orthogonal.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@bitdancer bitdancer Jan 1, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds like my rephrasing was correct then? Or maybe "do not insert any newlines"?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@serhiy-storchaka serhiy-storchaka Jan 2, 2026

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know, I only ask if that does not look weird in English. In one paragraph, "do not add any newlines", in the next paragraph -- "a newline character will be added at the end of the output".

But they are different paragraphs, and the latter specifically mention "at the end of the output", so this may be okay. If you don't see a problem, there is no problem.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@bitdancer bitdancer Jan 3, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see what you mean now. Yes, I would change it from 'do not add any newlines' to 'do not insert any newlines'. That should keep it distinct from the 'add' in the next paragraph.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
serhiy-storchaka added 5 commits December 31, 2025 12:14
@serhiy-storchaka
Address review comment.
bd3ed76
@serhiy-storchaka
Merge branch 'main' into base64-encode-wrapcol
7458e50
@serhiy-storchaka
Address yet one review comment.
a3bcc61
@serhiy-storchaka
Merge branch 'main' into base64-encode-wrapcol
bb5ff57
@serhiy-storchaka
Refactor plistlib.
7b3e7e1
@serhiy-storchaka serhiy-storchaka mentioned this pull request Jan 2, 2026
gh-143346: Fix calculation of the line width for wrapped Base64 in plistlib #143347
Merged
serhiy-storchaka added 4 commits January 2, 2026 13:04
@serhiy-storchaka
Fix the indent width in plistlib.
87a048d
@serhiy-storchaka
Merge branch 'main' into base64-encode-wrapcol
cb5c93f
@serhiy-storchaka
Polish docs.
6d190e9
@serhiy-storchaka
Merge branch 'main' into base64-encode-wrapcol
107224f
@serhiy-storchaka
serhiy-storchaka merged commit a471a32 into python:main Jan 14, 2026
46 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting core review label Jan 14, 2026
@serhiy-storchaka
serhiy-storchaka deleted the base64-encode-wrapcol branch January 14, 2026 12:44
thunder-coding pushed a commit to thunder-coding/cpython that referenced this pull request Feb 15, 2026
@serhiy-storchaka @thunder-coding
pythongh-143214: Add the wrapcol parameter in binascii.b2a_base64() a…
abd5771
…nd base64.b64encode() (pythonGH-143216)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@gpshead gpshead gpshead left review comments
@bitdancer bitdancer bitdancer left review comments
@cmaloney cmaloney cmaloney left review comments
@picnixz picnixz picnixz left review comments
@AA-Turner AA-Turner Awaiting requested review from AA-Turner AA-Turner is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@serhiy-storchaka @gpshead @bitdancer @cmaloney @picnixz
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.