Skip to content

Locale class uses str(...) in __init__ #1252

@nathaniel-kotzrenko-hs

Description

@nathaniel-kotzrenko-hs

Hello!

I noticed that the Locale class under babel/core.py uses str(...) when getting it's identifiers.
This can pose an issue for overriding classes that wish to modify the str representation of the object.

Looking at the class, all other points in the class (and str dunder itself) use a different function (get_locale_identifier), that can be used in init too, and free str to modifications. As of right now modifying it causes a bug on creating the Locale object properly and limiting usage.

def __init__(
      self,
      language: str,
      territory: str | None = None,
      script: str | None = None,
      variant: str | None = None,
      modifier: str | None = None,
  ) -> None:
      """Initialize the locale object from the given identifier components.

      >>> locale = Locale('en', 'US')
      >>> locale.language
      'en'
      >>> locale.territory
      'US'

      :param language: the language code
      :param territory: the territory (country or region) code
      :param script: the script code
      :param variant: the variant code
      :param modifier: a modifier (following the '@' symbol, sometimes called '@variant')
      :raise `UnknownLocaleError`: if no locale data is available for the
                                   requested locale
      """
      #: the language code
      self.language = language
      #: the territory (country or region) code
      self.territory = territory
      #: the script code
      self.script = script
      #: the variant code
      self.variant = variant
      #: the modifier
      self.modifier = modifier
      self.__data: localedata.LocaleDataDict | None = None

      # identifier = str(this) <-- this is the old part, the following is the proposed solution to free __str__ up for inheriting classes
      identifier = get_locale_identifier(
          (self.language, self.territory, self.script, self.variant, self.modifier),
      )
      identifier_without_modifier = identifier.partition('@')[0]
      if localedata.exists(identifier):
          self.__data_identifier = identifier
      elif localedata.exists(identifier_without_modifier):
          self.__data_identifier = identifier_without_modifier
      else:
          raise UnknownLocaleError(identifier)

# Current implementation of str in the Locale class
def __str__(self) -> str:
      return get_locale_identifier(
          (self.language, self.territory, self.script, self.variant, self.modifier),
      )

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions