From c83556159fd05b985e14e0950e582ca456fa7c4d Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sun, 31 Aug 2025 21:29:02 +0100 Subject: [PATCH 1/3] [3.13] gh-138286: Run ``ruff`` on ``Tools/i18n`` (GH-138287) (cherry picked from commit 78acd8e95e78bc410b8207cd60e1323ece01b3d5) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Tomas R. --- .pre-commit-config.yaml | 4 ++++ Tools/i18n/.ruff.toml | 10 ++++++++++ Tools/i18n/makelocalealias.py | 14 +++++++------- Tools/i18n/msgfmt.py | 24 ++++++++++++------------ 4 files changed, 33 insertions(+), 19 deletions(-) create mode 100644 Tools/i18n/.ruff.toml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c146201fc355ef..e35b0880a4370e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,6 +10,10 @@ repos: name: Run Ruff (lint) on Lib/test/ args: [--exit-non-zero-on-fix] files: ^Lib/test/ + - id: ruff + name: Run Ruff (lint) on Tools/i18n/ + args: [--exit-non-zero-on-fix, --config=Tools/i18n/.ruff.toml] + files: ^Tools/i18n/ - id: ruff name: Run Ruff (lint) on Argument Clinic args: [--exit-non-zero-on-fix, --config=Tools/clinic/.ruff.toml] diff --git a/Tools/i18n/.ruff.toml b/Tools/i18n/.ruff.toml new file mode 100644 index 00000000000000..a8f4f2f5a96d7b --- /dev/null +++ b/Tools/i18n/.ruff.toml @@ -0,0 +1,10 @@ +extend = "../../.ruff.toml" # Inherit the project-wide settings + +target-version = "py313" + +[lint] +select = [ + "F", # pyflakes + "I", # isort + "UP", # pyupgrade +] diff --git a/Tools/i18n/makelocalealias.py b/Tools/i18n/makelocalealias.py index 02af1caff7d499..085da1c63b701c 100755 --- a/Tools/i18n/makelocalealias.py +++ b/Tools/i18n/makelocalealias.py @@ -8,6 +8,7 @@ """ import locale import sys + _locale = locale # Location of the X11 alias file. @@ -89,16 +90,15 @@ def parse_glibc_supported(filename): def pprint(data): items = sorted(data.items()) for k, v in items: - print(' %-40s%a,' % ('%a:' % k, v)) + print(f" {k!a:<40}{v!a},") def print_differences(data, olddata): items = sorted(olddata.items()) for k, v in items: if k not in data: - print('# removed %a' % k) + print(f'# removed {k!a}') elif olddata[k] != data[k]: - print('# updated %a -> %a to %a' % \ - (k, olddata[k], data[k])) + print(f'# updated {k!a} -> {olddata[k]!a} to {data[k]!a}') # Additions are not mentioned def optimize(data): @@ -121,7 +121,7 @@ def check(data): errors = 0 for k, v in data.items(): if locale.normalize(k) != v: - print('ERROR: %a -> %a != %a' % (k, locale.normalize(k), v), + print(f'ERROR: {k!a} -> {locale.normalize(k)!a} != {v!a}', file=sys.stderr) errors += 1 return errors @@ -131,10 +131,10 @@ def check(data): parser = argparse.ArgumentParser() parser.add_argument('--locale-alias', default=LOCALE_ALIAS, help='location of the X11 alias file ' - '(default: %a)' % LOCALE_ALIAS) + f'(default: {LOCALE_ALIAS})') parser.add_argument('--glibc-supported', default=SUPPORTED, help='location of the glibc SUPPORTED locales file ' - '(default: %a)' % SUPPORTED) + f'(default: {SUPPORTED})') args = parser.parse_args() data = locale.locale_alias.copy() diff --git a/Tools/i18n/msgfmt.py b/Tools/i18n/msgfmt.py index ecebf5d6a51ee8..5cbb63d9de2c8d 100755 --- a/Tools/i18n/msgfmt.py +++ b/Tools/i18n/msgfmt.py @@ -5,8 +5,7 @@ This program converts a textual Uniforum-style message catalog (.po file) into a binary GNU catalog (.mo file). This is essentially the same function as the -GNU msgfmt program, however, it is a simpler implementation. Currently it -does not handle plural forms but it does handle message contexts. +GNU msgfmt program, however, it is a simpler implementation. Usage: msgfmt.py [OPTIONS] filename.po @@ -25,16 +24,17 @@ Display version information and exit. """ -import os -import sys +import array import ast import getopt +import os import struct -import array +import sys from email.parser import HeaderParser __version__ = "1.2" + MESSAGES = {} @@ -112,11 +112,12 @@ def make(filename, outfile): try: with open(infile, 'rb') as f: lines = f.readlines() - except IOError as msg: + except OSError as msg: print(msg, file=sys.stderr) sys.exit(1) section = msgctxt = None + msgid = msgstr = b'' fuzzy = 0 # Start off assuming Latin-1, so everything decodes without failure, @@ -168,7 +169,7 @@ def make(filename, outfile): # This is a message with plural forms elif l.startswith('msgid_plural'): if section != ID: - print('msgid_plural not preceded by msgid on %s:%d' % (infile, lno), + print(f'msgid_plural not preceded by msgid on {infile}:{lno}', file=sys.stderr) sys.exit(1) l = l[12:] @@ -179,7 +180,7 @@ def make(filename, outfile): section = STR if l.startswith('msgstr['): if not is_plural: - print('plural without msgid_plural on %s:%d' % (infile, lno), + print(f'plural without msgid_plural on {infile}:{lno}', file=sys.stderr) sys.exit(1) l = l.split(']', 1)[1] @@ -187,7 +188,7 @@ def make(filename, outfile): msgstr += b'\0' # Separator of the various plural forms else: if is_plural: - print('indexed msgstr required for plural on %s:%d' % (infile, lno), + print(f'indexed msgstr required for plural on {infile}:{lno}', file=sys.stderr) sys.exit(1) l = l[6:] @@ -203,8 +204,7 @@ def make(filename, outfile): elif section == STR: msgstr += l.encode(encoding) else: - print('Syntax error on %s:%d' % (infile, lno), \ - 'before:', file=sys.stderr) + print(f'Syntax error on {infile}:{lno} before:', file=sys.stderr) print(l, file=sys.stderr) sys.exit(1) # Add last entry @@ -217,7 +217,7 @@ def make(filename, outfile): try: with open(outfile,"wb") as f: f.write(output) - except IOError as msg: + except OSError as msg: print(msg, file=sys.stderr) From a385f5556a6820b35dcf91ab50415fe4979f09ed Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Fri, 5 Sep 2025 07:48:55 +0100 Subject: [PATCH 2/3] Commit --- Tools/i18n/msgfmt.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tools/i18n/msgfmt.py b/Tools/i18n/msgfmt.py index 5cbb63d9de2c8d..27b67f28431435 100755 --- a/Tools/i18n/msgfmt.py +++ b/Tools/i18n/msgfmt.py @@ -5,7 +5,8 @@ This program converts a textual Uniforum-style message catalog (.po file) into a binary GNU catalog (.mo file). This is essentially the same function as the -GNU msgfmt program, however, it is a simpler implementation. +GNU msgfmt program, however, it is a simpler implementation. Currently it +does not handle plural forms but it does handle message contexts. Usage: msgfmt.py [OPTIONS] filename.po From b704d225ede5ec34ae0085ca1d8f0059f4e00113 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Fri, 5 Sep 2025 07:52:24 +0100 Subject: [PATCH 3/3] Commit --- Tools/i18n/pygettext.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/i18n/pygettext.py b/Tools/i18n/pygettext.py index 8f59982640cbba..058a4178377911 100755 --- a/Tools/i18n/pygettext.py +++ b/Tools/i18n/pygettext.py @@ -214,7 +214,7 @@ def make_escapes(pass_nonascii): else: mod = 256 escape = escape_nonascii - escapes = [r"\%03o" % i for i in range(mod)] + escapes = [fr"\{i:03o}" for i in range(mod)] for i in range(32, 127): escapes[i] = chr(i) escapes[ord('\\')] = r'\\' @@ -620,7 +620,7 @@ class Options: try: with open(options.excludefilename) as fp: options.toexclude = fp.readlines() - except IOError: + except OSError: print(_( "Can't read --exclude-file: %s") % options.excludefilename, file=sys.stderr) sys.exit(1)