Skip to content

Commit 44c7eab

Browse files
committed
gh-133049: Require an input file in pygettext
Like xgettext, exit with status 1 and an error message when no input file is given, instead of writing a header-only messages.pot. The check runs before the arguments are expanded, so a path that matches nothing keeps its current behaviour.
1 parent d54c2d8 commit 44c7eab

3 files changed

Lines changed: 35 additions & 5 deletions

File tree

‎Lib/test/test_tools/test_i18n.py‎

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
from textwrap import dedent
88
from pathlib import Path
99

10-
from test.support.script_helper import assert_python_ok
10+
from test.support.script_helper import (assert_python_failure,
11+
assert_python_ok,
12+
run_python_until_end)
1113
from test.test_tools import imports_under_tool, skip_if_missing, toolsdir
1214
from test.support.os_helper import temp_cwd, temp_dir
1315

@@ -122,7 +124,8 @@ def test_header(self):
122124
http://www.gnu.org/software/gettext/manual/gettext.html#Header-Entry
123125
"""
124126
with temp_cwd(None) as cwd:
125-
assert_python_ok('-Xutf8', self.script)
127+
Path('test.py').touch()
128+
assert_python_ok('-Xutf8', self.script, 'test.py')
126129
with open('messages.pot', encoding='utf-8') as fp:
127130
data = fp.read()
128131
header = self.get_header(data)
@@ -149,7 +152,8 @@ def test_POT_Creation_Date(self):
149152
""" Match the date format from xgettext for POT-Creation-Date """
150153
from datetime import datetime
151154
with temp_cwd(None) as cwd:
152-
assert_python_ok('-Xutf8', self.script)
155+
Path('test.py').touch()
156+
assert_python_ok('-Xutf8', self.script, 'test.py')
153157
with open('messages.pot', encoding='utf-8') as fp:
154158
data = fp.read()
155159
header = self.get_header(data)
@@ -165,11 +169,28 @@ def test_POT_Creation_Date(self):
165169
def test_output_option(self):
166170
for opt in ('-o', '--output='):
167171
with temp_cwd():
168-
assert_python_ok(self.script, f'{opt}test')
172+
Path('test.py').touch()
173+
assert_python_ok(self.script, f'{opt}test', 'test.py')
169174
self.assertTrue(os.path.exists('test'))
170-
res = assert_python_ok(self.script, f'{opt}-')
175+
res = assert_python_ok(self.script, f'{opt}-', 'test.py')
171176
self.assertIn(b'Project-Id-Version: PACKAGE VERSION', res.out)
172177

178+
def test_no_input_file(self):
179+
"""Like xgettext, require at least one input file."""
180+
for args in ((), ('-o', '-')):
181+
with self.subTest(args=args), temp_cwd(None):
182+
res = assert_python_failure('-Xutf8', self.script, *args)
183+
self.assertEqual(res.rc, 1)
184+
self.assertEqual(res.out, b'')
185+
self.assertIn(b'pygettext: no input file given', res.err)
186+
self.assertFalse(os.path.exists('messages.pot'))
187+
188+
def test_missing_input_file_is_not_no_input(self):
189+
# A path that matches nothing is not the same as no path at all.
190+
with temp_cwd(None):
191+
res, _ = run_python_until_end(self.script, 'does_not_exist.py')
192+
self.assertNotIn(b'no input file given', res.err)
193+
173194
def test_funcdocstring(self):
174195
for doc in ('"""doc"""', "r'''doc'''", "R'doc'", 'u"doc"'):
175196
with self.subTest(doc):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:program:`pygettext` now exits with an error if no input file is given,
2+
like :program:`xgettext`.

‎Tools/i18n/pygettext.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,13 @@ class Options:
817817
else:
818818
options.toexclude = []
819819

820+
# xgettext requires at least one input file
821+
if not args:
822+
print("pygettext: no input file given\n"
823+
"Try 'pygettext --help' for more information.",
824+
file=sys.stderr)
825+
sys.exit(1)
826+
820827
# resolve args to module lists
821828
expanded = []
822829
for arg in args:

0 commit comments

Comments
 (0)