FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Locale __init__/parse inconsistencies · Issue #283 · python-babel/babel · GitHub

Repository navigation

Locale __init__/parse inconsistencies #283

Open

Description

Babel 2.1.1, Python 2.7.5


Locale.parse('en_US') returns Locale('en', territory='US')
but
Locale('en_US') returns Locale('en_US')
when I would expect
Locale('en_US') returns Locale('en', territory='US') or UnknownLocaleError


Locale.parse(12) intentionally raises TypeError: Unxpected value for identifier: 12
but
Locale(12) causes an uncaught TypeError

babel/core.pyc, line 150, __init__
    identifier = str(self)
babel/core.pyc, line 339, __str__
    return get_locale_identifier((self.language, self.territory, self.script, self.variant))
babel/core.pyc, line 943, get_locale_identifier
    return sep.join(filter(None, (lang, script, territory, variant)))
TypeError: sequence item 0: expected string, int found

Activity

  1. akx commented on Dec 30, 2015

    Member

    Well, Locale() is meant to construct a locale exactly as you tell it to, but I do see your point.

    I see two approaches:

    • Make the Locale constructor a "do what I mean" API, and have it use the same logic as Locale.parse() if the given locale is not .isalpha().
    • Error out in the constructor if the locale is not alphabetical.
  2. mpkuth commented on Dec 30, 2015

    Author

    IMO, keeping Locale.parse(identifier) and Locale(language, territory=None, script=None, variant=None) separate is a good thing. I believe that the core of the issue when using the constructor is the validation logic that currently reads as follows.

    identifier = str(self)
    if not localedata.exists(identifier):
        raise UnknownLocaleError(identifier)
    

    The problem is that str(self) returns the same thing for both Locale('en_US') and Locale('en', territory='US') objects. The first is not valid because en_US is not a valid language but this check doesn't catch that and you get a whole locale identifier stored in the language attribute.

    Each given part of the locale should probably be validated separately. Something like...

    try:
        language = get_global('language_aliases')[language]
    except KeyError:
        raise UnknownLocaleError('Unknown language ' + language)
    
    if territory is not None:
        try:
            territory = get_global('territory_aliases')[territory][0]
        except KeyError:
            raise UnknownLocaleError('Unknown territory ' + territory)
    
    if script is not None:    
        try:
            script = get_global('script_aliases')[script]
        except KeyError:
            raise UnknownLocaleError('Unknown script ' + script)
    
    if variant is not None:
        try:
            variant = get_global('variant_aliases')[variant]
        except KeyError:
            raise UnknownLocaleError('Unknown variant ' + variant)
    

    This should also have the side effect of fixing the "I passed you a number" uncaught exception in the validator that isn't working as expected.

  3. akx commented on Dec 30, 2015

    Member

    The alias tables don't contain every language/territory/script/variant there is, though.

    Maybe if we start by validating the pieces to be alphabetical if they exist, and then build up to more precise validation later?

  4. mpkuth commented on Dec 30, 2015

    Author

    Forgive me as I haven't dug too deeply into the code, but if those tables aren't complete and you can get a Locale object with a language/territory/script/variant that isn't there then how is it useful? i.e. How does it know what to return for formatting and other functions?

    In any case, if you can't look it up directly then ensuring that each piece is only alpha or only alpha/num and of the correct length (if applicable) as you suggest would be a good starting point for better validation of constructor arguments.

  5. added a commit that references this issue on Dec 30, 2015
  6. akx commented on Dec 30, 2015

    Member

    Those are alias tables, such as

        "variant_aliases": {
            "HEPLOC": "ALALC97", 
            "AALAND": "AX", 
            "POLYTONI": "POLYTON"
        }

    that map previously/occasionally used names into the canonical names used by the CLDR.

    The actual knowledge of which locales are available stems from the existence of a .dat file for the particular locale identifier.

  7. added a commit that references this issue on Dec 30, 2015
  8. added a commit that references this issue on Jan 23, 2016
  9. added this to the Babel 3 milestone on Apr 25, 2016
  10. removed their assignment
    on Aug 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL