gh-104400: Remove `fintl.gettext` from pygettext (#129580)

The ``fintl`` module is never installed or tested, meaning that the
fallback identity function is unconditionally used for ``_()``.
This means we can simplify, converting the docstring to a real
docstring, and converting some other strings to f-strings.

We also convert the module to UTF-8, sort imports,
and remove the history comment, which was last updated in 2002.
Consult the git history for a more accurate summary of changes.
This commit is contained in:
Adam Turner 2025-02-02 14:30:34 +00:00 committed by GitHub
parent df4a2f5bd7
commit 237f186da4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,26 +1,6 @@
#! /usr/bin/env python3
# -*- coding: iso-8859-1 -*-
# Originally written by Barry Warsaw <barry@python.org>
#
# Minimally patched to make it even more xgettext compatible
# by Peter Funk <pf@artcom-gmbh.de>
#
# 2002-11-22 Jürgen Hermann <jh@web.de>
# Added checks that _() only contains string literals, and
# command line args are resolved to module lists, i.e. you
# can now pass a filename, a module or package name, or a
# directory (including globbing chars, important for Win32).
# Made docstring fit in 80 chars wide displays using pydoc.
#
# for selftesting
try:
import fintl
_ = fintl.gettext
except ImportError:
_ = lambda s: s
__doc__ = _("""pygettext -- Python equivalent of xgettext(1)
"""pygettext -- Python equivalent of xgettext(1)
Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the
internationalization of C programs. Most of these tools are independent of
@ -153,16 +133,16 @@ Options:
conjunction with the -D option above.
If `inputfile' is -, standard input is read.
""")
"""
import os
import ast
import getopt
import glob
import importlib.machinery
import importlib.util
import os
import sys
import glob
import time
import getopt
import ast
import tokenize
from collections import defaultdict
from dataclasses import dataclass, field
@ -173,7 +153,7 @@ __version__ = '1.5'
# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's
# there.
pot_header = _('''\
pot_header = '''\
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
@ -190,7 +170,7 @@ msgstr ""
"Content-Transfer-Encoding: %(encoding)s\\n"
"Generated-By: pygettext.py %(version)s\\n"
''')
'''
def usage(code, msg=''):
@ -204,7 +184,7 @@ def make_escapes(pass_nonascii):
global escapes, escape
if pass_nonascii:
# Allow non-ascii characters to pass through so that e.g. 'msgid
# "Höhe"' would result not result in 'msgid "H\366he"'. Otherwise we
# "Höhe"' would result not result in 'msgid "H\366he"'. Otherwise we
# escape any character outside the 32..126 range.
mod = 128
escape = escape_ascii
@ -224,6 +204,7 @@ def make_escapes(pass_nonascii):
def escape_ascii(s, encoding):
return ''.join(escapes[ord(c)] if ord(c) < 128 else c for c in s)
def escape_nonascii(s, encoding):
return ''.join(escapes[b] for b in s.encode(encoding))
@ -416,7 +397,7 @@ class TokenEater:
if func_name not in opts.keywords:
continue
if len(call.args) != 1:
print(_(
print((
'*** %(file)s:%(lineno)s: Seen unexpected amount of'
' positional arguments in gettext call: %(source_segment)s'
) % {
@ -426,7 +407,7 @@ class TokenEater:
}, file=sys.stderr)
continue
if call.keywords:
print(_(
print((
'*** %(file)s:%(lineno)s: Seen unexpected keyword arguments'
' in gettext call: %(source_segment)s'
) % {
@ -437,7 +418,7 @@ class TokenEater:
continue
arg = call.args[0]
if not isinstance(arg, ast.Constant):
print(_(
print((
'*** %(file)s:%(lineno)s: Seen unexpected argument type'
' in gettext call: %(source_segment)s'
) % {
@ -550,7 +531,7 @@ class TokenEater:
)
def warn_unexpected_token(self, token):
print(_(
print((
'*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"'
) % {
'token': token,
@ -677,7 +658,7 @@ def main():
elif opt in ('-S', '--style'):
options.locationstyle = locations.get(arg.lower())
if options.locationstyle is None:
usage(1, _('Invalid value for --style: %s') % arg)
usage(1, f'Invalid value for --style: {arg}')
elif opt in ('-o', '--output'):
options.outfile = arg
elif opt in ('-p', '--output-dir'):
@ -685,13 +666,13 @@ def main():
elif opt in ('-v', '--verbose'):
options.verbose = 1
elif opt in ('-V', '--version'):
print(_('pygettext.py (xgettext for Python) %s') % __version__)
print(f'pygettext.py (xgettext for Python) {__version__}')
sys.exit(0)
elif opt in ('-w', '--width'):
try:
options.width = int(arg)
except ValueError:
usage(1, _('--width argument must be an integer: %s') % arg)
usage(1, f'--width argument must be an integer: {arg}')
elif opt in ('-x', '--exclude-file'):
options.excludefilename = arg
elif opt in ('-X', '--no-docstrings'):
@ -719,8 +700,8 @@ def main():
with open(options.excludefilename) as fp:
options.toexclude = fp.readlines()
except IOError:
print(_(
"Can't read --exclude-file: %s") % options.excludefilename, file=sys.stderr)
print(f"Can't read --exclude-file: {options.excludefilename}",
file=sys.stderr)
sys.exit(1)
else:
options.toexclude = []
@ -739,12 +720,12 @@ def main():
for filename in args:
if filename == '-':
if options.verbose:
print(_('Reading standard input'))
print('Reading standard input')
fp = sys.stdin.buffer
closep = 0
else:
if options.verbose:
print(_('Working on %s') % filename)
print(f'Working on {filename}')
fp = open(filename, 'rb')
closep = 1
try:
@ -779,7 +760,3 @@ def main():
if __name__ == '__main__':
main()
# some more test strings
# this one creates a warning
_('*** Seen unexpected token "%(token)s"') % {'token': 'test'}
_('more' 'than' 'one' 'string')