Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions Lib/test/test_binascii.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
"""Test the binascii C module."""

import sys
import threading
import unittest
import binascii
import array
import re
from test import support
from test.support import bigmemtest, _1G, _4G
from test.support.hypothesis_helper import hypothesis
from test.support import threading_helper
from test.support.script_helper import assert_python_ok


# Note: "*_hex" functions are aliases for "(un)hexlify"
Expand Down Expand Up @@ -517,5 +522,63 @@ def test_big_buffer(self, size):
self.assertEqual(binascii.crc32(data), 1044521549)


class FreeThreadingTest(unittest.TestCase):
@unittest.skipUnless(support.Py_GIL_DISABLED,
'only meaningful in free-threaded builds')
def test_import_does_not_enable_gil(self):
assert_python_ok(
'-X', 'gil=0',
'-c',
(
'import sys\n'
'if sys._is_gil_enabled():\n'
' raise SystemExit("GIL unexpectedly enabled")\n'
'import binascii\n'
'if sys._is_gil_enabled():\n'
' raise SystemExit("GIL unexpectedly enabled after import")\n'
),
)
Comment on lines +528 to +540
Copy link
Member

Choose a reason for hiding this comment

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

Do we have precedent for this anywhere? I don't think this is particularly helpful to test for.


@unittest.skipUnless(support.Py_GIL_DISABLED,
'this test can only possibly fail with GIL disabled')
@threading_helper.reap_threads
@threading_helper.requires_working_threading()
def test_free_threading(self):
if sys._is_gil_enabled():
self.skipTest('test requires running with -X gil=0')
Comment on lines +547 to +548
Copy link
Member

Choose a reason for hiding this comment

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

Let's remove this. Things should still be thread-safe with the GIL enabled.


num_threads = 8
barrier = threading.Barrier(num_threads)

payload = (
b'The quick brown fox jumps over the lazy dog.\r\n'
+ bytes(range(256))
)
hexed = binascii.hexlify(payload)
b64 = binascii.b2a_base64(payload, newline=False)
expected_crc = binascii.crc32(payload)

def worker():
barrier.wait(timeout=support.SHORT_TIMEOUT)
for _ in range(1000):
if binascii.unhexlify(hexed) != payload:
raise AssertionError('unhexlify mismatch')
Comment on lines +564 to +565
Copy link
Member

Choose a reason for hiding this comment

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

Use self.assertEqual instead of manually raising assertions like this.

if binascii.hexlify(payload) != hexed:
raise AssertionError('hexlify mismatch')
if binascii.a2b_base64(b64) != payload:
raise AssertionError('a2b_base64 mismatch')
if binascii.b2a_base64(payload, newline=False) != b64:
raise AssertionError('b2a_base64 mismatch')
if binascii.crc32(payload) != expected_crc:
raise AssertionError('crc32 mismatch')

threads = [threading.Thread(target=worker) for _ in range(num_threads)]
with threading_helper.catch_threading_exception() as cm:
with threading_helper.start_threads(threads):
pass
if cm.exc_value is not None:
raise cm.exc_value


if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added free-threading regression tests for the binascii module.
Copy link
Member

Choose a reason for hiding this comment

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

We don't need a news entry for this, since it's an internal-only change. I'm not sure why we have a section for this; I'll ask internally. For now, let's remove this, and I'll apply the skip news label.

Loading