From dd698dcb4d14ec59fdd60416018b15e43438ecfe Mon Sep 17 00:00:00 2001 From: Mate Barany Date: Thu, 19 Sep 2024 17:28:20 +0200 Subject: [PATCH] Add type hints to LocaleSourceEditor and TimeZoneDataWriter Task-number: QTBUG-128634 Pick-to: 6.8 Change-Id: I5dabb5e721b610bc9edb01b86aa173d03c36a48a Reviewed-by: Edward Welbourne --- util/locale_database/qlocalexml2cpp.py | 98 ++++++++++++++------------ 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/util/locale_database/qlocalexml2cpp.py b/util/locale_database/qlocalexml2cpp.py index d77403ef95d..17cf5c80f5d 100755 --- a/util/locale_database/qlocalexml2cpp.py +++ b/util/locale_database/qlocalexml2cpp.py @@ -19,7 +19,7 @@ import argparse from pathlib import Path from typing import Callable, Iterator, Optional -from qlocalexml import QLocaleXmlReader +from qlocalexml import Locale, QLocaleXmlReader from localetools import * from iso639_3 import LanguageCodeData from zonedata import utcIdList, windowsIdList @@ -173,7 +173,7 @@ def currencyIsoCodeData(s: str) -> str: return "{0,0,0}" class LocaleSourceEditor (SourceFileEditor): - def __init__(self, path: Path, temp: Path, version: str): + def __init__(self, path: Path, temp: Path, version: str) -> None: super().__init__(path, temp) self.version = version @@ -194,54 +194,58 @@ class LocaleSourceEditor (SourceFileEditor): """) class TimeZoneDataWriter (LocaleSourceEditor): - def __init__(self, path: Path, temp: Path, version: str): + def __init__(self, path: Path, temp: Path, version: str) -> None: super().__init__(path, temp, version) self.__ianaTable = ByteArrayData() # Single IANA IDs self.__ianaListTable = ByteArrayData() # Space-joined lists of IDs self.__windowsTable = ByteArrayData() # Windows names for zones self.__metaIdData = ByteArrayData() # Metazone names - self.__windowsList = sorted(windowsIdList, - key=lambda p: p[0].lower()) - self.windowsKey = {name: (key, off) for key, (name, off) - in enumerate(self.__windowsList, 1)} + self.__windowsList: list[tuple[str, int]] = sorted(windowsIdList, + key=lambda p: p[0].lower()) + self.windowsKey: dict[str, tuple[int, int]] = {name: (key, off) for key, (name, off) + in enumerate(self.__windowsList, 1)} from enumdata import territory_map - self.__landKey = {code: (i, name) for i, (name, code) in territory_map.items()} + self.__landKey: dict[str, tuple[int, str]] = {code: (i, name) for i, (name, code) + in territory_map.items()} - def utcTable(self): - offsetMap, out = {}, self.writer.write + def utcTable(self) -> None: + offsetMap: dict[int, tuple[str, ...]] = {} + out: Callable[[str], int] = self.writer.write for name in utcIdList: - offset = self.__offsetOf(name) + offset: int = self.__offsetOf(name) offsetMap[offset] = offsetMap.get(offset, ()) + (name,) # Write UTC ID key table out('\n// IANA List Index, UTC Offset\n') out('static constexpr UtcData utcDataTable[] = {\n') for offset in sorted(offsetMap.keys()): # Sort so C++ can binary-chop. - names = offsetMap[offset]; - joined = self.__ianaListTable.append(' '.join(names)) + names: tuple[str, ...] = offsetMap[offset] + joined: int = self.__ianaListTable.append(' '.join(names)) out(f' {{ {joined:6d},{offset:6d} }}, // {names[0]}\n') out('};\n') - def aliasToIana(self, pairs): - out, store = self.writer.write, self.__ianaTable.append + def aliasToIana(self, pairs: Iterator[tuple[str, str]]) -> None: + out: Callable[[str], int] = self.writer.write + store: Callable[[str], int] = self.__ianaTable.append out('// IANA ID indices of alias and IANA ID\n') out('static constexpr AliasData aliasMappingTable[] = {\n') for name, iana in pairs: # They're ready-sorted - assert name != iana, (alias, iana) # Filtered out in QLocaleXmlWriter + assert name != iana, (name, iana) # Filtered out in QLocaleXmlWriter out(f' {{ {store(name):6d},{store(iana):6d} }},' f' // {name} -> {iana}\n') out('};\n\n') - def territoryZone(self, pairs): + def territoryZone(self, pairs: Iterator[tuple[str, str]]) -> None: self.__beginNonIcuFeatureTZL() - out, store = self.writer.write, self.__ianaTable.append - landKey = self.__landKey - seq = sorted((landKey[code][0], iana, landKey[code][1]) - for code, iana in pairs) + out: Callable[[str], int] = self.writer.write + store: Callable[[str], int] = self.__ianaTable.append + landKey: dict[str, tuple[int, str]] = self.__landKey + seq: list[tuple[int, str, str]] = sorted((landKey[code][0], iana, landKey[code][1]) + for code, iana in pairs) # Write territory-to-zone table out('\n// QLocale::Territory value, IANA ID Index\n') out('static constexpr TerritoryZone territoryZoneMap[] = {\n') @@ -252,13 +256,15 @@ class TimeZoneDataWriter (LocaleSourceEditor): # self.__endNonIcuFeatureTZL() - def metaLandZone(self, quads): + def metaLandZone(self, quads: Iterator[tuple[str, int, str, str]]) -> None: # self.__beginNonIcuFeatureTZL() - out, metaStore = self.writer.write, self.__metaIdData.append - ianaStore = self.__ianaTable.append - landKey = self.__landKey - seq = sorted((metaKey, landKey[land][0], meta, landKey[land][1], iana) - for meta, metaKey, land, iana in quads) + out: Callable[[str], int] = self.writer.write + metaStore: Callable[[str], int] = self.__metaIdData.append + ianaStore: Callable[[str], int] = self.__ianaTable.append + landKey: dict[str, tuple[int, str]] = self.__landKey + seq: list[tuple[int, int, str, str, str]] = sorted( + (metaKey, landKey[land][0], meta, landKey[land][1], iana) + for meta, metaKey, land, iana in quads) # Write (metazone, territory, zone) table out('\n// MetaZone Key, MetaZone Name Index, ' @@ -272,10 +278,11 @@ class TimeZoneDataWriter (LocaleSourceEditor): # self.__endNonIcuFeatureTZL() - def zoneMetaStory(self, quads): + def zoneMetaStory(self, quads: Iterator[tuple[str, int, int, int]]) -> None: # self.__beginNonIcuFeatureTZL() - out, store = self.writer.write, self.__ianaTable.append + out: Callable[[str], int] = self.writer.write + store: Callable[[str], int] = self.__ianaTable.append # Write (zone, metazone key, begin, end) table: out('\n// IANA ID Index, MetaZone Key, interval start, end\n') @@ -287,10 +294,11 @@ class TimeZoneDataWriter (LocaleSourceEditor): self.__endNonIcuFeatureTZL() - def msToIana(self, pairs): - out, winStore = self.writer.write, self.__windowsTable.append - ianaStore = self.__ianaTable.append - alias = dict(pairs) # {MS name: IANA ID} + def msToIana(self, pairs: Iterator[tuple[str, str]]) -> None: + out: Callable[[str], int] = self.writer.write + winStore: Callable[[str], int] = self.__windowsTable.append + ianaStore: Callable[[str], int] = self.__ianaTable.append + alias: dict[str, str] = dict(pairs) # {MS name: IANA ID} assert all(not any(x.isspace() for x in iana) for iana in alias.values()) out('\n// Windows ID Key, Windows ID Index, IANA ID Index, UTC Offset\n') @@ -302,12 +310,14 @@ class TimeZoneDataWriter (LocaleSourceEditor): f'{ianaStore(alias[name]):6d},{offset:6d} }}, // {name}\n') out('};\n') - def msLandIanas(self, triples): # (MS name, territory code, IANA list) - out, store = self.writer.write, self.__ianaListTable.append - landKey = self.__landKey - seq = sorted((self.windowsKey[name][0], landKey[land][0], - name, landKey[land][1], ianas) - for name, land, ianas in triples) + def msLandIanas(self, triples: Iterator[tuple[str, str, str]]) -> None: + # triples (MS name, territory code, IANA list) + out: Callable[[str], int] = self.writer.write + store: Callable[[str], int] = self.__ianaListTable.append + landKey: dict[str, tuple[int, str]] = self.__landKey + seq: list[tuple[int, int, str, str, str]] = sorted( + (self.windowsKey[name][0], landKey[land][0], name, landKey[land][1], ianas) + for name, land, ianas in triples) out('// Windows ID Key, Territory Enum, IANA List Index\n') out('static constexpr ZoneData zoneDataTable[] = {\n') @@ -317,7 +327,7 @@ class TimeZoneDataWriter (LocaleSourceEditor): f' // {name} / {land}\n') out('};\n') - def nameTables(self, locales): + def nameTables(self, locales: Iterator[Locale]) -> tuple[ByteArrayData, ByteArrayData]: """Ensure all zone and metazone names used by locales are known Must call before writeTables(), to ensure zone and metazone naming @@ -340,7 +350,7 @@ class TimeZoneDataWriter (LocaleSourceEditor): self.__metaIdData.append(k) return self.__ianaTable, self.__metaIdData - def writeTables(self): + def writeTables(self) -> None: self.__windowsTable.write(self.writer.write, 'windowsIdData') self.__ianaListTable.write(self.writer.write, 'ianaListData') self.__ianaTable.write(self.writer.write, 'ianaIdData') @@ -350,13 +360,13 @@ class TimeZoneDataWriter (LocaleSourceEditor): self.writer.write('\n') # Implementation details: - def __beginNonIcuFeatureTZL(self): + def __beginNonIcuFeatureTZL(self) -> None: self.writer.write('\n#if QT_CONFIG(timezone_locale) && !QT_CONFIG(icu)\n') - def __endNonIcuFeatureTZL(self): + def __endNonIcuFeatureTZL(self) -> None: self.writer.write('\n#endif // timezone_locale but not ICU\n') @staticmethod - def __offsetOf(utcName): + def __offsetOf(utcName: str) -> int: "Maps a UTC±HH:mm name to its offset in seconds" assert utcName.startswith('UTC') if len(utcName) == 3: