Skip to content
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

gh-90300: split --help output into separate options #30331

Merged
merged 33 commits into from Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
225c869
move list of X options out of help output
merwok Jan 2, 2022
eaefd1a
mention help option in fatal error message
merwok Jan 2, 2022
57fd33b
move variable declaration out of case block
merwok Jan 2, 2022
55dbf69
move extra envvars help to separate option
merwok Jan 2, 2022
0aaf9af
doc
merwok Jan 2, 2022
a592003
add minimal tests
merwok Jan 2, 2022
1c4cf63
flatten the sub-switch
merwok Jan 2, 2022
d8bfcff
suggestion from Barry
merwok Jan 3, 2022
38f2dd8
more suggestions from flufl
merwok Jan 3, 2022
a828fe8
remove unnecessary
merwok Jan 7, 2022
8bde4ec
mention all envvars in --help-env
merwok Jan 7, 2022
0dbaf03
mistake
merwok Jan 7, 2022
0c9a995
introduce --help-xoptions
merwok Jan 12, 2022
aab464f
add --help-all
merwok Jan 12, 2022
064d4ad
merge upstream
merwok Jan 12, 2022
b9a0b19
replace fprintf by printf; remove extra blanklines
merwok Jan 15, 2022
0ee24d4
merge upstream
merwok Feb 9, 2022
dd2beaa
Merge branch 'main' into shorten-help-output
merwok Apr 11, 2022
c74fc69
merge upstream
merwok May 5, 2022
2f108fe
merge upstream
merwok May 23, 2022
4f345e8
check return code in verify_valid_flag
merwok May 23, 2022
a6573d6
remove duplicate check
merwok May 24, 2022
da97a38
fix some help texts in 80 columns
merwok May 24, 2022
98525b4
remove needless checks
merwok May 25, 2022
5585095
reformat and rearrange some help entries
merwok May 25, 2022
24526bd
fix formatting issues and missing info in man page and --help
merwok May 25, 2022
0bb5dfa
make new tests a bit more useful
merwok May 25, 2022
8fa72f5
512 bytes should be enough for everyone
merwok May 25, 2022
29d04a0
keep long option at the end of help text
merwok May 26, 2022
356d1bf
merge branch 'fix-help-man'
merwok May 26, 2022
ac1b5fb
fix tests and output
merwok May 26, 2022
9bcea95
final fixes
merwok May 26, 2022
5485255
merge upstream
merwok May 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 26 additions & 1 deletion Doc/using/cmdline.rst
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 @@ -436,6 +459,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 @@ -529,6 +553,7 @@ Miscellaneous options
The ``-X frozen_modules`` option.



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

Expand Down
20 changes: 16 additions & 4 deletions Lib/test/test_cmd_line.py
Expand Up @@ -37,6 +37,20 @@ def verify_valid_flag(self, cmd_line):
self.assertNotIn(b'Traceback', out)
self.assertNotIn(b'Traceback', err)

def test_help(self):
self.verify_valid_flag('-h')
self.verify_valid_flag('-?')
self.verify_valid_flag('--help')

def test_help_env(self):
self.verify_valid_flag('--help-env')

def test_help_xoptions(self):
self.verify_valid_flag('--help-xoptions')

def test_help_all(self):
self.verify_valid_flag('--help-all')
merwok marked this conversation as resolved.
Show resolved Hide resolved

def test_optimize(self):
self.verify_valid_flag('-O')
self.verify_valid_flag('-OO')
Expand Down Expand Up @@ -89,9 +103,9 @@ def get_xoptions(*args):
@unittest.skipIf(interpreter_requires_environment(),
'Cannot run -E tests when PYTHON env vars are required.')
def test_unknown_xoptions(self):
rc, out, err = assert_python_failure('-X', 'blech')
_, 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 @@ -132,7 +146,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 @@ -234,7 +247,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
@@ -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
Expand Up @@ -66,10 +66,10 @@ python \- an interpreted, interactive, object-oriented programming language
.B \-x
]
[
[
.B \-X
.I option
]
[
merwok marked this conversation as resolved.
Show resolved Hide resolved
.B \-?
]
.br
Expand All @@ -81,6 +81,19 @@ python \- an interpreted, interactive, object-oriented programming language
|
.I never
]
.br
[
.B \--help
]
[
.B \--help-env
]
[
.B \--help-xoptions
]
[
.B \--help-all
]
Copy link
Member Author

Choose a reason for hiding this comment

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

I thought showing all help options on their own line could be nice.

.br
[
.B \-c
Expand Down Expand Up @@ -146,6 +159,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 @@ -279,7 +302,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
6 changes: 5 additions & 1 deletion Python/getopt.c
Expand Up @@ -44,8 +44,12 @@ static const wchar_t *opt_ptr = L"";
#define SHORT_OPTS L"bBc:dEhiIJm:OqRsStuvVW: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
109 changes: 84 additions & 25 deletions Python/initconfig.c
Expand Up @@ -28,9 +28,10 @@
static const char usage_line[] =
"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";

/* Long usage message, split into parts < 512 bytes */
/* Long help messages, split into parts < 512 bytes */
/* Lines sorted by option name; keep in sync with usage_envvars* below */
static const char usage_1[] = "\
Options and arguments (and corresponding environment variables):\n\
Options (and corresponding environment variables):\n\
-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
and comparing bytes/bytearray with str. (-bb: issue errors)\n\
-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
Expand All @@ -39,6 +40,9 @@ Options and arguments (and corresponding environment variables):\n\
debug builds); also PYTHONDEBUG=x\n\
-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
-h : print this help message and exit (also --help)\n\
--help-env : print help about Python-specific environment variables and exit\n\
merwok marked this conversation as resolved.
Show resolved Hide resolved
--help-xoptions : print help about implementation-specific -X options and exit\n\
--help-all : print complete help information and exit\n\
";
static const char usage_2[] = "\
ericsnowcurrently marked this conversation as resolved.
Show resolved Hide resolved
-i : inspect interactively after running script; forces a prompt even\n\
Expand All @@ -63,8 +67,19 @@ static const char usage_3[] = "\
-W arg : warning control; arg is action:message:category:module:lineno\n\
also PYTHONWARNINGS=arg\n\
-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
-X opt : set implementation-specific option. The following options are available:\n\
\n\
-X opt : set implementation-specific option\n\
Copy link
Member

Choose a reason for hiding this comment

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

--help-xoptions is listed a few items below, but if scanning the list it might be helpful to explicitly mention it here. (Sorry if it's been suggested before & declined!).

Suggested change
-X opt : set implementation-specific option\n\
-X opt : set implementation-specific option (see --help-xoptions)\n\

Copy link
Member Author

@merwok merwok May 30, 2022

Choose a reason for hiding this comment

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

I’ve added it and removed it. In the current version, I think it is not needed, as it is a few lines later and in the man page and shown in error message for unknown X option, but have no problem adding it if someone adds 👍🏽 to your comment 🙂

--check-hash-based-pycs always|default|never :\n\
control how Python invalidates hash-based .pyc files\n\
";
static const char usage_4[] = "\
Arguments:\n\
merwok marked this conversation as resolved.
Show resolved Hide resolved
file : program read from script file\n\
- : program read from stdin (default; interactive mode if a tty)\n\
arg ...: arguments passed to program in sys.argv[1:]\n\
";

static const char usage_xoptions[] = "\
merwok marked this conversation as resolved.
Show resolved Hide resolved
The following implementation-specific options are available:\n\
-X faulthandler: enable faulthandler\n\
-X showrefcount: output the total reference count and number of used\n\
memory blocks when the program finishes or after each statement in the\n\
Expand Down Expand Up @@ -98,29 +113,23 @@ static const char usage_3[] = "\
files are desired as well as suppressing the extra visual location indicators \n\
when the interpreter displays tracebacks.\n\
-X frozen_modules=[on|off]: whether or not frozen modules should be used.\n\
The default is \"on\" (or \"off\" if you are running a local build).\n\
\n\
--check-hash-based-pycs always|default|never:\n\
control how Python invalidates hash-based .pyc files\n\
";
static const char usage_4[] = "\
file : program read from script file\n\
- : program read from stdin (default; interactive mode if a tty)\n\
arg ...: arguments passed to program in sys.argv[1:]\n\n\
Other environment variables:\n\
The default is \"on\" (or \"off\" if you are running a local build).";

/* Envvars that don't have equivalent command-line options are listed first */
static const char usage_envvars1[] = "\
Environment variables that change behavior:\n\
PYTHONSTARTUP: file executed on interactive startup (no default)\n\
PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
default module search path. The result is sys.path.\n\
";
static const char usage_5[] =
default module search path. The result is sys.path.\n";
static const char usage_envvars2[] =
"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
" The default module search path uses %s.\n"
"PYTHONPLATLIBDIR : override sys.platlibdir.\n"
"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n"
"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
static const char usage_6[] =
static const char usage_envvars3[] =
"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
" to seed the hashes of str and bytes objects. It can also be set to an\n"
" integer in the range [0,4294967295] to get hash values with a\n"
Expand All @@ -130,7 +139,8 @@ static const char usage_6[] =
" hooks.\n"
"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
" locale coercion and locale compatibility warnings on stderr.\n"
" locale coercion and locale compatibility warnings on stderr.";
static const char usage_envvars4[] =
"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
" debugger. It can be set to the callable of your debugger of choice.\n"
"PYTHONDEVMODE: enable the development mode.\n"
Expand All @@ -141,6 +151,16 @@ static const char usage_6[] =
" and end column offset) to every instruction in code objects. This is useful \n"
" when smaller cothe de objects and pyc files are desired as well as suppressing the \n"
" extra visual location indicators when the interpreter displays tracebacks.\n";
merwok marked this conversation as resolved.
Show resolved Hide resolved
static const char usage_envvars5[] = "\
These variables have equivalent command-line parameters (see --help for details):\n\
PYTHONDEBUG : enable parser debug mode (-d)\n\
PYTHONDONTWRITEBYTECODE : don't write .pyc files (-B)\n\
PYTHONINSPECT : inspect interactively after running script (-i)\n\
PYTHONNOUSERSITE : disable user site directory (-s)\n\
PYTHONOPTIMIZE : enable level 1 optimizations (-O)\n\
PYTHONUNBUFFERED : disable stdout/stderr buffering (-u)\n\
PYTHONVERBOSE : trace import statements (-v)\n\
PYTHONWARNINGS=arg : warning control (-W arg)";

#if defined(MS_WINDOWS)
# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
Expand Down Expand Up @@ -2060,7 +2080,7 @@ config_read(PyConfig *config, int compute_path_config)
/* -X options */
const wchar_t* option = _Py_check_xoptions(&config->xoptions, known_xoptions);
if (option != NULL) {
return PyStatus_Error("Unknown value for option -X");
return PyStatus_Error("Unknown value for option -X (see --help-xoptions)");
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Turns out that showing the invalid value in this error message is not trivial: real C programmers had issue with it too before #28823


if (config_get_xoption(config, L"showrefcount")) {
Expand Down Expand Up @@ -2216,12 +2236,36 @@ config_usage(int error, const wchar_t* program)
fputs(usage_1, f);
fputs(usage_2, f);
fputs(usage_3, f);
fprintf(f, usage_4, (wint_t)DELIM);
fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
fputs(usage_6, f);
fputs(usage_4, f);
}
}

static void
config_envvars_usage()
{
printf(usage_envvars1, (wint_t)DELIM);
printf(usage_envvars2, (wint_t)DELIM, PYTHONHOMEHELP);
puts(usage_envvars3);
puts(usage_envvars4);
puts(usage_envvars5);
}

static void
config_xoptions_usage()
{
puts(usage_xoptions);
}

static void
config_complete_usage(const wchar_t* program)
{
config_usage(0, program);
puts("\n");
merwok marked this conversation as resolved.
Show resolved Hide resolved
config_envvars_usage();
puts("\n");
merwok marked this conversation as resolved.
Show resolved Hide resolved
config_xoptions_usage();
}
merwok marked this conversation as resolved.
Show resolved Hide resolved


/* Parse the command line arguments */
static PyStatus
Expand Down Expand Up @@ -2273,9 +2317,9 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
}

switch (c) {
// Integers represent long options, see Python/getopt.c
case 0:
// Handle long option.
assert(longindex == 0); // Only one long option now.
// check-hash-based-pycs
if (wcscmp(_PyOS_optarg, L"always") == 0
|| wcscmp(_PyOS_optarg, L"never") == 0
|| wcscmp(_PyOS_optarg, L"default") == 0)
Expand All @@ -2293,6 +2337,21 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
}
break;

case 1:
// help-all
config_complete_usage(program);
return _PyStatus_EXIT(0);

case 2:
// help-env
config_envvars_usage();
return _PyStatus_EXIT(0);

case 3:
// help-xoptions
config_xoptions_usage();
return _PyStatus_EXIT(0);

case 'b':
config->bytes_warning++;
break;
Expand Down