Skip to content

Currency symbol parsing code should ignore alternate symbols #397

@jtwang

Description

@jtwang

CLDR defines several formats for currency symbols (narrow, variant), Babel currently exposes the main symbol only. Eg. In es.xml, 'KMF' is 'main' symbol for currency KMF.

            <currency type="KMF">
                <displayName>franco comorense</displayName>
                <displayName count="one">franco comorense</displayName>
                <displayName count="other">francos comorenses</displayName>
                <symbol>KMF</symbol>
                <symbol alt="narrow">CF</symbol>
            </currency>

However, the code that selects and processes this element does not exclude the alternate forms, so in theory it's possible for an alternate symbol to be read and set as the symbol instead. This is does not actually manifest as a bug in Babel 2.3.x since CLDR 28 always defines the 'main' symbol element before the alt versions; however, this doesn't change the fact that the code isn't quite right. :)

Demonstration

Current CLDR + import-cldr script work fine:

$ grep -A6 currency.*KMF cldr/core-28/common/main/es.xml | grep symbol
                <symbol>KMF</symbol>
                <symbol alt="narrow">CF</symbol>
$ make clean-cldr
$ make import-cldr
$ python
>>> from babel.numbers import *
>>> get_currency_symbol('KMF', locale='es')
u'KMF'

Now switch the two symbol lines in es.xml and try again:

$ grep -A6 currency.*KMF cldr/core-28/common/main/es.xml | grep symbol
                <symbol alt="narrow">CF</symbol>
                <symbol>KMF</symbol>
$ make clean-cldr
$ make import-cldr
$ python
>>> from babel.numbers import *
>>> get_currency_symbol('KMF', locale='es')
u'CF'

A Possible Fix

Although it would be cool if we supported alt symbols. :)

diff --git a/scripts/import_cldr.py b/scripts/import_cldr.py
index 8de7043..c7d42d0 100755
--- a/scripts/import_cldr.py
+++ b/scripts/import_cldr.py
@@ -747,9 +747,9 @@ def parse_currency_names(data, tree):
             else:
                 currency_names[code] = text_type(name.text)
         # TODO: support choice patterns for currency symbol selection
-        symbol = elem.find('symbol')
-        if symbol is not None and 'draft' not in symbol.attrib and 'choice' not in symbol.attrib:
-            currency_symbols[code] = text_type(symbol.text)
+        for symbol in elem.findall('symbol'):
+            if symbol is not None and 'draft' not in symbol.attrib and 'choice' not in symbol.attrib and 'alt' not in symbol.attrib:
+                currency_symbols[code] = text_type(symbol.text)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions