This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: locale.atof keep '.' even if not part of the localeconv
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: ced, eric.smith, matrixise, terry.reedy, vstinner
Priority: normal Keywords:

Created on 2015-11-03 13:30 by ced, last changed 2022-04-11 14:58 by admin.

Messages (7)
msg253989 - (view) Author: Cédric Krier (ced) * Date: 2015-11-03 13:30
If a value containing '.' is passed to locale.atof, but '.' is not the locale decimal_point (and not the thousands_sep), it is anyway parsed as the decimal_point.
For me, it should raise a ValueError
msg253990 - (view) Author: Cédric Krier (ced) * Date: 2015-11-03 13:34
Example:

>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8')
'fr_FR.UTF-8'
>>> locale.atof('2.5')
2.5
>>> locale.atof('2,5')
2.5
msg253991 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2015-11-03 13:39
locale.atof() is implemented as float(locale.delocalize(string)).

locale.delocalize() replaces the locale numeric dot with ".":

>>> locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8')
'fr_FR.UTF-8'
>>> locale.delocalize("1,2")
'1.2'
>>> locale.localeconv()['decimal_point']
','
>>> locale.delocalize("1.2")
'1.2'

I'm not sure that it's very useful to break backward compatibility to be more strict.

locale.delocalize() and locale.atof() are a few lines of Python, it's probably worth to copy them and modify them to get the expected behaviour.
msg253992 - (view) Author: Cédric Krier (ced) * Date: 2015-11-03 13:51
But you can have some strange behaviour:

>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8')
'fr_FR.UTF-8'
>>> locale.atof('2.500,5')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/locale.py", line 316, in atof
    return func(string)
ValueError: invalid literal for float(): 2.500.5
>>> locale.atof('2.500')
2.5

If you agree to make it more strict, I can work on a patch, otherwise I will just add some tests on my code.
msg253999 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2015-11-03 16:12
That's an unfortunate implementation choice. I agree we probably can't break locale.atof, but how about adding another function with a better implementation, that's strictly locale-aware?
msg254020 - (view) Author: Stéphane Wirtel (matrixise) * (Python committer) Date: 2015-11-03 21:34
@eric.smith maybe we can add a new strict function.
msg254240 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2015-11-06 23:43
I much prefer a new argument, 'strict=False', to a new, near-duplicate function.

locale.atof('2.500,5') should raise.  The only question is what should be displayed as the invalid literal: the original or the converted.  It seems to me that delocalize should replace the local thousands separator, in this case '.', with ',' as it replaces the local decimal point with '.'.  Then the invalid literal would be '1,234.5'.  And locale.atof('1.5') would become float('1,5'), which would raise.
History
Date User Action Args
2022-04-11 14:58:23adminsetgithub: 69729
2015-11-06 23:43:49terry.reedysetnosy: + terry.reedy
messages: + msg254240
2015-11-03 21:34:26matrixisesetnosy: + matrixise
messages: + msg254020
2015-11-03 16:12:08eric.smithsetnosy: + eric.smith
messages: + msg253999
2015-11-03 13:51:34cedsetmessages: + msg253992
2015-11-03 13:39:30vstinnersetnosy: + vstinner

messages: + msg253991
versions: + Python 3.6
2015-11-03 13:34:01cedsetmessages: + msg253990
2015-11-03 13:30:18cedcreate