Skip to content

[3.11] gh-90300: split --help output into separate options (GH-30331) #93413

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 1 commit into from
Jun 14, 2022
Merged
Show file tree
Hide file tree
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
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this doc in the main branch already has 3.11 for version added, so both versions will agree.


.. 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 @@ -457,6 +480,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 @@ -550,6 +574,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 @@ -28,32 +28,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 @@ -93,7 +116,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 @@ -137,7 +160,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 @@ -170,7 +192,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 @@ -250,7 +271,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 @@ -895,6 +915,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