Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 2, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 21 additions & 44 deletions Tools/i18n/pygettext.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,6 @@
#! /usr/bin/env python3
# -*- coding: iso-8859-1 -*-
# Originally written by Barry Warsaw <[email protected]>
#
# Minimally patched to make it even more xgettext compatible
# by Peter Funk <[email protected]>
#
# 2002-11-22 Jürgen Hermann <[email protected]>
# 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
Expand Down Expand Up @@ -153,16 +133,16 @@
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
Expand All @@ -173,7 +153,7 @@

# 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.
Expand All @@ -190,7 +170,7 @@
"Content-Transfer-Encoding: %(encoding)s\\n"
"Generated-By: pygettext.py %(version)s\\n"

''')
'''


def usage(code, msg=''):
Expand All @@ -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
Expand All @@ -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))

Expand Down Expand Up @@ -416,7 +397,7 @@ def __waiting(self, ttype, tstring, lineno):
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'
) % {
Expand All @@ -426,7 +407,7 @@ def __waiting(self, ttype, tstring, lineno):
}, file=sys.stderr)
continue
if call.keywords:
print(_(
print((
'*** %(file)s:%(lineno)s: Seen unexpected keyword arguments'
' in gettext call: %(source_segment)s'
) % {
Expand All @@ -437,7 +418,7 @@ def __waiting(self, ttype, tstring, lineno):
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'
) % {
Expand Down Expand Up @@ -550,7 +531,7 @@ def __addentry(self, msg, lineno=None, *, is_docstring=False):
)

def warn_unexpected_token(self, token):
print(_(
print((
'*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"'
) % {
'token': token,
Expand Down Expand Up @@ -677,21 +658,21 @@ class Options:
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'):
options.outpath = arg
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'):
Expand Down Expand Up @@ -719,8 +700,8 @@ class Options:
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 = []
Expand All @@ -739,12 +720,12 @@ class Options:
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:
Expand Down Expand Up @@ -779,7 +760,3 @@ class Options:

if __name__ == '__main__':
main()
# some more test strings
# this one creates a warning
_('*** Seen unexpected token "%(token)s"') % {'token': 'test'}
_('more' 'than' 'one' 'string')
Loading