-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
gh-101178: Add Ascii85, base85, and Z85 support to binascii #102753
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 7 commits
05ae5ad
aa06c5d
6377440
6c0e4a3
ce4773c
4072e3b
bc9217f
2c40ba0
fd9eaf7
4746d18
d075593
6d65fec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
"""C accelerator wrappers for originally pure-Python parts of base64.""" | ||
|
||
from binascii import Error, a2b_ascii85, a2b_base85, b2a_ascii85, b2a_base85 | ||
from base64 import _bytes_from_decode_data, bytes_types | ||
|
||
|
||
# Base 85 encoder functions in base64 silently convert input to bytes. | ||
def _bytes_from_encode_data(b): | ||
return b if isinstance(b, bytes_types) else memoryview(b).tobytes() | ||
|
||
|
||
# Functions in binascii raise binascii.Error instead of ValueError. | ||
def raise_valueerror(func): | ||
def _func(*args, **kwargs): | ||
try: | ||
return func(*args, **kwargs) | ||
except Error as e: | ||
raise ValueError(e) from None | ||
return _func | ||
|
||
|
||
@raise_valueerror | ||
def _a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False): | ||
b = _bytes_from_encode_data(b) | ||
return b2a_ascii85(b, fold_spaces=foldspaces, | ||
wrap=adobe, width=wrapcol, pad=pad) | ||
|
||
|
||
@raise_valueerror | ||
def _a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v'): | ||
b = _bytes_from_decode_data(b) | ||
return a2b_ascii85(b, fold_spaces=foldspaces, | ||
wrap=adobe, ignore=ignorechars) | ||
|
||
|
||
@raise_valueerror | ||
def _b85encode(b, pad=False): | ||
b = _bytes_from_encode_data(b) | ||
return b2a_base85(b, pad=pad, newline=False) | ||
|
||
|
||
@raise_valueerror | ||
def _b85decode(b): | ||
b = _bytes_from_decode_data(b) | ||
return a2b_base85(b, strict_mode=True) | ||
|
||
|
||
@raise_valueerror | ||
def _z85encode(s): | ||
s = _bytes_from_encode_data(s) | ||
return b2a_base85(s, newline=False, z85=True) | ||
|
||
|
||
@raise_valueerror | ||
def _z85decode(s): | ||
s = _bytes_from_decode_data(s) | ||
return a2b_base85(s, strict_mode=True, z85=True) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -576,6 +576,27 @@ def decodebytes(s): | |
return binascii.a2b_base64(s) | ||
|
||
|
||
# Use accelerated implementations of originally pure-Python parts if possible. | ||
try: | ||
from _base64 import (_a85encode, _a85decode, _b85encode, | ||
_b85decode, _z85encode, _z85decode) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given these are already in a private module, you can remove the prefix. That means the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
from functools import update_wrapper | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Functools is an expensive import, I would copy the relative parts of |
||
update_wrapper(_a85encode, a85encode) | ||
update_wrapper(_a85decode, a85decode) | ||
update_wrapper(_b85encode, b85encode) | ||
update_wrapper(_b85decode, b85decode) | ||
update_wrapper(_z85encode, z85encode) | ||
update_wrapper(_z85decode, z85decode) | ||
a85encode = _a85encode | ||
a85decode = _a85decode | ||
b85encode = _b85encode | ||
b85decode = _b85decode | ||
z85encode = _z85encode | ||
z85decode = _z85decode | ||
except ImportError: | ||
pass | ||
|
||
|
||
# Usable as a script... | ||
def main(): | ||
"""Small main program""" | ||
|
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.
We should avoid import cycles like this, it can make refactoring in the future harder.