Skip to content

Commit

Permalink
pythongh-90300: split --help output into separate options (python#30331)
Browse files Browse the repository at this point in the history
Make --help output shorter and add new help options.

--help-env, --help-xoptions and --help-all command-line options are
added to complement --help.
  • Loading branch information
merwok authored Jun 1, 2022
1 parent 132e563 commit 8aa9d40
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 80 deletions.
27 changes: 26 additions & 1 deletion Doc/using/cmdline.rst
Original file line number Diff line number Diff line change
Expand Up @@ -183,15 +183,37 @@ automatically enabled, if available on your platform (see
Automatic enabling of tab-completion and history editing.


.. _using-on-generic-options:

Generic options
~~~~~~~~~~~~~~~

.. cmdoption:: -?
-h
--help

Print a short description of all command line options.
Print a short description of all command line options and corresponding
environment variables and exit.

.. cmdoption:: --help-env

Print a short description of Python-specific environment variables
and exit.

.. versionadded:: 3.11

.. cmdoption:: --help-xoptions

Print a description of implementation-specific :option:`-X` options
and exit.

.. versionadded:: 3.11

.. cmdoption:: --help-all

Print complete usage information and exit.

.. versionadded:: 3.11

.. cmdoption:: -V
--version
Expand All @@ -212,6 +234,7 @@ Generic options
.. versionadded:: 3.6
The ``-VV`` option.


.. _using-on-misc-options:

Miscellaneous options
Expand Down Expand Up @@ -460,6 +483,7 @@ Miscellaneous options
See :ref:`warning-filter` and :ref:`describing-warning-filters` for more
details.


.. cmdoption:: -x

Skip the first line of the source, allowing use of non-Unix forms of
Expand Down Expand Up @@ -553,6 +577,7 @@ Miscellaneous options
The ``-X frozen_modules`` option.



Options you shouldn't use
~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
45 changes: 33 additions & 12 deletions Lib/test/test_cmd_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,55 @@ def _kill_python_and_exit_code(p):
returncode = p.wait()
return data, returncode


class CmdLineTest(unittest.TestCase):
def test_directories(self):
assert_python_failure('.')
assert_python_failure('< .')

def verify_valid_flag(self, cmd_line):
rc, out, err = assert_python_ok(*cmd_line)
rc, out, err = assert_python_ok(cmd_line)
self.assertTrue(out == b'' or out.endswith(b'\n'))
self.assertNotIn(b'Traceback', out)
self.assertNotIn(b'Traceback', err)
return out

def test_optimize(self):
self.verify_valid_flag('-O')
self.verify_valid_flag('-OO')
def test_help(self):
self.verify_valid_flag('-h')
self.verify_valid_flag('-?')
out = self.verify_valid_flag('--help')
lines = out.splitlines()
self.assertIn(b'usage', lines[0])
self.assertNotIn(b'PYTHONHOME', out)
self.assertNotIn(b'-X dev', out)
self.assertLess(len(lines), 50)

def test_site_flag(self):
self.verify_valid_flag('-S')
def test_help_env(self):
out = self.verify_valid_flag('--help-env')
self.assertIn(b'PYTHONHOME', out)

def test_help_xoptions(self):
out = self.verify_valid_flag('--help-xoptions')
self.assertIn(b'-X dev', out)

def test_usage(self):
rc, out, err = assert_python_ok('-h')
def test_help_all(self):
out = self.verify_valid_flag('--help-all')
lines = out.splitlines()
self.assertIn(b'usage', lines[0])
self.assertIn(b'PYTHONHOME', out)
self.assertIn(b'-X dev', out)

# The first line contains the program name,
# but the rest should be ASCII-only
b''.join(lines[1:]).decode('ascii')

def test_optimize(self):
self.verify_valid_flag('-O')
self.verify_valid_flag('-OO')

def test_site_flag(self):
self.verify_valid_flag('-S')

def test_version(self):
version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii")
for switch in '-V', '--version', '-VV':
Expand Down Expand Up @@ -90,7 +113,7 @@ def get_xoptions(*args):
def test_unknown_xoptions(self):
rc, out, err = assert_python_failure('-X', 'blech')
self.assertIn(b'Unknown value for option -X', err)
msg = b'Fatal Python error: Unknown value for option -X'
msg = b'Fatal Python error: Unknown value for option -X (see --help-xoptions)'
self.assertEqual(err.splitlines().count(msg), 1)
self.assertEqual(b'', out)

Expand Down Expand Up @@ -134,7 +157,6 @@ def test_xoption_frozen_modules(self):
}
for raw, expected in tests:
cmd = ['-X', f'frozen_modules{raw}',
#'-c', 'import os; print(os.__spec__.loader.__name__, end="")']
'-c', 'import os; print(os.__spec__.loader, end="")']
with self.subTest(raw):
res = assert_python_ok(*cmd)
Expand Down Expand Up @@ -167,7 +189,6 @@ def test_relativedir_bug46421(self):
# Test `python -m unittest` with a relative directory beginning with ./
# Note: We have to switch to the project's top module's directory, as per
# the python unittest wiki. We will switch back when we are done.
defaultwd = os.getcwd()
projectlibpath = os.path.dirname(__file__).removesuffix("test")
with os_helper.change_cwd(projectlibpath):
# Testing with and without ./
Expand Down Expand Up @@ -247,7 +268,6 @@ def test_invalid_utf8_arg(self):
#
# Test with default config, in the C locale, in the Python UTF-8 Mode.
code = 'import sys, os; s=os.fsencode(sys.argv[1]); print(ascii(s))'
base_cmd = [sys.executable, '-c', code]

def run_default(arg):
cmd = [sys.executable, '-c', code, arg]
Expand Down Expand Up @@ -892,6 +912,7 @@ def test_sys_flags_not_set(self):
PYTHONSAFEPATH="1",
)


class SyntaxErrorTests(unittest.TestCase):
def check_string(self, code):
proc = subprocess.run([sys.executable, "-"], input=code,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Make ``--help`` output shorter by moving some info to the new
``--help-env`` and ``--help-xoptions`` command-line options.
Also add ``--help-all`` option to print complete usage.
27 changes: 25 additions & 2 deletions Misc/python.man
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ python \- an interpreted, interactive, object-oriented programming language
|
.I never
]
.br
[
.B \--help
]
[
.B \--help-env
]
[
.B \--help-xoptions
]
[
.B \--help-all
]
.br
[
.B \-c
Expand Down Expand Up @@ -149,6 +162,16 @@ the behavior of the interpreter.
.B \-h ", " \-? ", "\-\-help
Prints the usage for the interpreter executable and exits.
.TP
.B "\-\-help\-env"
Prints help about Python-specific environment variables and exits.
.TP
.B "\-\-help\-xoptions"
Prints help about implementation-specific \fB\-X\fP options and exits.
.TP
.TP
.B "\-\-help\-all"
Prints complete usage information and exits.
.TP
.B \-i
When a script is passed as first argument or the \fB\-c\fP option is
used, enter interactive mode after executing the script or the
Expand Down Expand Up @@ -287,7 +310,7 @@ a regular expression on the warning message.

.TP
.BI "\-X " option
Set implementation specific option. The following options are available:
Set implementation-specific option. The following options are available:

-X faulthandler: enable faulthandler

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

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

.TP
Expand Down
6 changes: 5 additions & 1 deletion Python/getopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,12 @@ static const wchar_t *opt_ptr = L"";
#define SHORT_OPTS L"bBc:dEhiIJm:OPqRsStuvVW:xX:?"

static const _PyOS_LongOption longopts[] = {
/* name, has_arg, val (used in switch in initconfig.c) */
{L"check-hash-based-pycs", 1, 0},
{NULL, 0, 0},
{L"help-all", 0, 1},
{L"help-env", 0, 2},
{L"help-xoptions", 0, 3},
{NULL, 0, -1}, /* sentinel */
};


Expand Down
Loading

0 comments on commit 8aa9d40

Please sign in to comment.