locale_database: Use f-strings in Python code

Replace most uses of str.format() and string arithmetic by f-strings.
This results in more compact code and the code is easier to read
when using an appropriate editor.

Task-number: QTBUG-83488
Pick-to: 6.2
Change-Id: I3409f745b5d0324985cbd5690f5eda8d09b869ca
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Ievgenii Meshcheriakov 2021-07-06 16:22:07 +02:00
parent 65a0e04072
commit 41458fafa0
6 changed files with 131 additions and 140 deletions

View File

@ -79,7 +79,7 @@ class CldrReader (object):
and e.message.startswith('Unknown ') and ' code ' in e.message):
skips.append(use)
else:
self.grumble('Skipping likelySubtag "{}" -> "{}" ({})\n'.format(got, use, e.message))
self.grumble(f'Skipping likelySubtag "{got}" -> "{use}" ({e})\n')
continue
if all(code.startswith('Any') and code[3].isupper() for code in have[:-1]):
continue
@ -105,7 +105,7 @@ class CldrReader (object):
def __allLocales(self, calendars):
def skip(locale, reason):
return 'Skipping defaultContent locale "{}" ({})\n'.format(locale, reason)
return f'Skipping defaultContent locale "{locale}" ({reason})\n'
for locale in self.root.defaultContentLocales:
try:
@ -142,7 +142,7 @@ class CldrReader (object):
continue
yield self.__getLocaleData(chain, calendars, language, script, territory, variant)
except Error as e:
self.grumble('Skipping file locale "{}" ({})\n'.format(locale, e.message))
self.grumble(f'Skipping file locale "{locale}" ({e})\n')
import textwrap
@staticmethod
@ -209,7 +209,7 @@ class CldrReader (object):
rest.extend(tags)
if rest:
self.grumble('Ignoring unparsed cruft {} in {}\n'.format('_'.join(rest), name))
self.grumble(f'Ignoring unparsed cruft {"_".join(rest)} in {name}\n')
def __getLocaleData(self, scan, calendars, language, script, territory, variant):
ids, names = zip(*self.root.codesToIdName(language, script, territory, variant))
@ -315,7 +315,7 @@ class CldrAccess (object):
try:
return self.__numberSystems[system]
except KeyError:
raise Error('Unsupported number system: {}'.format(system))
raise Error(f'Unsupported number system: {system}')
def weekData(self, territory):
"""Data on the weekly cycle.
@ -368,10 +368,10 @@ class CldrAccess (object):
naming, enums = self.__codeMap(key), enum(key)
value = values[index]
if value not in enums:
text = '{} code {}'.format(key, value)
text = f'{key} code {value}'
name = naming.get(value)
if name and value != 'POSIX':
text += ' (could add {})'.format(name)
text += f' (could add {name})'
parts.append(text)
if len(parts) > 1:
parts[-1] = 'and ' + parts[-1]
@ -392,7 +392,7 @@ class CldrAccess (object):
# No en.xml name for this code, but supplementalData's
# parentLocale may still believe in it:
if code not in scraps:
yield name, '[Found no CLDR name for code {}]'.format(code)
yield name, f'[Found no CLDR name for code {code}]'
continue
if name == right: continue
ok = right.replace('&', 'And')
@ -429,15 +429,15 @@ enumdata.py (keeping the old name as an alias):
""")
if lang:
grumble('Language:\n\t'
+ '\n\t'.join('{} -> {}'.format(k, v) for k, v in lang.items())
+ '\n\t'.join(f'{k} -> {v}' for k, v in lang.items())
+ '\n')
if land:
grumble('Territory:\n\t'
+ '\n\t'.join('{} -> {}'.format(k, v) for k, v in land.items())
+ '\n\t'.join(f'{k} -> {v}' for k, v in land.items())
+ '\n')
if text:
grumble('Script:\n\t'
+ '\n\t'.join('{} -> {}'.format(k, v) for k, v in text.items())
+ '\n\t'.join(f'{k} -> {v}' for k, v in text.items())
+ '\n')
grumble('\n')
@ -568,7 +568,7 @@ enumdata.py (keeping the old name as an alias):
source = self.__supplementalData
for key in ('firstDay', 'weekendStart', 'weekendEnd'):
result = {}
for ignore, attrs in source.find('weekData/' + key):
for ignore, attrs in source.find(f'weekData/{key}'):
assert ignore == key
day = attrs['day']
assert day in ('mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'), day
@ -601,7 +601,7 @@ enumdata.py (keeping the old name as an alias):
break
if iso:
for tag, data in source.find(
'currencyData/fractions/info[iso4217={}]'.format(iso)):
f'currencyData/fractions/info[iso4217={iso}]'):
digits = data['digits']
rounding = data['rounding']
cache[territory] = iso, digits, rounding
@ -745,7 +745,7 @@ enumdata.py (keeping the old name as an alias):
def __localeAsDoc(self, name, aliasFor = None,
joinPath = os.path.join, exists = os.path.isfile):
path = ('common', 'main', name + '.xml')
path = ('common', 'main', f'{name}.xml')
if exists(joinPath(self.root, *path)):
elt = self.__xml(path)
for child in Node(elt).findAllChildren('alias'):
@ -759,8 +759,8 @@ enumdata.py (keeping the old name as an alias):
return elt
if aliasFor:
raise Error('Fatal error: found an alias "{}" -> "{}", but found no file for the alias'
.format(aliasFor, name))
raise Error(f'Fatal error: found an alias "{aliasFor}" -> "{name}", '
'but found no file for the alias')
def __scanLocaleRoots(self, name):
while name and name != 'root':

View File

@ -61,10 +61,10 @@ from cldr import CldrReader
from qlocalexml import QLocaleXmlWriter
def usage(name, err, message = ''):
err.write("""Usage: {} path/to/cldr/common/main [out-file.xml]
""".format(name)) # TODO: expand command-line, improve help message
err.write(f"""Usage: {name} path/to/cldr/common/main [out-file.xml]
""") # TODO: expand command-line, improve help message
if message:
err.write('\n' + message + '\n')
err.write(f'\n{message}\n')
def main(args, out, err):
# TODO: make calendars a command-line option
@ -78,22 +78,21 @@ def main(args, out, err):
root = args.pop(0)
if not os.path.exists(os.path.join(root, 'common', 'main', 'root.xml')):
usage(name, err,
'First argument is the root of the CLDR tree: found no common/main/root.xml under '
+ root)
usage(name, err, 'First argument is the root of the CLDR tree: '
f'found no common/main/root.xml under {root}')
return 1
xml = args.pop(0) if args else None
if not xml or xml == '-':
emit = out
elif not xml.endswith('.xml'):
usage(name, err, 'Please use a .xml extension on your output file name, not ' + xml)
usage(name, err, f'Please use a .xml extension on your output file name, not {xml}')
return 1
else:
try:
emit = open(xml, 'w')
except IOError as e:
usage(name, err, 'Failed to open "{}" to write output to it\n'.format(xml))
usage(name, err, f'Failed to open "{xml}" to write output to it\n')
return 1
if args:

View File

@ -255,13 +255,13 @@ class ByteArrayData:
lst = unicode2hex(s)
index = len(self.data)
if index > 0xffff:
raise Error('Index ({}) outside the uint16 range !'.format(index))
raise Error(f'Index ({index}) outside the uint16 range !')
self.hash[s] = index
self.data += lst
return index
def write(self, out, name):
out('\nstatic const char {}[] = {{\n'.format(name))
out(f'\nstatic const char {name}[] = {{\n')
out(wrap_list(self.data))
out('\n};\n')
@ -273,10 +273,10 @@ class ZoneIdWriter (SourceFileEditor):
iana.write(self.writer.write, 'ianaIdData')
def __writeWarning(self, version):
self.writer.write("""
self.writer.write(f"""
/*
This part of the file was generated on {} from the
Common Locale Data Repository v{} file supplemental/windowsZones.xml
This part of the file was generated on {datetime.date.today()} from the
Common Locale Data Repository v{version} file supplemental/windowsZones.xml
http://www.unicode.org/cldr/
@ -284,7 +284,7 @@ class ZoneIdWriter (SourceFileEditor):
edited) CLDR data; see qtbase/util/locale_database/.
*/
""".format(str(datetime.date.today()), version))
""")
@staticmethod
def __writeTables(out, defaults, windowsIds):
@ -325,10 +325,10 @@ class ZoneIdWriter (SourceFileEditor):
return windowsIdData, ianaIdData
def usage(err, name, message=''):
err.write("""Usage: {} path/to/cldr/root path/to/qtbase
""".format(name)) # TODO: more interesting message
err.write(f"""Usage: {name} path/to/cldr/root path/to/qtbase
""") # TODO: more interesting message
if message:
err.write('\n' + message + '\n')
err.write(f'\n{message}\n')
def main(args, out, err):
"""Parses CLDR's data and updates Qt's representation of it.
@ -347,15 +347,15 @@ def main(args, out, err):
qtPath = args.pop(0)
if not os.path.isdir(qtPath):
usage(err, name, "No such Qt directory: " + qtPath)
usage(err, name, f"No such Qt directory: {qtPath}")
return 1
if not os.path.isdir(cldrPath):
usage(err, name, "No such CLDR directory: " + cldrPath)
usage(err, name, f"No such CLDR directory: {cldrPath}")
return 1
dataFilePath = os.path.join(qtPath, 'src', 'corelib', 'time', 'qtimezoneprivate_data_p.h')
if not os.path.isfile(dataFilePath):
usage(err, name, 'No such file: ' + dataFilePath)
usage(err, name, f'No such file: {dataFilePath}')
return 1
try:
@ -363,11 +363,11 @@ def main(args, out, err):
dict((name, ind) for ind, name in enumerate((x[0] for x in windowsIdList), 1)))
except IOError as e:
usage(err, name,
'Failed to open common/supplemental/windowsZones.xml: ' + str(e))
f'Failed to open common/supplemental/windowsZones.xml: {e}')
return 1
except Error as e:
err.write('\n'.join(textwrap.wrap(
'Failed to read windowsZones.xml: ' + (e.message or e.args[1]),
f'Failed to read windowsZones.xml: {e}',
subsequent_indent=' ', width=80)) + '\n')
return 1
@ -375,18 +375,18 @@ def main(args, out, err):
try:
writer = ZoneIdWriter(dataFilePath, qtPath)
except IOError as e:
err.write('Failed to open files to transcribe: {}'.format(e))
err.write(f'Failed to open files to transcribe: {e}')
return 1
try:
writer.write(version, defaults, winIds)
except Error as e:
writer.cleanup()
err.write('\nError in Windows ID data: ' + e.message + '\n')
err.write(f'\nError in Windows ID data: {e}\n')
return 1
writer.close()
out.write('Data generation completed, please check the new file at ' + dataFilePath + '\n')
out.write(f'Data generation completed, please check the new file at {dataFilePath}\n')
return 0
if __name__ == '__main__':

View File

@ -241,7 +241,7 @@ class LocaleScanner (object):
except (KeyError, AttributeError):
pass
else:
raise Error('Alias to {}'.format(source))
raise Error(f'Alias to {source}')
ids = root.findUniqueChild('identity')
for code in ('language', 'script', 'territory', 'variant'):
@ -263,8 +263,8 @@ class LocaleScanner (object):
includes some currency formats.
"""
if isoCode:
stem = 'numbers/currencies/currency[{}]/'.format(isoCode)
symbol = self.find(stem + 'symbol', '')
stem = f'numbers/currencies/currency[{isoCode}]/'
symbol = self.find(f'{stem}symbol', '')
name = self.__currencyDisplayName(stem)
else:
symbol = name = ''
@ -279,15 +279,15 @@ class LocaleScanner (object):
we expect this to have 'digits' as a key.
"""
system = self.find('numbers/defaultNumberingSystem')
stem = 'numbers/symbols[numberSystem={}]/'.format(system)
decimal = self.find(stem + 'decimal')
group = self.find(stem + 'group')
stem = f'numbers/symbols[numberSystem={system}]/'
decimal = self.find(f'{stem}decimal')
group = self.find(f'{stem}group')
assert decimal != group, (self.name, system, decimal)
yield 'decimal', decimal
yield 'group', group
yield 'percent', self.find(stem + 'percentSign')
yield 'list', self.find(stem + 'list')
yield 'exp', self.find(stem + 'exponential')
yield 'percent', self.find(f'{stem}percentSign')
yield 'list', self.find(f'{stem}list')
yield 'exp', self.find(f'{stem}exponential')
yield 'groupSizes', self.__numberGrouping(system)
digits = lookup(system)['digits']
@ -299,8 +299,8 @@ class LocaleScanner (object):
for i, c in enumerate(digits[1:], 1))
yield 'zero', zero
plus = self.find(stem + 'plusSign')
minus = self.find(stem + 'minusSign')
plus = self.find(f'{stem}plusSign')
minus = self.find(f'{stem}minusSign')
yield 'plus', plus
yield 'minus', minus
@ -308,7 +308,7 @@ class LocaleScanner (object):
xpath = 'numbers/currencyFormats/currencyFormatLength/currencyFormat[accounting]/pattern'
try:
money = self.find(xpath.replace('Formats/',
'Formats[numberSystem={}]/'.format(system)))
f'Formats[numberSystem={system}]/'))
except Error:
money = self.find(xpath)
money = self.__currencyFormats(money, plus, minus)
@ -322,12 +322,12 @@ class LocaleScanner (object):
def textPatternData(self):
for key in ('quotationStart', 'alternateQuotationEnd',
'quotationEnd', 'alternateQuotationStart'):
yield key, self.find('delimiters/' + key)
yield key, self.find(f'delimiters/{key}')
for key in ('start', 'middle', 'end'):
yield ('listPatternPart' + key.capitalize(),
yield (f'listPatternPart{key.capitalize()}',
self.__fromLdmlListPattern(self.find(
'listPatterns/listPattern/listPatternPart[{}]'.format(key))))
f'listPatterns/listPattern/listPatternPart[{key}]')))
yield ('listPatternPartTwo',
self.__fromLdmlListPattern(self.find(
'listPatterns/listPattern/listPatternPart[2]')))
@ -335,17 +335,16 @@ class LocaleScanner (object):
stem = 'dates/calendars/calendar[gregorian]/'
# TODO: is wide really the right width to use here ?
# abbreviated might be an option ... or try both ?
meridiem = stem + 'dayPeriods/dayPeriodContext[format]/dayPeriodWidth[wide]/'
meridiem = f'{stem}dayPeriods/dayPeriodContext[format]/dayPeriodWidth[wide]/'
for key in ('am', 'pm'):
yield key, self.find(meridiem + 'dayPeriod[{}]'.format(key),
yield key, self.find(f'{meridiem}dayPeriod[{key}]',
draft = Node.draftScore('contributed'))
for pair in (('long', 'full'), ('short', 'short')):
for key in ('time', 'date'):
yield (pair[0] + key.capitalize() + 'Format',
yield (f'{pair[0]}{key.capitalize()}Format',
convert_date(self.find(
stem + '{}Formats/{}FormatLength[{}]/{}Format/pattern'.format(
key, key, pair[1], key))))
f'{stem}{key}Formats/{key}FormatLength[{pair[1]}]/{key}Format/pattern')))
def endonyms(self, language, script, territory, variant):
# TODO: take variant into account ?
@ -355,8 +354,7 @@ class LocaleScanner (object):
continue
try:
yield ('languageEndonym',
self.find('localeDisplayNames/languages/language[{}]'
.format('_'.join(seq))))
self.find(f'localeDisplayNames/languages/language[{"_".join(seq)}]'))
except Error:
pass
else:
@ -366,8 +364,7 @@ class LocaleScanner (object):
yield 'languageEndonym', ''
yield ('territoryEndonym',
self.find('localeDisplayNames/territories/territory[{}]'
.format(territory), ''))
self.find(f'localeDisplayNames/territories/territory[{territory}]', ''))
def unitData(self):
yield ('byte_unit',
@ -386,20 +383,20 @@ class LocaleScanner (object):
def calendarNames(self, calendars):
namings = self.__nameForms
for cal in calendars:
stem = 'dates/calendars/calendar[' + cal + ']/months/'
stem = f'dates/calendars/calendar[{cal}]/months/'
for key, mode, size in namings:
prop = 'monthContext[' + mode + ']/monthWidth[' + size + ']/'
yield (key + 'Months_' + cal,
';'.join(self.find(stem + prop + 'month[{}]'.format(i))
prop = f'monthContext[{mode}]/monthWidth[{size}]/'
yield (f'{key}Months_{cal}',
';'.join(self.find(f'{stem}{prop}month[{i}]')
for i in range(1, 13)))
# Day data (for Gregorian, at least):
stem = 'dates/calendars/calendar[gregorian]/days/'
days = ('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat')
for (key, mode, size) in namings:
prop = 'dayContext[' + mode + ']/dayWidth[' + size + ']/day'
yield (key + 'Days',
';'.join(self.find(stem + prop + '[' + day + ']')
prop = f'dayContext[{mode}]/dayWidth[{size}]/day'
yield (f'{key}Days',
';'.join(self.find(f'{stem}{prop}[{day}]')
for day in days))
# Implementation details
@ -444,9 +441,8 @@ class LocaleScanner (object):
break
sought = '/'.join(tags)
if sought != xpath:
sought += ' (for {})'.format(xpath)
raise Error('All lack child {} for {} in {}'.format(
selector, sought, self.name))
sought += f' (for {xpath})'
raise Error(f'All lack child {selector} for {sought} in {self.name}')
else: # Found matching elements
for elt in roots:
@ -454,8 +450,8 @@ class LocaleScanner (object):
sought = '/'.join(tags)
if sought != xpath:
sought += ' (for {})'.format(xpath)
raise Error('No {} in {}'.format(sought, self.name))
sought += f' (for {xpath})'
raise Error(f'No {sought} in {self.name}')
def __currencyDisplayName(self, stem):
try:
@ -464,7 +460,7 @@ class LocaleScanner (object):
pass
for x in ('zero', 'one', 'two', 'few', 'many', 'other'):
try:
return self.find(stem + 'displayName[count={}]'.format(x))
return self.find(f'{stem}displayName[count={x}]')
except Error:
pass
return ''
@ -474,10 +470,10 @@ class LocaleScanner (object):
# (even for unitLength[narrow]) instead of kB (etc.), so
# prefer any unitPattern provided, but prune its placeholder:
for size in ('short', 'narrow'): # TODO: reverse order ?
stem = 'units/unitLength[{}]/unit[digital-{}byte]/'.format(size + keySuffix, quantify)
stem = f'units/unitLength[{size}{keySuffix}]/unit[digital-{quantify}byte]/'
for count in ('many', 'few', 'two', 'other', 'zero', 'one'):
try:
ans = self.find(stem + 'unitPattern[count={}]'.format(count))
ans = self.find(f'{stem}unitPattern[count={count}]')
except Error:
continue
@ -490,7 +486,7 @@ class LocaleScanner (object):
return ans
try:
return self.find(stem + 'displayName')
return self.find(f'{stem}displayName')
except Error:
pass
@ -518,10 +514,10 @@ class LocaleScanner (object):
if cache:
byte = cache.pop()
if all(byte == k for k in cache):
suffix = 'i' + byte
suffix = f'i{byte}'
for q in siQuantifiers:
# Those don't (yet, v36) exist in CLDR, so we always get the fall-back:
yield self.__findUnit(keySuffix, q[:2], q[0].upper() + suffix)
yield self.__findUnit(keySuffix, q[:2], f'{q[0].upper()}{suffix}')
else: # first call
tail = suffix = suffix or 'B'
for q in siQuantifiers:
@ -556,8 +552,8 @@ class LocaleScanner (object):
elsewhere)."""
top = int(self.find('numbers/minimumGroupingDigits'))
assert top < 4, top # We store it in a 2-bit field
grouping = self.find('numbers/decimalFormats[numberSystem='
+ system + ']/decimalFormatLength/decimalFormat/pattern')
grouping = self.find(f'numbers/decimalFormats[numberSystem={system}]/'
'decimalFormatLength/decimalFormat/pattern')
groups = grouping.split('.')[0].split(',')[-3:]
assert all(len(x) < 8 for x in groups[-2:]), grouping # we store them in 3-bit fields
if len(groups) > 2:

View File

@ -59,7 +59,7 @@ def camelCase(words):
return ''.join(camel(iter(words)))
def addEscapes(s):
return ''.join(c if n < 128 else '\\x{:02x}'.format(n)
return ''.join(c if n < 128 else f'\\x{n:02x}'
for n, c in ((ord(c), c) for c in s))
def startCount(c, text): # strspn
@ -154,7 +154,7 @@ class QLocaleXmlReader (object):
if language != 1: # C
if territory == 0:
grumble('loadLocaleMap: No territory id for "{}"\n'.format(locale.language))
grumble(f'loadLocaleMap: No territory id for "{locale.language}"\n')
if script == 0:
# Find default script for the given language and territory - see:
@ -213,7 +213,7 @@ class QLocaleXmlReader (object):
# Implementation details:
def __loadMap(self, category):
kid = self.__firstChildText
for element in self.__eachEltInGroup(self.root, category + 'List', category):
for element in self.__eachEltInGroup(self.root, f'{category}List', category):
yield int(kid(element, 'id')), kid(element, 'name'), kid(element, 'code')
def __likelySubtagsMap(self):
@ -254,7 +254,7 @@ class QLocaleXmlReader (object):
return child
child = child.nextSibling
raise Error('No {} child found'.format(name))
raise Error(f'No {name} child found')
@classmethod
def __firstChildText(cls, elt, key):
@ -310,7 +310,7 @@ class Spacer (object):
elif line.startswith('<') and not line.startswith('<!'):
cut = line.find('>')
tag = (line[1:] if cut < 0 else line[1 : cut]).strip().split()[0]
if '</{}>'.format(tag) not in line:
if f'</{tag}>' not in line:
self.current += self.__each
return indent + line + '\n'
@ -378,7 +378,7 @@ class QLocaleXmlWriter (object):
self.inTag('version', cldrVersion)
def inTag(self, tag, text):
self.__write('<{0}>{1}</{0}>'.format(tag, text))
self.__write(f'<{tag}>{text}</{tag}>')
def close(self, grumble):
"""Finish writing and grumble any issues discovered."""
@ -390,7 +390,7 @@ class QLocaleXmlWriter (object):
grumble('Some enum members are unused, corresponding to these tags:\n')
import textwrap
def kvetch(kind, seq, g = grumble, w = textwrap.wrap):
g('\n\t'.join(w(' {}: '.format(kind) + ', '.join(sorted(seq)), width=80)) + '\n')
g('\n\t'.join(w(f' {kind}: {", ".join(sorted(seq))}', width=80)) + '\n')
if self.__languages:
kvetch('Languages', self.__languages)
if self.__scripts:
@ -408,14 +408,14 @@ class QLocaleXmlWriter (object):
raise Error('Attempted to write data after closing :-(')
def __enumTable(self, tag, table):
self.__openTag(tag + 'List')
self.__openTag(f'{tag}List')
for key, value in table.items():
self.__openTag(tag)
self.inTag('name', value[0])
self.inTag('id', key)
self.inTag('code', value[1])
self.__closeTag(tag)
self.__closeTag(tag + 'List')
self.__closeTag(f'{tag}List')
def __likelySubTag(self, tag, likely):
self.__openTag(tag)
@ -432,9 +432,9 @@ class QLocaleXmlWriter (object):
self.__territories.discard(locale.territory_code)
def __openTag(self, tag):
self.__write('<{}>'.format(tag))
self.__write(f'<{tag}>')
def __closeTag(self, tag):
self.__write('</{}>'.format(tag))
self.__write(f'</{tag}>')
def __write(self, line):
self.__rawOutput(self.__wrap(line))
@ -529,7 +529,7 @@ class Locale (object):
get = lambda k: getattr(self, k)
for key in ('language', 'script', 'territory'):
write(key, get(key))
write('{}code'.format(key), get('{}_code'.format(key)))
write(f'{key}code', get(f'{key}_code'))
for key in ('decimal', 'group', 'zero', 'list',
'percent', 'minus', 'plus', 'exp'):

View File

@ -66,9 +66,9 @@ class LocaleKeySorter:
class StringDataToken:
def __init__(self, index, length, bits):
if index > 0xffff:
raise ValueError('Start-index ({}) exceeds the uint16 range!'.format(index))
raise ValueError(f'Start-index ({index}) exceeds the uint16 range!')
if length >= (1 << bits):
raise ValueError('Data size ({}) exceeds the {}-bit range!'.format(length, bits))
raise ValueError(f'Data size ({length}) exceeds the {bits}-bit range!')
self.index = index
self.length = length
@ -120,10 +120,9 @@ class StringData:
def write(self, fd):
if len(self.data) > 0xffff:
raise ValueError('Data is too big ({}) for quint16 index to its end!'
.format(len(self.data)),
raise ValueError(f'Data is too big ({len(self.data)}) for quint16 index to its end!',
self.name)
fd.write("\nstatic const char16_t {}[] = {{\n".format(self.name))
fd.write(f"\nstatic const char16_t {self.name}[] = {{\n")
fd.write(wrap_list(self.data))
fd.write("\n};\n")
@ -135,10 +134,10 @@ def currencyIsoCodeData(s):
class LocaleSourceEditor (SourceFileEditor):
def __init__(self, path, temp, version):
super().__init__(path, temp)
self.writer.write("""
self.writer.write(f"""
/*
This part of the file was generated on {} from the
Common Locale Data Repository v{}
This part of the file was generated on {datetime.date.today()} from the
Common Locale Data Repository v{version}
http://www.unicode.org/cldr/
@ -147,7 +146,7 @@ class LocaleSourceEditor (SourceFileEditor):
edited) CLDR data; see qtbase/util/locale_database/.
*/
""".format(datetime.date.today(), version))
""")
class LocaleDataWriter (LocaleSourceEditor):
def likelySubtags(self, likely):
@ -170,13 +169,13 @@ class LocaleDataWriter (LocaleSourceEditor):
self.writer.write(' {{ {:3d}, {:3d}, {:3d} }}'.format(*have))
self.writer.write(', {{ {:3d}, {:3d}, {:3d} }}'.format(*give))
self.writer.write(' ' if i == len(likely) else ',')
self.writer.write(' // {} -> {}\n'.format(had, got))
self.writer.write(f' // {had} -> {got}\n')
self.writer.write('};\n\n')
def localeIndex(self, indices):
self.writer.write('static const quint16 locale_index[] = {\n')
for pair in indices:
self.writer.write('{:6d}, // {}\n'.format(*pair))
for index, name in indices:
self.writer.write(f'{index:6d}, // {name}\n')
self.writer.write(' 0 // trailing 0\n')
self.writer.write('};\n\n')
@ -327,8 +326,7 @@ class LocaleDataWriter (LocaleSourceEditor):
locale.currencyRounding, # unused (QTBUG-81343)
locale.firstDayOfWeek, locale.weekendStart, locale.weekendEnd,
locale.groupTop, locale.groupHigher, locale.groupLeast) ))
+ ', // {}/{}/{}\n'.format(
locale.language, locale.script, locale.territory))
+ f', // {locale.language}/{locale.script}/{locale.territory}\n')
self.writer.write(formatLine(*( # All zeros, matching the format:
(0,) * 3 + (0,) * 37 * 2
+ (currencyIsoCodeData(0),)
@ -346,32 +344,32 @@ class LocaleDataWriter (LocaleSourceEditor):
@staticmethod
def __writeNameData(out, book, form):
out('static const char {}_name_list[] =\n'.format(form))
out(f'static const char {form}_name_list[] =\n')
out('"Default\\0"\n')
for key, value in book.items():
if key == 0:
continue
out('"' + value[0] + '\\0"\n')
out(f'"{value[0]}\\0"\n')
out(';\n\n')
out('static const quint16 {}_name_index[] = {{\n'.format(form))
out(' 0, // Any{}\n'.format(form.capitalize()))
out(f'static const quint16 {form}_name_index[] = {{\n')
out(f' 0, // Any{form.capitalize()}\n')
index = 8
for key, value in book.items():
if key == 0:
continue
name = value[0]
out('{:6d}, // {}\n'.format(index, name))
out(f'{index:6d}, // {name}\n')
index += len(name) + 1
out('};\n\n')
@staticmethod
def __writeCodeList(out, book, form, width):
out('static const unsigned char {}_code_list[] =\n'.format(form))
out(f'static const unsigned char {form}_code_list[] =\n')
for key, value in book.items():
code = value[1]
code += r'\0' * max(width - len(code), 0)
out('"{}" // {}\n'.format(code, value[0]))
out(f'"{code}" // {value[0]}\n')
out(';\n\n')
def languageNames(self, languages):
@ -439,7 +437,7 @@ class CalendarDataWriter (LocaleSourceEditor):
key +
tuple(r.index for r in ranges) +
tuple(r.length for r in ranges) ))
+ '// {}/{}/{}\n'.format(locale.language, locale.script, locale.territory))
+ f'// {locale.language}/{locale.script}/{locale.territory}\n')
self.writer.write(self.formatCalendar(*( (0,) * (3 + 6 * 2) ))
+ '// trailing zeros\n')
self.writer.write('};\n')
@ -474,7 +472,7 @@ class LocaleHeaderWriter (SourceFileEditor):
suffix = name
out, dupes = self.writer.write, self.__dupes
out(' enum {} : ushort {{\n'.format(name))
out(f' enum {name} : ushort {{\n')
for key, value in book.items():
member = value[0].replace('-', ' ')
if name == 'Script':
@ -483,27 +481,26 @@ class LocaleHeaderWriter (SourceFileEditor):
if not member.endswith('Script'):
member += 'Script'
if member in dupes:
raise Error('The script name "{}" is messy'.format(member))
raise Error(f'The script name "{member}" is messy')
else:
member = ''.join(member.split())
member = member + suffix if member in dupes else member
out(' {} = {},\n'.format(member, key))
out(f' {member} = {key},\n')
out('\n '
+ ',\n '.join('{} = {}'.format(*pair)
for pair in sorted(alias.items()))
+ ',\n\n Last{} = {}'.format(suffix, member))
+ ',\n '.join(f'{k} = {v}' for k, v in sorted(alias.items()))
+ f',\n\n Last{suffix} = {member}')
# for "LastCountry = LastTerritory"
# ### Qt 7: Remove
if suffix != name:
out(',\n Last{} = Last{}'.format(name, suffix))
out(f',\n Last{name} = Last{suffix}')
out('\n };\n')
def usage(name, err, message = ''):
err.write("""Usage: {} path/to/qlocale.xml root/of/qtbase
""".format(name)) # TODO: elaborate
err.write(f"""Usage: {name} path/to/qlocale.xml root/of/qtbase
""") # TODO: elaborate
if message:
err.write('\n' + message + '\n')
@ -523,7 +520,7 @@ def main(args, out, err):
if not (os.path.isdir(qtsrcdir)
and all(os.path.isfile(os.path.join(qtsrcdir, 'src', 'corelib', 'text', leaf))
for leaf in ('qlocale_data_p.h', 'qlocale.h', 'qlocale.qdoc'))):
usage(name, err, 'Missing expected files under qtbase source root ' + qtsrcdir)
usage(name, err, f'Missing expected files under qtbase source root {qtsrcdir}')
return 1
reader = QLocaleXmlReader(qlocalexml)
@ -535,7 +532,7 @@ def main(args, out, err):
'qlocale_data_p.h'),
qtsrcdir, reader.cldrVersion)
except IOError as e:
err.write('Failed to open files to transcribe locale data: ' + str(e))
err.write(f'Failed to open files to transcribe locale data: {e}')
return 1
try:
@ -552,7 +549,7 @@ def main(args, out, err):
writer.territoryCodes(reader.territories)
except Error as e:
writer.cleanup()
err.write('\nError updating locale data: ' + e.message + '\n')
err.write(f'\nError updating locale data: {e}\n')
return 1
writer.close()
@ -561,18 +558,17 @@ def main(args, out, err):
for calendar, stem in calendars.items():
try:
writer = CalendarDataWriter(os.path.join(qtsrcdir, 'src', 'corelib', 'time',
'q{}calendar_data_p.h'.format(stem)),
f'q{stem}calendar_data_p.h'),
qtsrcdir, reader.cldrVersion)
except IOError as e:
err.write('Failed to open files to transcribe ' + calendar
+ ' data ' + str(e))
err.write(f'Failed to open files to transcribe {calendar} data {e}')
return 1
try:
writer.write(calendar, locale_map, locale_keys)
except Error as e:
writer.cleanup()
err.write('\nError updating ' + calendar + ' locale data: ' + e.message + '\n')
err.write(f'\nError updating {calendar} locale data: {e}\n')
return 1
writer.close()
@ -582,7 +578,7 @@ def main(args, out, err):
writer = LocaleHeaderWriter(os.path.join(qtsrcdir, 'src', 'corelib', 'text', 'qlocale.h'),
qtsrcdir, reader.dupes)
except IOError as e:
err.write('Failed to open files to transcribe qlocale.h: ' + str(e))
err.write(f'Failed to open files to transcribe qlocale.h: {e}')
return 1
try:
@ -591,7 +587,7 @@ def main(args, out, err):
writer.territories(reader.territories)
except Error as e:
writer.cleanup()
err.write('\nError updating qlocale.h: ' + e.message + '\n')
err.write(f'\nError updating qlocale.h: {e}\n')
return 1
writer.close()
@ -601,19 +597,19 @@ def main(args, out, err):
writer = Transcriber(os.path.join(qtsrcdir, 'src', 'corelib', 'text', 'qlocale.qdoc'),
qtsrcdir)
except IOError as e:
err.write('Failed to open files to transcribe qlocale.qdoc: ' + str(e))
err.write(f'Failed to open files to transcribe qlocale.qdoc: {e}')
return 1
DOCSTRING = " QLocale's data is based on Common Locale Data Repository "
try:
for line in writer.reader:
if DOCSTRING in line:
writer.writer.write(DOCSTRING + 'v' + reader.cldrVersion + '.\n')
writer.writer.write(f'{DOCSTRING}v{reader.cldrVersion}.\n')
else:
writer.writer.write(line)
except Error as e:
writer.cleanup()
err.write('\nError updating qlocale.qdoc: ' + e.message + '\n')
err.write(f'\nError updating qlocale.qdoc: {e}\n')
return 1
writer.close()