Skip to content

locale.normalize strips "-" from UTF-8, which fails on Mac #54363

Closed

Description

@ixokai
mannequin
BPO 10154
Nosy @malemburg, @birkenfeld, @ronaldoussoren, @pitrou, @vstinner, @Lothiraldan
Files
  • issue10154.patch
  • 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 = 'https://github.com/ronaldoussoren'
    closed_at = <Date 2011-05-17.12:14:26.253>
    created_at = <Date 2010-10-20.15:31:23.515>
    labels = ['OS-mac', 'type-bug', 'library']
    title = 'locale.normalize strips "-" from UTF-8,\twhich fails on Mac'
    updated_at = <Date 2011-05-17.12:49:51.177>
    user = 'https://bugs.python.org/ixokai'

    bugs.python.org fields:

    activity = <Date 2011-05-17.12:49:51.177>
    actor = 'python-dev'
    assignee = 'ronaldoussoren'
    closed = True
    closed_date = <Date 2011-05-17.12:14:26.253>
    closer = 'ronaldoussoren'
    components = ['Library (Lib)', 'macOS']
    creation = <Date 2010-10-20.15:31:23.515>
    creator = 'ixokai'
    dependencies = []
    files = ['21916']
    hgrepos = []
    issue_num = 10154
    keywords = ['patch']
    message_count = 15.0
    messages = ['119213', '119216', '119236', '119298', '119301', '119309', '122374', '123553', '123667', '129662', '134271', '134450', '135406', '136150', '136154']
    nosy_count = 10.0
    nosy_names = ['lemburg', 'georg.brandl', 'ixokai', 'ronaldoussoren', 'pitrou', 'vstinner', 'ruseel', 'Boris.FELD', 'python-dev', 'PiotrSikora']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue10154'
    versions = ['Python 3.1', 'Python 2.7', 'Python 3.2', 'Python 3.3']

    Activity

    1. ixokai commented on Oct 20, 2010

      ixokaimannequin
      MannequinAuthor

      In the course of investigating bpo-10092, Georg discovered that the behavior of locale.normalize() on Mac is bad.

      Basically, "en_US.UTF-8" is how the "correct" locale string should be spelled on the Mac. If you drop the dash, it fails: which locale.normalize does, so you can't pass the return value of the function to setlocale, even though that's what its documented to be for.

      If that isn't clear, this should demonstrate (from /branches/py3k):

      Top-2:build pythonbuildbot$ ./python.exe
      Python 3.2a3+ (py3k:85631, Oct 17 2010, 06:45:22) 
      [GCC 4.2.1 (Apple Inc. build 5664)] on darwin
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import locale
      [51767 refs]
      >>> locale.normalize("en_US.UTF-8")
      'en_US.UTF8'
      [51770 refs]
      >>> locale.setlocale(locale.LC_TIME, 'en_US.UTF8')
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "/Users/pythonbuildbot/test/build/Lib/locale.py", line 538, in setlocale
          return _setlocale(category, locale)
      locale.Error: unsupported locale setting
      [51816 refs]
      >>> locale.setlocale(locale.LC_TIME, 'en_US.UTF-8')
      'en_US.UTF-8'
      [51816 refs]

      The precise same behavior exists on my stock/system Python 2.6, too, fwiw. (Not that it can be fixed on 2.6, but maybe 2.7?)

    2. added
      stdlibStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or error
      on Oct 20, 2010
    3. ronaldoussoren commented on Oct 20, 2010

      @ronaldoussoren
      Contributor

      This patch solves the immediate failure:

      Index: Lib/locale.py
      ===================================================================

      --- Lib/locale.py	(revision 85743)
      +++ Lib/locale.py	(working copy)
      @@ -396,6 +396,9 @@
               else:
                   encoding = defenc
               #print 'found encoding %r' % encoding
      +        if sys.platform == 'darwin' and encoding == 'UTF8':
      +            encoding = 'UTF-8'
      +
               if encoding:
                   return langname + '.' + encoding
               else:

      I'm not happy about hardcoding this specific exception though, there should be a better solution than this.

      Ronald

    4. malemburg commented on Oct 20, 2010

      @malemburg
      Member

      Ronald Oussoren wrote:

      Ronald Oussoren <ronaldoussoren@mac.com> added the comment:

      This patch solves the immediate failure:

      Index: Lib/locale.py
      ===================================================================
      --- Lib/locale.py (revision 85743)
      +++ Lib/locale.py (working copy)
      @@ -396,6 +396,9 @@
      else:
      encoding = defenc
      #print 'found encoding %r' % encoding

      •    if sys.platform == 'darwin' and encoding == 'UTF8':
        
      •        encoding = 'UTF-8'
        
      •    if encoding:
               return langname + '.' + encoding
           else:
        

      I'm not happy about hardcoding this specific exception though, there should be a better solution than this.

      Could you tell me the values of localename, code, langname and encoding
      at that step in the process ?

      We may need to add an locale_encoding_alias from 'UTF8' to 'UTF-8',
      since the version with the hyphen is what the C lib uses.

    5. changed the title [-]locale.normalize strips "-" from UTF-8, which fails on Mac[/-] [+]locale.normalize strips "-" from UTF-8, which fails on Mac[/+] on Oct 20, 2010
    6. ixokai commented on Oct 21, 2010

      ixokaimannequin
      MannequinAuthor

      Mark, the locals() right before "if encoding:" (line 399) are:

      >>> locale.normalize("en_US.UTF-8")
      {'code': 'en_US.ISO8859-1', 'langname': 'en_US', 'encoding': 'UTF8', 'norm_encoding': 'utf_8', 'defenc': 'ISO8859-1', 'localename': 'en_US.UTF-8', 'lookup_name': 'en_us.utf-8', 'fullname': 'en_us.utf-8'}
      'en_US.UTF8'
    7. malemburg commented on Oct 21, 2010

      @malemburg
      Member
      Stephen Hansen wrote:
      > 
      > Stephen Hansen <me+python@ixokai.io> added the comment:
      > 
      > Mark, the locals() right before "if encoding:" (line 399) are:
      > 
      >>>> locale.normalize("en_US.UTF-8")
      > {'code': 'en_US.ISO8859-1', 'langname': 'en_US', 'encoding': 'UTF8', 'norm_encoding': 'utf_8', 'defenc': 'ISO8859-1', 'localename': 'en_US.UTF-8', 'lookup_name': 'en_us.utf-8', 'fullname': 'en_us.utf-8'}
      > 'en_US.UTF8'

      Thanks.

      Line 646 in the alias table is wrong:

      'utf_8':                        'UTF8',
      

      should read:

      'utf_8':                        'UTF-8',
      

      I wonder why this wasn't reported earlier - did the GlibC change
      the UTF-8 spelling at some point ? I do vaguely remember that I
      had to remove the hyphen due to problems with setlocale() not
      accepting 'UTF-8', but that was at the time I wrote that part
      of locale.py, i.e. many years ago.

      It doesn't appear to be necessary anymore. I checked on openSUSE
      10.3 and 11.3. Both work fine with 'UTF-8' and 'UTF8'.

    8. birkenfeld commented on Oct 21, 2010

      @birkenfeld
      Member

      If other Posix-y systems accept both spellings and only Macs insist on the dash, we should probably indeed change the alias entry to use it.

    9. pitrou commented on Nov 25, 2010

      @pitrou
      Member

      Mandriva and Debian also work fine with both "UTF8" and "UTF-8". For the record, the canonical spelling inside /usr/share/locale is "UTF-8". I suppose glibc does its own normalization.

    10. ronaldoussoren commented on Dec 7, 2010

      @ronaldoussoren
      Contributor

      UTF-8 works on SuSE Enterprise Linux 9 and 10 as well.

      BTW, neither UTF8 nor UTF-8 work on HPUX 10. That platform requires spelling it as utf8.

      This sadly enought means that this code doesn't work on HPUX 10:

      >>> locale.setlocale(locale.LC_ALL, locale.getdefaultlocale())
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "/opt/python2.7/lib/python2.7/locale.py", line 531, in setlocale
          return _setlocale(category, locale)
      locale.Error: unsupported locale setting

      That's because getdefaultlocale returns 'UTF8' as the encoding, even though LANG is set to 'nl_NL.utf8' (which is a working locale on the machine I tested).

      BTW. I'm +1 on changing the alias table as Marc-Andre proposed.

    11. ruseel commented on Dec 9, 2010

      ruseelmannequin
      Mannequin

      Ubuntu 10.4.1 LTS
      also work fine with both "UTF8" and "UTF-8"

    12. Lothiraldan commented on Feb 27, 2011

      Lothiraldanmannequin
      Mannequin

      Bug confirmed on python2.5+ and python3.2-.

      If it works with the dash, is agree with the Marc-Andre solution.

    13. PiotrSikora commented on Apr 22, 2011

      PiotrSikoramannequin
      Mannequin

      It's the same on OpenBSD (and I'm pretty sure it's true for other BSDs as well).

      >>> locale.resetlocale()
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "/usr/local/lib/python2.6/locale.py", line 523, in resetlocale
          _setlocale(category, _build_localename(getdefaultlocale()))
      locale.Error: unsupported locale setting
      >>> locale._build_localename(locale.getdefaultlocale())
      'en_US.UTF8'

      Works fine with Marc-Andre's alias table fix.

      Any chances this will be eventually fixed in 2.x?

    14. changed the title [-]locale.normalize strips "-" from UTF-8, which fails on Mac[/-] [+]locale.normalize strips "-" from UTF-8, which fails on Mac[/+] on Apr 23, 2011
    15. malemburg commented on Apr 26, 2011

      @malemburg
      Member
      Piotr Sikora wrote:
      > 
      > Piotr Sikora <piotr.sikora@frickle.com> added the comment:
      > 
      > It's the same on OpenBSD (and I'm pretty sure it's true for other BSDs as well).
      > 
      >>>> locale.resetlocale()
      > Traceback (most recent call last):
      >   File "<stdin>", line 1, in <module>
      >   File "/usr/local/lib/python2.6/locale.py", line 523, in resetlocale
      >     _setlocale(category, _build_localename(getdefaultlocale()))
      > locale.Error: unsupported locale setting
      >>>> locale._build_localename(locale.getdefaultlocale())
      > 'en_US.UTF8'
      > 
      > Works fine with Marc-Andre's alias table fix.
      > 
      > Any chances this will be eventually fixed in 2.x?

      This can go into Python 2.7, and, of course, into the 3.x
      branches.

    16. changed the title [-]locale.normalize strips "-" from UTF-8, which fails on Mac[/-] [+]locale.normalize strips "-" from UTF-8, which fails on Mac[/+] on Apr 26, 2011
    17. ronaldoussoren commented on May 7, 2011

      @ronaldoussoren
      Contributor

      The attached patch implements the change that Marc-Andre proposed.

      I intend to apply this patch to all active branches later today (after some more testing)

    18. python-dev commented on May 17, 2011

      python-devmannequin
      Mannequin

      New changeset 932de36903e7 by Ronald Oussoren in branch '2.7':
      (backport)Fix bpo-10154 and bpo-10090: locale normalizes the UTF-8 encoding to "UTF-8" instead of "UTF8"
      http://hg.python.org/cpython/rev/932de36903e7

      New changeset 28e410eb86af by Ronald Oussoren in branch '3.1':
      Fix bpo-10154 and bpo-10090: locale normalizes the UTF-8 encoding to "UTF-8" instead of "UTF8"
      http://hg.python.org/cpython/rev/28e410eb86af

      New changeset 454d13e535ff by Ronald Oussoren in branch '3.2':
      (merge) Fix bpo-10154 and bpo-10090: locale normalizes the UTF-8 encoding to "UTF-8" instead of "UTF8"
      http://hg.python.org/cpython/rev/454d13e535ff

    19. python-dev commented on May 17, 2011

      python-devmannequin
      Mannequin

      New changeset 3d7cb852a176 by Ronald Oussoren in branch 'default':
      Fix for bpo-10154, merge from 3.2
      http://hg.python.org/cpython/rev/3d7cb852a176

    20. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Labels

    OS-macstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions