[3.12] gh-114563: C decimal falls back to pydecimal for unsupported format strings (GH-114879) (GH-115353)

Immediate merits:
* eliminate complex workarounds for 'z' format support
  (NOTE: mpdecimal recently added 'z' support, so this becomes
  efficient in the long term.)
* fix 'z' format memory leak
* fix 'z' format applied to 'F'
* fix missing '#' format support

Suggested and prototyped by Stefan Krah.

Fixes gh-114563, gh-91060

(cherry picked from commit 72340d15cd)

Co-authored-by: John Belmonte <john@neggie.net>
Co-authored-by: Stefan Krah <skrah@bytereef.org>
This commit is contained in:
John Belmonte 2024-02-13 06:31:12 +09:00 committed by GitHub
parent 2ed47d8f8b
commit 09c98e4633
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 88 additions and 122 deletions

View file

@ -1121,6 +1121,13 @@ class FormatTest:
('z>z6.1f', '-0.', 'zzz0.0'),
('x>z6.1f', '-0.', 'xxx0.0'),
('🖤>z6.1f', '-0.', '🖤🖤🖤0.0'), # multi-byte fill char
('\x00>z6.1f', '-0.', '\x00\x00\x000.0'), # null fill char
# issue 114563 ('z' format on F type in cdecimal)
('z3,.10F', '-6.24E-323', '0.0000000000'),
# issue 91060 ('#' format in cdecimal)
('#', '0', '0.'),
# issue 6850
('a=-7.0', '0.12345', 'aaaa0.1'),
@ -5712,6 +5719,21 @@ class CWhitebox(unittest.TestCase):
with self.assertRaisesRegex(ValueError, err_msg):
sd.copy()
def test_format_fallback_capitals(self):
# Fallback to _pydecimal formatting (triggered by `#` format which
# is unsupported by mpdecimal) should honor the current context.
x = C.Decimal('6.09e+23')
self.assertEqual(format(x, '#'), '6.09E+23')
with C.localcontext(capitals=0):
self.assertEqual(format(x, '#'), '6.09e+23')
def test_format_fallback_rounding(self):
y = C.Decimal('6.09')
self.assertEqual(format(y, '#.1f'), '6.1')
with C.localcontext(rounding=C.ROUND_DOWN):
self.assertEqual(format(y, '#.1f'), '6.0')
@requires_docstrings
@requires_cdecimal
class SignatureTest(unittest.TestCase):