Skip to content

Commit cbfbe24

Browse files
gh-90300: split --help output into separate options (GH-30331)
Make --help output shorter and add new help options. --help-env, --help-xoptions and --help-all command-line options are added to complement --help. (cherry picked from commit 8aa9d40) Co-authored-by: Éric <[email protected]>
1 parent 29c7e81 commit cbfbe24

File tree

6 files changed

+210
-80
lines changed

6 files changed

+210
-80
lines changed

Doc/using/cmdline.rst

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,37 @@ automatically enabled, if available on your platform (see
183183
Automatic enabling of tab-completion and history editing.
184184

185185

186+
.. _using-on-generic-options:
187+
186188
Generic options
187189
~~~~~~~~~~~~~~~
188190

189191
.. cmdoption:: -?
190192
-h
191193
--help
192194

193-
Print a short description of all command line options.
195+
Print a short description of all command line options and corresponding
196+
environment variables and exit.
197+
198+
.. cmdoption:: --help-env
199+
200+
Print a short description of Python-specific environment variables
201+
and exit.
202+
203+
.. versionadded:: 3.11
204+
205+
.. cmdoption:: --help-xoptions
194206

207+
Print a description of implementation-specific :option:`-X` options
208+
and exit.
209+
210+
.. versionadded:: 3.11
211+
212+
.. cmdoption:: --help-all
213+
214+
Print complete usage information and exit.
215+
216+
.. versionadded:: 3.11
195217

196218
.. cmdoption:: -V
197219
--version
@@ -212,6 +234,7 @@ Generic options
212234
.. versionadded:: 3.6
213235
The ``-VV`` option.
214236

237+
215238
.. _using-on-misc-options:
216239

217240
Miscellaneous options
@@ -457,6 +480,7 @@ Miscellaneous options
457480
See :ref:`warning-filter` and :ref:`describing-warning-filters` for more
458481
details.
459482

483+
460484
.. cmdoption:: -x
461485

462486
Skip the first line of the source, allowing use of non-Unix forms of
@@ -550,6 +574,7 @@ Miscellaneous options
550574
The ``-X frozen_modules`` option.
551575

552576

577+
553578
Options you shouldn't use
554579
~~~~~~~~~~~~~~~~~~~~~~~~~
555580

Lib/test/test_cmd_line.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,55 @@ def _kill_python_and_exit_code(p):
2828
returncode = p.wait()
2929
return data, returncode
3030

31+
3132
class CmdLineTest(unittest.TestCase):
3233
def test_directories(self):
3334
assert_python_failure('.')
3435
assert_python_failure('< .')
3536

3637
def verify_valid_flag(self, cmd_line):
37-
rc, out, err = assert_python_ok(*cmd_line)
38+
rc, out, err = assert_python_ok(cmd_line)
3839
self.assertTrue(out == b'' or out.endswith(b'\n'))
3940
self.assertNotIn(b'Traceback', out)
4041
self.assertNotIn(b'Traceback', err)
42+
return out
4143

42-
def test_optimize(self):
43-
self.verify_valid_flag('-O')
44-
self.verify_valid_flag('-OO')
44+
def test_help(self):
45+
self.verify_valid_flag('-h')
46+
self.verify_valid_flag('-?')
47+
out = self.verify_valid_flag('--help')
48+
lines = out.splitlines()
49+
self.assertIn(b'usage', lines[0])
50+
self.assertNotIn(b'PYTHONHOME', out)
51+
self.assertNotIn(b'-X dev', out)
52+
self.assertLess(len(lines), 50)
4553

46-
def test_site_flag(self):
47-
self.verify_valid_flag('-S')
54+
def test_help_env(self):
55+
out = self.verify_valid_flag('--help-env')
56+
self.assertIn(b'PYTHONHOME', out)
57+
58+
def test_help_xoptions(self):
59+
out = self.verify_valid_flag('--help-xoptions')
60+
self.assertIn(b'-X dev', out)
4861

49-
def test_usage(self):
50-
rc, out, err = assert_python_ok('-h')
62+
def test_help_all(self):
63+
out = self.verify_valid_flag('--help-all')
5164
lines = out.splitlines()
5265
self.assertIn(b'usage', lines[0])
66+
self.assertIn(b'PYTHONHOME', out)
67+
self.assertIn(b'-X dev', out)
68+
5369
# The first line contains the program name,
5470
# but the rest should be ASCII-only
5571
b''.join(lines[1:]).decode('ascii')
5672

73+
def test_optimize(self):
74+
self.verify_valid_flag('-O')
75+
self.verify_valid_flag('-OO')
76+
77+
def test_site_flag(self):
78+
self.verify_valid_flag('-S')
79+
5780
def test_version(self):
5881
version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii")
5982
for switch in '-V', '--version', '-VV':
@@ -93,7 +116,7 @@ def get_xoptions(*args):
93116
def test_unknown_xoptions(self):
94117
rc, out, err = assert_python_failure('-X', 'blech')
95118
self.assertIn(b'Unknown value for option -X', err)
96-
msg = b'Fatal Python error: Unknown value for option -X'
119+
msg = b'Fatal Python error: Unknown value for option -X (see --help-xoptions)'
97120
self.assertEqual(err.splitlines().count(msg), 1)
98121
self.assertEqual(b'', out)
99122

@@ -137,7 +160,6 @@ def test_xoption_frozen_modules(self):
137160
}
138161
for raw, expected in tests:
139162
cmd = ['-X', f'frozen_modules{raw}',
140-
#'-c', 'import os; print(os.__spec__.loader.__name__, end="")']
141163
'-c', 'import os; print(os.__spec__.loader, end="")']
142164
with self.subTest(raw):
143165
res = assert_python_ok(*cmd)
@@ -170,7 +192,6 @@ def test_relativedir_bug46421(self):
170192
# Test `python -m unittest` with a relative directory beginning with ./
171193
# Note: We have to switch to the project's top module's directory, as per
172194
# the python unittest wiki. We will switch back when we are done.
173-
defaultwd = os.getcwd()
174195
projectlibpath = os.path.dirname(__file__).removesuffix("test")
175196
with os_helper.change_cwd(projectlibpath):
176197
# Testing with and without ./
@@ -250,7 +271,6 @@ def test_invalid_utf8_arg(self):
250271
#
251272
# Test with default config, in the C locale, in the Python UTF-8 Mode.
252273
code = 'import sys, os; s=os.fsencode(sys.argv[1]); print(ascii(s))'
253-
base_cmd = [sys.executable, '-c', code]
254274

255275
def run_default(arg):
256276
cmd = [sys.executable, '-c', code, arg]
@@ -895,6 +915,7 @@ def test_sys_flags_not_set(self):
895915
PYTHONSAFEPATH="1",
896916
)
897917

918+
898919
class SyntaxErrorTests(unittest.TestCase):
899920
def check_string(self, code):
900921
proc = subprocess.run([sys.executable, "-"], input=code,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Make ``--help`` output shorter by moving some info to the new
2+
``--help-env`` and ``--help-xoptions`` command-line options.
3+
Also add ``--help-all`` option to print complete usage.

Misc/python.man

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,19 @@ python \- an interpreted, interactive, object-oriented programming language
8484
|
8585
.I never
8686
]
87+
.br
88+
[
89+
.B \--help
90+
]
91+
[
92+
.B \--help-env
93+
]
94+
[
95+
.B \--help-xoptions
96+
]
97+
[
98+
.B \--help-all
99+
]
87100
.br
88101
[
89102
.B \-c
@@ -149,6 +162,16 @@ the behavior of the interpreter.
149162
.B \-h ", " \-? ", "\-\-help
150163
Prints the usage for the interpreter executable and exits.
151164
.TP
165+
.B "\-\-help\-env"
166+
Prints help about Python-specific environment variables and exits.
167+
.TP
168+
.B "\-\-help\-xoptions"
169+
Prints help about implementation-specific \fB\-X\fP options and exits.
170+
.TP
171+
.TP
172+
.B "\-\-help\-all"
173+
Prints complete usage information and exits.
174+
.TP
152175
.B \-i
153176
When a script is passed as first argument or the \fB\-c\fP option is
154177
used, enter interactive mode after executing the script or the
@@ -287,7 +310,7 @@ a regular expression on the warning message.
287310

288311
.TP
289312
.BI "\-X " option
290-
Set implementation specific option. The following options are available:
313+
Set implementation-specific option. The following options are available:
291314

292315
-X faulthandler: enable faulthandler
293316

@@ -332,7 +355,7 @@ Set implementation specific option. The following options are available:
332355
files are desired as well as suppressing the extra visual location indicators
333356
when the interpreter displays tracebacks.
334357

335-
-X frozen_modules=[on|off]: whether or not frozen modules should be used
358+
-X frozen_modules=[on|off]: whether or not frozen modules should be used.
336359
The default is "on" (or "off" if you are running a local build).
337360

338361
.TP

Python/getopt.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,12 @@ static const wchar_t *opt_ptr = L"";
4444
#define SHORT_OPTS L"bBc:dEhiIJm:OPqRsStuvVW:xX:?"
4545

4646
static const _PyOS_LongOption longopts[] = {
47+
/* name, has_arg, val (used in switch in initconfig.c) */
4748
{L"check-hash-based-pycs", 1, 0},
48-
{NULL, 0, 0},
49+
{L"help-all", 0, 1},
50+
{L"help-env", 0, 2},
51+
{L"help-xoptions", 0, 3},
52+
{NULL, 0, -1}, /* sentinel */
4953
};
5054

5155

0 commit comments

Comments
 (0)