Add type annotations to QLocaleXmlReader
Task-number: QTBUG-129564 Change-Id: I8711152840e6bcb39ff1b1e67ff60b53801f28f0 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit feb39b2d033eae19937e86eca89c1c96141a0b4f)
This commit is contained in:
parent
42e138a529
commit
8c0867699c
@ -19,8 +19,9 @@ You can download jing from https://relaxng.org/jclark/jing.html if your
|
|||||||
package manager lacks the jing package.
|
package manager lacks the jing package.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Iterator
|
from typing import Callable, Iterable, Iterator
|
||||||
from xml.sax.saxutils import escape
|
from xml.sax.saxutils import escape
|
||||||
|
from xml.dom import minidom
|
||||||
|
|
||||||
from localetools import Error
|
from localetools import Error
|
||||||
|
|
||||||
@ -46,14 +47,16 @@ def startCount(c, text): # strspn
|
|||||||
return len(text)
|
return len(text)
|
||||||
|
|
||||||
class QLocaleXmlReader (object):
|
class QLocaleXmlReader (object):
|
||||||
def __init__(self, filename):
|
def __init__(self, filename: str) -> None:
|
||||||
self.root = self.__parse(filename)
|
self.root: minidom.Element = self.__parse(filename)
|
||||||
|
|
||||||
from enumdata import language_map, script_map, territory_map
|
from enumdata import language_map, script_map, territory_map
|
||||||
# Lists of (id, enum name, code, en.xml name) tuples:
|
# Tuples of (id, enum name, code, en.xml name) tuples:
|
||||||
languages = tuple(self.__loadMap('language', language_map))
|
languages = tuple(self.__loadMap('language', language_map))
|
||||||
scripts = tuple(self.__loadMap('script', script_map))
|
scripts = tuple(self.__loadMap('script', script_map))
|
||||||
territories = tuple(self.__loadMap('territory', territory_map))
|
territories = tuple(self.__loadMap('territory', territory_map))
|
||||||
|
|
||||||
|
# as enum numeric values, tuple[tuple[int, int, int], tuple[int, int, int]]
|
||||||
self.__likely = tuple(self.__likelySubtagsMap())
|
self.__likely = tuple(self.__likelySubtagsMap())
|
||||||
|
|
||||||
# Mappings {ID: (enum name, code, en.xml name)}
|
# Mappings {ID: (enum name, code, en.xml name)}
|
||||||
@ -69,14 +72,15 @@ class QLocaleXmlReader (object):
|
|||||||
self.__dupes = set(v[1] for v in languages) & set(v[1] for v in territories)
|
self.__dupes = set(v[1] for v in languages) & set(v[1] for v in territories)
|
||||||
self.cldrVersion = self.__firstChildText(self.root, "version")
|
self.cldrVersion = self.__firstChildText(self.root, "version")
|
||||||
|
|
||||||
def loadLocaleMap(self, calendars, grumble = lambda text: None):
|
def loadLocaleMap(self, calendars: Iterable[str], grumble = lambda text: None):
|
||||||
kid = self.__firstChildText
|
kid: Callable[[minidom.Element, str], str] = self.__firstChildText
|
||||||
likely = dict(self.__likely)
|
likely: dict[tuple[int, int, int], tuple[int, int, int]] = dict(self.__likely)
|
||||||
|
|
||||||
for elt in self.__eachEltInGroup(self.root, 'localeList', 'locale'):
|
for elt in self.__eachEltInGroup(self.root, 'localeList', 'locale'):
|
||||||
locale = Locale.fromXmlData(lambda k: kid(elt, k), calendars)
|
locale: Locale = Locale.fromXmlData(lambda k: kid(elt, k), calendars)
|
||||||
language = self.__langByName[locale.language][0]
|
language: int = self.__langByName[locale.language][0]
|
||||||
script = self.__textByName[locale.script][0]
|
script: int = self.__textByName[locale.script][0]
|
||||||
territory = self.__landByName[locale.territory][0]
|
territory: int = self.__landByName[locale.territory][0]
|
||||||
|
|
||||||
if language != 1: # C
|
if language != 1: # C
|
||||||
if territory == 0:
|
if territory == 0:
|
||||||
@ -87,7 +91,8 @@ class QLocaleXmlReader (object):
|
|||||||
# http://www.unicode.org/reports/tr35/#Likely_Subtags
|
# http://www.unicode.org/reports/tr35/#Likely_Subtags
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
to = likely[(locale.language, 'AnyScript', locale.territory)]
|
to: tuple[int, int, int] = likely[(locale.language, 'AnyScript',
|
||||||
|
locale.territory)]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
to = likely[(locale.language, 'AnyScript', 'AnyTerritory')]
|
to = likely[(locale.language, 'AnyScript', 'AnyTerritory')]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@ -98,22 +103,22 @@ class QLocaleXmlReader (object):
|
|||||||
|
|
||||||
yield (language, script, territory), locale
|
yield (language, script, territory), locale
|
||||||
|
|
||||||
def aliasToIana(self):
|
def aliasToIana(self) -> Iterator[tuple[str, str]]:
|
||||||
kid = self.__firstChildText
|
kid: Callable[[minidom.Element, str], str] = self.__firstChildText
|
||||||
for elt in self.__eachEltInGroup(self.root, 'zoneAliases', 'zoneAlias'):
|
for elt in self.__eachEltInGroup(self.root, 'zoneAliases', 'zoneAlias'):
|
||||||
yield kid(elt, 'alias'), kid(elt, 'iana')
|
yield kid(elt, 'alias'), kid(elt, 'iana')
|
||||||
|
|
||||||
def msToIana(self):
|
def msToIana(self) -> Iterator[tuple[str, str]]:
|
||||||
kid = self.__firstChildText
|
kid: Callable[[minidom.Element, str], str] = self.__firstChildText
|
||||||
for elt in self.__eachEltInGroup(self.root, 'windowsZone', 'msZoneIana'):
|
for elt in self.__eachEltInGroup(self.root, 'windowsZone', 'msZoneIana'):
|
||||||
yield kid(elt, 'msid'), kid(elt, 'iana')
|
yield kid(elt, 'msid'), kid(elt, 'iana')
|
||||||
|
|
||||||
def msLandIanas(self):
|
def msLandIanas(self) -> Iterator[tuple[str, str, str]]:
|
||||||
kid = self.__firstChildText
|
kid: Callable[[minidom.Element, str], str] = self.__firstChildText
|
||||||
for elt in self.__eachEltInGroup(self.root, 'windowsZone', 'msLandZones'):
|
for elt in self.__eachEltInGroup(self.root, 'windowsZone', 'msLandZones'):
|
||||||
yield kid(elt, 'msid'), kid(elt, 'territorycode'), kid(elt, 'ianaids')
|
yield kid(elt, 'msid'), kid(elt, 'territorycode'), kid(elt, 'ianaids')
|
||||||
|
|
||||||
def languageIndices(self, locales):
|
def languageIndices(self, locales: tuple[int, ...]) -> Iterator[tuple[int, str]]:
|
||||||
index = 0
|
index = 0
|
||||||
for key, value in self.languages.items():
|
for key, value in self.languages.items():
|
||||||
i, count = 0, locales.count(key)
|
i, count = 0, locales.count(key)
|
||||||
@ -122,14 +127,15 @@ class QLocaleXmlReader (object):
|
|||||||
index += count
|
index += count
|
||||||
yield i, value[0]
|
yield i, value[0]
|
||||||
|
|
||||||
def likelyMap(self):
|
def likelyMap(self) -> Iterator[tuple[str, tuple[int, int, int], str, tuple[int, int, int]]]:
|
||||||
def tag(t):
|
def tag(t: tuple[tuple[int, str], tuple[int, str], tuple[int, str]]) -> Iterator[str]:
|
||||||
lang, script, land = t
|
lang, script, land = t
|
||||||
yield lang[1] if lang[0] else 'und'
|
yield lang[1] if lang[0] else 'und'
|
||||||
if script[0]: yield script[1]
|
if script[0]: yield script[1]
|
||||||
if land[0]: yield land[1]
|
if land[0]: yield land[1]
|
||||||
|
|
||||||
def ids(t):
|
def ids(t: tuple[tuple[int, str], tuple[int, str], tuple[int, str]]
|
||||||
|
) -> tuple[int, int, int]:
|
||||||
return tuple(x[0] for x in t)
|
return tuple(x[0] for x in t)
|
||||||
|
|
||||||
for pair in self.__likely:
|
for pair in self.__likely:
|
||||||
@ -151,7 +157,7 @@ class QLocaleXmlReader (object):
|
|||||||
self.__textByName[give[1]][0]),
|
self.__textByName[give[1]][0]),
|
||||||
self.__landByName[give[2]][0])
|
self.__landByName[give[2]][0])
|
||||||
|
|
||||||
def enumify(self, name, suffix):
|
def enumify(self, name: str, suffix: str) -> str:
|
||||||
"""Stick together the parts of an enumdata.py name.
|
"""Stick together the parts of an enumdata.py name.
|
||||||
|
|
||||||
Names given in enumdata.py include spaces and hyphens that we
|
Names given in enumdata.py include spaces and hyphens that we
|
||||||
@ -178,17 +184,21 @@ class QLocaleXmlReader (object):
|
|||||||
return name
|
return name
|
||||||
|
|
||||||
# Implementation details:
|
# Implementation details:
|
||||||
def __loadMap(self, category, enum):
|
def __loadMap(self, category: str, enum: dict[int, tuple[str, str]]
|
||||||
|
) -> Iterator[tuple[int, str, str, str]]:
|
||||||
kid = self.__firstChildText
|
kid = self.__firstChildText
|
||||||
for element in self.__eachEltInGroup(self.root, f'{category}List', category):
|
for element in self.__eachEltInGroup(self.root, f'{category}List', category):
|
||||||
key = int(kid(element, 'id'))
|
key = int(kid(element, 'id'))
|
||||||
yield key, enum[key][0], kid(element, 'code'), kid(element, 'name')
|
yield key, enum[key][0], kid(element, 'code'), kid(element, 'name')
|
||||||
|
|
||||||
def __likelySubtagsMap(self):
|
# Likely subtag management:
|
||||||
def triplet(element, keys=('language', 'script', 'territory'), kid = self.__firstChildText):
|
def __likelySubtagsMap(self) -> Iterator[tuple[tuple[int, int, int], tuple[int, int, int]]]:
|
||||||
|
def triplet(element: minidom.Element,
|
||||||
|
keys: tuple[str, str, str]=('language', 'script', 'territory'),
|
||||||
|
kid = self.__firstChildText) -> tuple[str, str, str]:
|
||||||
return tuple(kid(element, key) for key in keys)
|
return tuple(kid(element, key) for key in keys)
|
||||||
|
|
||||||
kid = self.__firstChildElt
|
kid: Callable[[minidom.Element, str], minidom.Element] = self.__firstChildElt
|
||||||
for elt in self.__eachEltInGroup(self.root, 'likelySubtags', 'likelySubtag'):
|
for elt in self.__eachEltInGroup(self.root, 'likelySubtags', 'likelySubtag'):
|
||||||
yield triplet(kid(elt, "from")), triplet(kid(elt, "to"))
|
yield triplet(kid(elt, "from")), triplet(kid(elt, "to"))
|
||||||
|
|
||||||
@ -198,17 +208,18 @@ class QLocaleXmlReader (object):
|
|||||||
# DOM access:
|
# DOM access:
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __parse(filename, read = minidom.parse):
|
def __parse(filename: str, read = minidom.parse) -> minidom.Element:
|
||||||
return read(filename).documentElement
|
return read(filename).documentElement
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __isNodeNamed(elt, name, TYPE=minidom.Node.ELEMENT_NODE):
|
def __isNodeNamed(elt: minidom.Element|minidom.Text, name: str,
|
||||||
|
TYPE: int = minidom.Node.ELEMENT_NODE) -> bool:
|
||||||
return elt.nodeType == TYPE and elt.nodeName == name
|
return elt.nodeType == TYPE and elt.nodeName == name
|
||||||
del minidom
|
del minidom
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __eltWords(elt):
|
def __eltWords(elt: minidom.Element) -> Iterator[str]:
|
||||||
child = elt.firstChild
|
child: minidom.Text|minidom.CDATASection|None = elt.firstChild
|
||||||
while child:
|
while child:
|
||||||
if child.nodeType == elt.TEXT_NODE:
|
if child.nodeType == elt.TEXT_NODE:
|
||||||
# Note: do not strip(), as some group separators are
|
# Note: do not strip(), as some group separators are
|
||||||
@ -217,8 +228,8 @@ class QLocaleXmlReader (object):
|
|||||||
child = child.nextSibling
|
child = child.nextSibling
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __firstChildElt(cls, parent, name):
|
def __firstChildElt(cls, parent: minidom.Element, name: str) -> minidom.Element:
|
||||||
child = parent.firstChild
|
child: minidom.Text|minidom.Element = parent.firstChild
|
||||||
while child:
|
while child:
|
||||||
if cls.__isNodeNamed(child, name):
|
if cls.__isNodeNamed(child, name):
|
||||||
return child
|
return child
|
||||||
@ -227,13 +238,14 @@ class QLocaleXmlReader (object):
|
|||||||
raise Error(f'No {name} child found')
|
raise Error(f'No {name} child found')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __firstChildText(cls, elt, key):
|
def __firstChildText(cls, elt: minidom.Element, key: str) -> str:
|
||||||
return ' '.join(cls.__eltWords(cls.__firstChildElt(elt, key)))
|
return ' '.join(cls.__eltWords(cls.__firstChildElt(elt, key)))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __eachEltInGroup(cls, parent, group, key):
|
def __eachEltInGroup(cls, parent: minidom.Element, group: str, key: str
|
||||||
|
) -> Iterator[minidom.Element]:
|
||||||
try:
|
try:
|
||||||
element = cls.__firstChildElt(parent, group).firstChild
|
element: minidom.Element = cls.__firstChildElt(parent, group).firstChild
|
||||||
except Error:
|
except Error:
|
||||||
element = None
|
element = None
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user