You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
non-ascii fill characters no longer work in formatting #57915
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2012-02-24.21:02:08.204>created_at=<Date2012-01-03.22:36:24.835>labels= ['interpreter-core', 'type-bug']
title='non-ascii fill characters no longer work in formatting'updated_at=<Date2012-02-24.21:02:08.203>user='https://github.com/skrah'
It used to be possible to specify Unicode fill characters in numeric
formatting:
Python 3.3.0a0 (default:1dd6908df8f5, Jul 16 2011, 11:16:00)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> format(1234, "\u2007<7")
'1234\u2007\u2007\u2007'
[64682 refs]
>>>
Now it doesn't work:
Python 3.3.0a0 (default:65ac469d30e6, Jan 3 2012, 23:23:07)
[GCC 4.4.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> format(1234, "\u2007<7")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: fill character too large
changed the title [-]Unicode fill characters no longer work in numeric formatting[/-][+]non-ascii fill characters no longer work in numeric formatting[/+]on Jan 3, 2012
I assume this is left over from the PEP-393 changes.
Correct.
I'm not sure such a restriction needs to exist any more.
The restriction was introduced to simplify the implementation. maxchar has to be computed exactly in format_string_internal(), format_int_or_long_internal(), format_float_internal() and format_complex_internal().
For format_string_internal(), the following change is enough (untested):
For number formatting functions, spec->n_lpadding, spec->n_spadding and spec->n_rpadding have to be checked. Something like:
if (spec->n_lpadding || spec->n_spadding || spec->n_rpadding)
maxchar = Py_MAX(maxchar, format->fill_char);
loewis commented on Jan 3, 2012
loewismannequin
Mannequin
More actions
Removing the if condition would be incorrect. The maximum char is computed at the beginning of the formatting. If, during formatting, need for a padding character is determined, the padding character must not be larger than the maximum char of the target string - which is 127 unless 'c' formatting is used.
One solution would be to determine whether the padding character is used in advance. Another solution would be to widen the string when the need for non-ASCII padding is detected.
I have no intention of fixing this issue myself; I don't mind if non-ASCII padding characters are not supported in 3.3.
skrah commented on Jan 3, 2012
skrahmannequin
MannequinAuthor
More actions
Actually the issue is not restricted to numeric formatting. It's not
possible to pad a Unicode string with a non-ascii whitespace:
>>> format("abcd", "\u2007<7")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: fill character too large
I'd be more than happy to restrict all numerical I/O operations to
ASCII. This includes input strings for int(), float(), Decimal().
It does break backwards compatibility though and the situation
for string formatting above seems odd to me. It is worse when
the rejected fill character is already present in the string:
>>> format("\u2007abcd", "\u2007<7")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: fill character too large
changed the title [-]non-ascii fill characters no longer work in numeric formatting[/-][+]non-ascii fill characters no longer work in formatting[/+]on Jan 3, 2012
The ps_AF locale fails with an assert after the latest commit:
...
format(13232434234.23423, "n")
python: Python/formatter_unicode.c:606: fill_number:
Assertion `r == spec->n_grouped_digits' failed.
Aborted
Oh, you found a locale with a non-ASCII decimal point, cool! I failed to find such locale. The last commit makes Python supports non-ASCII decimal point.
Your comment is incorrect, it was already failing before my commit ;-) Example at changeset 548a023c8230:
D9 AC/AB are byte strings b'\xD9\xAC' and b'\xD9\xAB' which are UTF-8 encode strings corresponding to U+066C (arabic thousands separator) and U+066B (arabic decimal separator).
\Uffffffab is a bug in a cast from signed char to 32-bit unsigned integer (Py_UNICODE on Linux).
By the way, Python 3.2 fails also to handle
non-ASCII thousands separator or non-ASCII
decimal point: (...)
Hum, it is not trivial to redo the work on Python 3.2. I prefer to leave the code unchanged to not introduce a regression, and I wait until a Python 3.2 user complains (the bug exists since Python 3.0 and nobody complained).
Activity
skrah commentedon Jan 3, 2012
It used to be possible to specify Unicode fill characters in numeric
formatting:
Now it doesn't work:
benjaminp commentedon Jan 3, 2012
It's still possible; it's just apparently limited to ASCII characters.
skrah commentedon Jan 3, 2012
Hum, somehow I always refuse to acknowledge that ASCII is a subset
of Unicode. :)
[-]Unicode fill characters no longer work in numeric formatting[/-][+]non-ascii fill characters no longer work in numeric formatting[/+]ericvsmith commentedon Jan 3, 2012
I assume this is left over from the PEP-393 changes. I think the right thing to do is delete this code from line 277 of formatter_unicode.c:
I'm not sure such a restriction needs to exist any more. But I'll admit to not having thought it through.
vstinner commentedon Jan 3, 2012
Correct.
The restriction was introduced to simplify the implementation. maxchar has to be computed exactly in format_string_internal(), format_int_or_long_internal(), format_float_internal() and format_complex_internal().
For format_string_internal(), the following change is enough (untested):
For number formatting functions, spec->n_lpadding, spec->n_spadding and spec->n_rpadding have to be checked. Something like:
loewis commentedon Jan 3, 2012
Removing the if condition would be incorrect. The maximum char is computed at the beginning of the formatting. If, during formatting, need for a padding character is determined, the padding character must not be larger than the maximum char of the target string - which is 127 unless 'c' formatting is used.
One solution would be to determine whether the padding character is used in advance. Another solution would be to widen the string when the need for non-ASCII padding is detected.
I have no intention of fixing this issue myself; I don't mind if non-ASCII padding characters are not supported in 3.3.
skrah commentedon Jan 3, 2012
Actually the issue is not restricted to numeric formatting. It's not
possible to pad a Unicode string with a non-ascii whitespace:
I'd be more than happy to restrict all numerical I/O operations to
ASCII. This includes input strings for int(), float(), Decimal().
It does break backwards compatibility though and the situation
for string formatting above seems odd to me. It is worse when
the rejected fill character is already present in the string:
[-]non-ascii fill characters no longer work in numeric formatting[/-][+]non-ascii fill characters no longer work in formatting[/+]ericvsmith commentedon Jan 12, 2012
Sorry for the off-the-cuff diagnosis. I had assumed this was the unintended result of the conversion, but of course I'm wrong.
I'd like to fix this.
python-dev commentedon Jan 21, 2012
New changeset 231c6042c40c by Victor Stinner in branch 'default':
Issue bpo-13706: Support non-ASCII fill characters
http://hg.python.org/cpython/rev/231c6042c40c
vstinner commentedon Jan 21, 2012
I fixed the original report, but there is still an issue with non-ASCII thousands separator.
python-dev commentedon Jan 31, 2012
New changeset 056f5cc8885d by Victor Stinner in branch 'default':
Issue bpo-13706: Add assertions to detect bugs earlier
http://hg.python.org/cpython/rev/056f5cc8885d
vstinner commentedon Feb 1, 2012
With the changeset 056f5cc8885d, format(1234, 'n') fails in a locale using a non-ASCII thousands separator. Patch showing the problem:
vstinner commentedon Feb 14, 2012
thousands_separator.patch:
Note: the patch handles also non-ASCII decimal point, even I don't know any locale using such point.
skrah commentedon Feb 14, 2012
I'm using ps_AF for testing:
python-dev commentedon Feb 23, 2012
New changeset f89e2f4cda88 by Victor Stinner in branch 'default':
Issue bpo-13706: Fix format(int, "n") for locale with non-ASCII thousands separator
http://hg.python.org/cpython/rev/f89e2f4cda88
skrah commentedon Feb 24, 2012
The ps_AF locale fails with an assert after the latest commit:
python-dev commentedon Feb 24, 2012
New changeset a29d20fa85b4 by Victor Stinner in branch 'default':
Issue bpo-13706: Fix format(float, "n") for locale with non-ASCII decimal point (e.g. ps_aF)
http://hg.python.org/cpython/rev/a29d20fa85b4
vstinner commentedon Feb 24, 2012
Oh, you found a locale with a non-ASCII decimal point, cool! I failed to find such locale. The last commit makes Python supports non-ASCII decimal point.
Your comment is incorrect, it was already failing before my commit ;-) Example at changeset 548a023c8230:
--
By the way, Python 3.2 fails also to handle non-ASCII thousands separator or non-ASCII decimal point:
D9 AC/AB are byte strings b'\xD9\xAC' and b'\xD9\xAB' which are UTF-8 encode strings corresponding to U+066C (arabic thousands separator) and U+066B (arabic decimal separator).
\Uffffffab is a bug in a cast from signed char to 32-bit unsigned integer (Py_UNICODE on Linux).
skrah commentedon Feb 24, 2012
STINNER Victor <report@bugs.python.org> wrote:
Ah, sorry about that. I was lazy and tested against 585d3664da89 (which is a
couple of weeks old).
That version didn't crash but produced UTF-8 output. :)
Now things look great, thanks for fixing all of that.
vstinner commentedon Feb 24, 2012
Hum, it is not trivial to redo the work on Python 3.2. I prefer to leave the code unchanged to not introduce a regression, and I wait until a Python 3.2 user complains (the bug exists since Python 3.0 and nobody complained).