From 225c869dce97fa190a47fa9361afd942ba6b79c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sun, 2 Jan 2022 00:57:11 -0500 Subject: [PATCH 01/26] move list of X options out of help output --- Doc/using/cmdline.rst | 5 +++++ Python/initconfig.c | 27 +++++++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index d341ea8bb43c88..feeca0d9e59ed5 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -436,6 +436,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 @@ -447,6 +448,7 @@ Miscellaneous options Reserved for various implementation-specific options. CPython currently defines the following possible values: + * ``-X help`` to print a short description of all X options; * ``-X faulthandler`` to enable :mod:`faulthandler`; * ``-X showrefcount`` to output the total reference count and number of used memory blocks when the program finishes or after each statement in the @@ -528,6 +530,9 @@ Miscellaneous options .. versionadded:: 3.11 The ``-X frozen_modules`` option. + .. versionadded:: 3.11 + The ``-X help`` option. + Options you shouldn't use ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Python/initconfig.c b/Python/initconfig.c index 47ebc64c8470a9..e30b6e4fa2f812 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -63,8 +63,12 @@ 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 (see details with -X help)\n\ +--check-hash-based-pycs always|default|never:\n\ + control how Python invalidates hash-based .pyc files\n\ +"; +static const char usage_xoptions[] = "\ +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\ @@ -99,9 +103,6 @@ static const char usage_3[] = "\ 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\ @@ -2005,6 +2006,7 @@ _PyConfig_InitImportConfig(PyConfig *config) // set, like -X showrefcount which requires a debug build. In this case unknown // options are silently ignored. const wchar_t* known_xoptions[] = { + L"help", L"faulthandler", L"showrefcount", L"tracemalloc", @@ -2222,6 +2224,11 @@ config_usage(int error, const wchar_t* program) } } +static void +config_xoptions_usage() +{ + fputs(usage_xoptions, stdout); +} /* Parse the command line arguments */ static PyStatus @@ -2308,7 +2315,6 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, case 'E': case 'I': - case 'X': /* option handled by _PyPreCmdline_Read() */ break; @@ -2370,6 +2376,15 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, config->use_hash_seed = 0; break; + case 'X': + const wchar_t *xoption = config_get_xoption(config, L"help"); + if (xoption) { + config_xoptions_usage(); + return _PyStatus_EXIT(0); + } + /* option handled by _PyPreCmdline_Read() */ + break; + /* This space reserved for other options */ default: From eaefd1a17716028d56f64c59711bc0c1101e667f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sun, 2 Jan 2022 13:02:02 -0500 Subject: [PATCH 02/26] mention help option in fatal error message --- Lib/test/test_cmd_line.py | 13 ++++++++++--- Python/initconfig.c | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 86ee27485c9642..b77de2e760fcc6 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -89,12 +89,20 @@ 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 -X help)' self.assertEqual(err.splitlines().count(msg), 1) self.assertEqual(b'', out) + @unittest.skipIf(interpreter_requires_environment(), + 'Cannot run -E tests when PYTHON env vars are required.') + def test_xoptions_help(self): + _, out, err = assert_python_ok('-X', 'help') + self.assertIn(b'implementation-specific options are available', out) + self.assertIn(b'-X faulthandler: enable faulthandler', out) + self.assertEqual(b'', err) + def test_showrefcount(self): def run_python(*args): # this is similar to assert_python_ok but doesn't strip @@ -234,7 +242,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] diff --git a/Python/initconfig.c b/Python/initconfig.c index e30b6e4fa2f812..a2bf9681655db2 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -2062,7 +2062,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 -X help)"); } if (config_get_xoption(config, L"showrefcount")) { From 57fd33b504efac8d87cb06f5ab772acf89e912e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sun, 2 Jan 2022 13:20:15 -0500 Subject: [PATCH 03/26] move variable declaration out of case block --- Python/initconfig.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index a2bf9681655db2..2c18addef3d259 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -2239,6 +2239,7 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, const PyWideStringList *argv = &config->argv; int print_version = 0; const wchar_t* program = config->program_name; + const wchar_t* xoption_help; _PyOS_ResetGetOpt(); do { @@ -2377,8 +2378,8 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, break; case 'X': - const wchar_t *xoption = config_get_xoption(config, L"help"); - if (xoption) { + xoption_help = config_get_xoption(config, L"help"); + if (xoption_help) { config_xoptions_usage(); return _PyStatus_EXIT(0); } From 55dbf698193f32974337752605316030da04d74f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sun, 2 Jan 2022 18:15:20 -0500 Subject: [PATCH 04/26] move extra envvars help to separate option --- .../2022-01-02-14-53-59.bpo-46142.WayjgT.rst | 2 + Misc/python.man | 19 ++++++- Python/getopt.c | 1 + Python/initconfig.c | 51 ++++++++++++++----- 4 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst new file mode 100644 index 00000000000000..83e9945111d6fa --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst @@ -0,0 +1,2 @@ +Add ``-X help`` and ``--help-env`` options and make ``--help`` output +shorter. diff --git a/Misc/python.man b/Misc/python.man index 45a49271d4dfe3..f6cdcd62362b48 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -66,10 +66,10 @@ python \- an interpreted, interactive, object-oriented programming language .B \-x ] [ -[ .B \-X .I option ] +[ .B \-? ] .br @@ -81,6 +81,16 @@ python \- an interpreted, interactive, object-oriented programming language | .I never ] +.br + [ +.B \--help +] +[ +.B \--help-env +] +[ +.B \-X help +] .br [ .B \-c @@ -146,6 +156,9 @@ the behavior of the interpreter. .B \-h ", " \-? ", "\-\-help Prints the usage for the interpreter executable and exits. .TP +.B \-\-help\-env +Prints help about environment variables 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 @@ -279,7 +292,9 @@ 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 help: show help about available options -X faulthandler: enable faulthandler diff --git a/Python/getopt.c b/Python/getopt.c index 2e3891aae2d16a..8e16be03f9aaec 100644 --- a/Python/getopt.c +++ b/Python/getopt.c @@ -45,6 +45,7 @@ static const wchar_t *opt_ptr = L""; static const _PyOS_LongOption longopts[] = { {L"check-hash-based-pycs", 1, 0}, + {L"help-env", 0, 0}, {NULL, 0, 0}, }; diff --git a/Python/initconfig.c b/Python/initconfig.c index 2c18addef3d259..f764eb11693c5d 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -64,11 +64,19 @@ static const char usage_3[] = "\ 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 (see details with -X help)\n\ ---check-hash-based-pycs always|default|never:\n\ +--help-env : print help about other environment variables\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\ +"; + static const char usage_xoptions[] = "\ The following implementation-specific options are available:\n\ + -X help: show this help\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\ @@ -104,16 +112,13 @@ The following implementation-specific options are available:\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\ "; -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\ +static const char usage_envvars1[] = "\ +Environment variables that change behavior (see also --help):\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[] = +static const char usage_envvars2[] = "PYTHONHOME : alternate directory (or %lc).\n" " The default module search path uses %s.\n" "PYTHONPLATLIBDIR : override sys.platlibdir.\n" @@ -121,7 +126,7 @@ static const char usage_5[] = "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" @@ -2218,16 +2223,24 @@ 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() +{ + FILE *f = stdout; + fprintf(f, usage_envvars1, (wint_t)DELIM); + fprintf(f, usage_envvars2, (wint_t)DELIM, PYTHONHOMEHELP); + fputs(usage_envvars3, f); +} + static void config_xoptions_usage() { - fputs(usage_xoptions, stdout); + FILE *f = stdout; + fputs(usage_xoptions, f); } /* Parse the command line arguments */ @@ -2282,8 +2295,11 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, switch (c) { case 0: - // Handle long option. - assert(longindex == 0); // Only one long option now. + // Handle long options. + assert(longindex < 2); // Only two long options for now. + switch(longindex) { + case 0: + // check-hash-based-pycs if (wcscmp(_PyOS_optarg, L"always") == 0 || wcscmp(_PyOS_optarg, L"never") == 0 || wcscmp(_PyOS_optarg, L"default") == 0) @@ -2300,6 +2316,13 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, return _PyStatus_EXIT(2); } break; + case 1: + // help-env + config_envvars_usage(); + return _PyStatus_EXIT(0); + break; + } + break; case 'b': config->bytes_warning++; From 0aaf9afd3713da2bb16f9f4de54782addd060df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sun, 2 Jan 2022 18:22:11 -0500 Subject: [PATCH 05/26] doc --- Doc/using/cmdline.rst | 12 +++++++++++- .../2022-01-02-14-53-59.bpo-46142.WayjgT.rst | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index feeca0d9e59ed5..33cc49dacec710 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -183,6 +183,8 @@ automatically enabled, if available on your platform (see Automatic enabling of tab-completion and history editing. +.. _using-on-generic-options: + Generic options ~~~~~~~~~~~~~~~ @@ -190,8 +192,12 @@ Generic options -h --help - Print a short description of all command line options. + Print a short description of all command line options and related + environment variables. + +.. cmdoption:: --help-env + Print a short description of additional environment variables. .. cmdoption:: -V --version @@ -212,6 +218,10 @@ Generic options .. versionadded:: 3.6 The ``-VV`` option. + .. versionadded:: 3.11 + The ``--help-env`` option. + + .. _using-on-misc-options: Miscellaneous options diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst index 83e9945111d6fa..a1da3f46bc5516 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst @@ -1,2 +1,2 @@ -Add ``-X help`` and ``--help-env`` options and make ``--help`` output -shorter. +Make ``--help`` output shorter by moving some info to the new +``--help-env`` and ``-X help`` options. From a592003c5a4a9ae4ef990b496c67dc6f6bbbd393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sun, 2 Jan 2022 18:26:16 -0500 Subject: [PATCH 06/26] add minimal tests --- Lib/test/test_cmd_line.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index b77de2e760fcc6..4b59475a7b756a 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -37,6 +37,14 @@ 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_optimize(self): self.verify_valid_flag('-O') self.verify_valid_flag('-OO') From 1c4cf637eac02d11c2b0dad532a231d60bc080c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sun, 2 Jan 2022 18:34:35 -0500 Subject: [PATCH 07/26] flatten the sub-switch --- Python/getopt.c | 4 ++-- Python/initconfig.c | 10 +++------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Python/getopt.c b/Python/getopt.c index 8e16be03f9aaec..97123729eb6d11 100644 --- a/Python/getopt.c +++ b/Python/getopt.c @@ -45,8 +45,8 @@ static const wchar_t *opt_ptr = L""; static const _PyOS_LongOption longopts[] = { {L"check-hash-based-pycs", 1, 0}, - {L"help-env", 0, 0}, - {NULL, 0, 0}, + {L"help-env", 0, 1}, + {NULL, 0, -1}, }; diff --git a/Python/initconfig.c b/Python/initconfig.c index f764eb11693c5d..3a7679affa835e 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -2294,11 +2294,8 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, } switch (c) { + // Integers represent long options, see Python/getopt.c case 0: - // Handle long options. - assert(longindex < 2); // Only two long options for now. - switch(longindex) { - case 0: // check-hash-based-pycs if (wcscmp(_PyOS_optarg, L"always") == 0 || wcscmp(_PyOS_optarg, L"never") == 0 @@ -2316,13 +2313,12 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, return _PyStatus_EXIT(2); } break; - case 1: + + case 1: // help-env config_envvars_usage(); return _PyStatus_EXIT(0); break; - } - break; case 'b': config->bytes_warning++; From d8bfcffbab749754c159a240acc2cc7b5a5fa9dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric?= Date: Mon, 3 Jan 2022 12:46:54 -0500 Subject: [PATCH 08/26] suggestion from Barry Co-authored-by: Barry Warsaw --- Doc/using/cmdline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 33cc49dacec710..47785e3562962f 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -458,7 +458,7 @@ Miscellaneous options Reserved for various implementation-specific options. CPython currently defines the following possible values: - * ``-X help`` to print a short description of all X options; + * ``-X help`` to print a short description of all ``-X`` options; * ``-X faulthandler`` to enable :mod:`faulthandler`; * ``-X showrefcount`` to output the total reference count and number of used memory blocks when the program finishes or after each statement in the From 38f2dd87d280ce452600b67b11164e6a4f2719f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric?= Date: Mon, 3 Jan 2022 12:51:42 -0500 Subject: [PATCH 09/26] more suggestions from flufl --- Doc/using/cmdline.rst | 2 +- Python/initconfig.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 47785e3562962f..c45e921ad5c549 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -192,7 +192,7 @@ Generic options -h --help - Print a short description of all command line options and related + Print a short description of all command line options and corresponding environment variables. .. cmdoption:: --help-env diff --git a/Python/initconfig.c b/Python/initconfig.c index 3a7679affa835e..c573451c7aa814 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -76,7 +76,7 @@ arg ...: arguments passed to program in sys.argv[1:]\n\ static const char usage_xoptions[] = "\ The following implementation-specific options are available:\n\ - -X help: show this help\n\ + -X help: show this help and exit\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\ From a828fe81cb21756005943b098b9cfaa5f7036b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Fri, 7 Jan 2022 17:06:37 -0500 Subject: [PATCH 10/26] remove unnecessary --- Python/initconfig.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index c573451c7aa814..c2291791cd415f 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -2318,7 +2318,6 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, // help-env config_envvars_usage(); return _PyStatus_EXIT(0); - break; case 'b': config->bytes_warning++; From 8bde4ecec290cb4c4221202b1c5ea22da3fdd424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Fri, 7 Jan 2022 17:33:31 -0500 Subject: [PATCH 11/26] mention all envvars in --help-env --- Doc/using/cmdline.rst | 2 +- Misc/python.man | 2 +- Python/initconfig.c | 28 ++++++++++++++++++++++++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index c45e921ad5c549..7096e8dad94202 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -197,7 +197,7 @@ Generic options .. cmdoption:: --help-env - Print a short description of additional environment variables. + Print a short description of Python-specific environment variables. .. cmdoption:: -V --version diff --git a/Misc/python.man b/Misc/python.man index f6cdcd62362b48..153c3b0cf42379 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -157,7 +157,7 @@ the behavior of the interpreter. Prints the usage for the interpreter executable and exits. .TP .B \-\-help\-env -Prints help about environment variables and exits. +Prints help about Python-specific environment variables and exits. .TP .B \-i When a script is passed as first argument or the \fB\-c\fP option is diff --git a/Python/initconfig.c b/Python/initconfig.c index c2291791cd415f..18489d47c066db 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -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\ @@ -64,11 +65,12 @@ static const char usage_3[] = "\ 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 (see details with -X help)\n\ ---help-env : print help about other environment variables\n\ +--help-env : print help about Python-specific environment variables\n\ --check-hash-based-pycs always|default|never :\n\ control how Python invalidates hash-based .pyc files\n\ "; static const char usage_4[] = "\ +Arguments:\n\ 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\ @@ -112,8 +114,10 @@ The following implementation-specific options are available:\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\ "; + +/* Envvars that don't have equivalent command-line options are listed first */ static const char usage_envvars1[] = "\ -Environment variables that change behavior (see also --help):\n\ +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\ @@ -137,6 +141,8 @@ static const char usage_envvars3[] = "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" +; +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" @@ -147,6 +153,18 @@ static const char usage_envvars3[] = " 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"; +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)\n\ +\n\ +"; #if defined(MS_WINDOWS) # define PYTHONHOMEHELP "\\python{major}{minor}" @@ -2234,6 +2252,8 @@ config_envvars_usage() fprintf(f, usage_envvars1, (wint_t)DELIM); fprintf(f, usage_envvars2, (wint_t)DELIM, PYTHONHOMEHELP); fputs(usage_envvars3, f); + fputs(usage_envvars4, f); + fputs(usage_envvars5, f); } static void From 0dbaf0370fe910ef057a2529d5051a8ceed9ade5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Fri, 7 Jan 2022 17:37:06 -0500 Subject: [PATCH 12/26] mistake --- Python/initconfig.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index 18489d47c066db..9f3f2fafb4090d 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -163,7 +163,6 @@ 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)\n\ -\n\ "; #if defined(MS_WINDOWS) From 0c9a995fe668900f09fe890de38eacf91bf510f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Tue, 11 Jan 2022 19:57:59 -0500 Subject: [PATCH 13/26] introduce --help-xoptions --- Doc/using/cmdline.rst | 20 +++++++++------ Lib/test/test_cmd_line.py | 2 +- .../2022-01-02-14-53-59.bpo-46142.WayjgT.rst | 2 +- Misc/python.man | 9 ++++--- Python/getopt.c | 1 + Python/initconfig.c | 25 ++++++++----------- 6 files changed, 30 insertions(+), 29 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 7096e8dad94202..3276fad322ec96 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -193,11 +193,21 @@ Generic options --help Print a short description of all command line options and corresponding - environment variables. + environment variables and exit. .. cmdoption:: --help-env - Print a short description of Python-specific environment variables. + 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:: -V --version @@ -218,9 +228,6 @@ Generic options .. versionadded:: 3.6 The ``-VV`` option. - .. versionadded:: 3.11 - The ``--help-env`` option. - .. _using-on-misc-options: @@ -458,7 +465,6 @@ Miscellaneous options Reserved for various implementation-specific options. CPython currently defines the following possible values: - * ``-X help`` to print a short description of all ``-X`` options; * ``-X faulthandler`` to enable :mod:`faulthandler`; * ``-X showrefcount`` to output the total reference count and number of used memory blocks when the program finishes or after each statement in the @@ -540,8 +546,6 @@ Miscellaneous options .. versionadded:: 3.11 The ``-X frozen_modules`` option. - .. versionadded:: 3.11 - The ``-X help`` option. Options you shouldn't use diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 4b59475a7b756a..a46dbac5781f1f 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -99,7 +99,7 @@ def get_xoptions(*args): def test_unknown_xoptions(self): _, 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 (see -X help)' + msg = b'Fatal Python error: Unknown value for option -X (see --help-xoptions)' self.assertEqual(err.splitlines().count(msg), 1) self.assertEqual(b'', out) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst index a1da3f46bc5516..b5b6910ac68f97 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst @@ -1,2 +1,2 @@ Make ``--help`` output shorter by moving some info to the new -``--help-env`` and ``-X help`` options. +``--help-env`` and ``--help-xoptions`` command-line options. diff --git a/Misc/python.man b/Misc/python.man index 153c3b0cf42379..a32aec78c97817 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -89,7 +89,7 @@ python \- an interpreted, interactive, object-oriented programming language .B \--help-env ] [ -.B \-X help +.B \--help-xoptions ] .br [ @@ -156,9 +156,12 @@ the behavior of the interpreter. .B \-h ", " \-? ", "\-\-help Prints the usage for the interpreter executable and exits. .TP -.B \-\-help\-env +.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 .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 @@ -294,8 +297,6 @@ a regular expression on the warning message. .BI "\-X " option Set implementation-specific option. The following options are available: - -X help: show help about available options - -X faulthandler: enable faulthandler -X showrefcount: output the total reference count and number of used diff --git a/Python/getopt.c b/Python/getopt.c index 97123729eb6d11..77da837a4e3876 100644 --- a/Python/getopt.c +++ b/Python/getopt.c @@ -46,6 +46,7 @@ static const wchar_t *opt_ptr = L""; static const _PyOS_LongOption longopts[] = { {L"check-hash-based-pycs", 1, 0}, {L"help-env", 0, 1}, + {L"help-xoptions", 0, 2}, {NULL, 0, -1}, }; diff --git a/Python/initconfig.c b/Python/initconfig.c index 9f3f2fafb4090d..31524b54601cb6 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -40,6 +40,8 @@ Options (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\ +--help-xoptions : print help about implementation-specific -X options and exit\n\ "; static const char usage_2[] = "\ -i : inspect interactively after running script; forces a prompt even\n\ @@ -64,8 +66,7 @@ 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 (see details with -X help)\n\ ---help-env : print help about Python-specific environment variables\n\ +-X opt : set implementation-specific option\n\ --check-hash-based-pycs always|default|never :\n\ control how Python invalidates hash-based .pyc files\n\ "; @@ -78,7 +79,6 @@ arg ...: arguments passed to program in sys.argv[1:]\n\ static const char usage_xoptions[] = "\ The following implementation-specific options are available:\n\ - -X help: show this help and exit\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\ @@ -2028,7 +2028,6 @@ _PyConfig_InitImportConfig(PyConfig *config) // set, like -X showrefcount which requires a debug build. In this case unknown // options are silently ignored. const wchar_t* known_xoptions[] = { - L"help", L"faulthandler", L"showrefcount", L"tracemalloc", @@ -2084,7 +2083,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 (see -X help)"); + return PyStatus_Error("Unknown value for option -X (see --help-xoptions)"); } if (config_get_xoption(config, L"showrefcount")) { @@ -2271,7 +2270,6 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, const PyWideStringList *argv = &config->argv; int print_version = 0; const wchar_t* program = config->program_name; - const wchar_t* xoption_help; _PyOS_ResetGetOpt(); do { @@ -2338,6 +2336,11 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, config_envvars_usage(); return _PyStatus_EXIT(0); + case 2: + // help-xoptions + config_xoptions_usage(); + return _PyStatus_EXIT(0); + case 'b': config->bytes_warning++; break; @@ -2353,6 +2356,7 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, case 'E': case 'I': + case 'X': /* option handled by _PyPreCmdline_Read() */ break; @@ -2414,15 +2418,6 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, config->use_hash_seed = 0; break; - case 'X': - xoption_help = config_get_xoption(config, L"help"); - if (xoption_help) { - config_xoptions_usage(); - return _PyStatus_EXIT(0); - } - /* option handled by _PyPreCmdline_Read() */ - break; - /* This space reserved for other options */ default: From aab464fb35f081df4c993ce23e3759778bbc7a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Tue, 11 Jan 2022 20:11:08 -0500 Subject: [PATCH 14/26] add --help-all --- Doc/using/cmdline.rst | 6 ++++++ Lib/test/test_cmd_line.py | 15 ++++++-------- .../2022-01-02-14-53-59.bpo-46142.WayjgT.rst | 1 + Misc/python.man | 7 +++++++ Python/getopt.c | 8 +++++--- Python/initconfig.c | 20 ++++++++++++++++++- 6 files changed, 44 insertions(+), 13 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 3276fad322ec96..9d23d2e4ed0004 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -209,6 +209,12 @@ Generic options .. versionadded:: 3.11 +.. cmdoption:: --help-all + + Print complete usage information and exit. + + .. versionadded:: 3.11 + .. cmdoption:: -V --version diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index a46dbac5781f1f..647ed8efce0584 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -45,6 +45,12 @@ def test_help(self): 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') + def test_optimize(self): self.verify_valid_flag('-O') self.verify_valid_flag('-OO') @@ -103,14 +109,6 @@ def test_unknown_xoptions(self): self.assertEqual(err.splitlines().count(msg), 1) self.assertEqual(b'', out) - @unittest.skipIf(interpreter_requires_environment(), - 'Cannot run -E tests when PYTHON env vars are required.') - def test_xoptions_help(self): - _, out, err = assert_python_ok('-X', 'help') - self.assertIn(b'implementation-specific options are available', out) - self.assertIn(b'-X faulthandler: enable faulthandler', out) - self.assertEqual(b'', err) - def test_showrefcount(self): def run_python(*args): # this is similar to assert_python_ok but doesn't strip @@ -148,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) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst index b5b6910ac68f97..3c62c54289946c 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-01-02-14-53-59.bpo-46142.WayjgT.rst @@ -1,2 +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. diff --git a/Misc/python.man b/Misc/python.man index a32aec78c97817..5ee6c9fc004ad3 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -91,6 +91,9 @@ python \- an interpreted, interactive, object-oriented programming language [ .B \--help-xoptions ] +[ +.B \--help-all +] .br [ .B \-c @@ -162,6 +165,10 @@ Prints help about Python-specific environment variables and exits. .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 diff --git a/Python/getopt.c b/Python/getopt.c index 77da837a4e3876..8fa9cd737db305 100644 --- a/Python/getopt.c +++ b/Python/getopt.c @@ -44,10 +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}, - {L"help-env", 0, 1}, - {L"help-xoptions", 0, 2}, - {NULL, 0, -1}, + {L"help-all", 0, 1}, + {L"help-env", 0, 2}, + {L"help-xoptions", 0, 3}, + {NULL, 0, -1}, /* sentinel */ }; diff --git a/Python/initconfig.c b/Python/initconfig.c index 31524b54601cb6..8cab154affc0e9 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -42,6 +42,7 @@ Options (and corresponding environment variables):\n\ -h : print this help message and exit (also --help)\n\ --help-env : print help about Python-specific environment variables and exit\n\ --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[] = "\ -i : inspect interactively after running script; forces a prompt even\n\ @@ -2261,6 +2262,18 @@ config_xoptions_usage() fputs(usage_xoptions, f); } +static void +config_complete_usage(const wchar_t* program) +{ + FILE *f = stdout; + config_usage(0, program); + fputs("\n", f); + config_envvars_usage(); + fputs("\n", f); + config_xoptions_usage(); +} + + /* Parse the command line arguments */ static PyStatus config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, @@ -2332,11 +2345,16 @@ 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 2: + case 3: // help-xoptions config_xoptions_usage(); return _PyStatus_EXIT(0); From b9a0b19e328c66039ac7d71512e5e3f91c57ebc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sat, 15 Jan 2022 00:26:54 -0500 Subject: [PATCH 15/26] replace fprintf by printf; remove extra blanklines --- Python/initconfig.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index 8cab154affc0e9..5378faebaef142 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -113,16 +113,14 @@ The following implementation-specific options are available:\n\ 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\ -"; + 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\ -"; + default module search path. The result is sys.path.\n"; static const char usage_envvars2[] = "PYTHONHOME : alternate directory (or %lc).\n" " The default module search path uses %s.\n" @@ -141,8 +139,7 @@ static const char usage_envvars3[] = " 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" @@ -163,8 +160,7 @@ 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)\n\ -"; +PYTHONWARNINGS=arg : warning control (-W arg)"; #if defined(MS_WINDOWS) # define PYTHONHOMEHELP "\\python{major}{minor}" @@ -2247,29 +2243,26 @@ config_usage(int error, const wchar_t* program) static void config_envvars_usage() { - FILE *f = stdout; - fprintf(f, usage_envvars1, (wint_t)DELIM); - fprintf(f, usage_envvars2, (wint_t)DELIM, PYTHONHOMEHELP); - fputs(usage_envvars3, f); - fputs(usage_envvars4, f); - fputs(usage_envvars5, f); + 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() { - FILE *f = stdout; - fputs(usage_xoptions, f); + puts(usage_xoptions); } static void config_complete_usage(const wchar_t* program) { - FILE *f = stdout; config_usage(0, program); - fputs("\n", f); + puts("\n"); config_envvars_usage(); - fputs("\n", f); + puts("\n"); config_xoptions_usage(); } From 4f345e8a0a854c688149f4fe4cba6a95a4fae3bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Mon, 23 May 2022 15:48:14 +0200 Subject: [PATCH 16/26] check return code in verify_valid_flag --- Lib/test/test_cmd_line.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 6230e22fc58c15..dceb2350cb77a9 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -28,6 +28,7 @@ def _kill_python_and_exit_code(p): returncode = p.wait() return data, returncode + class CmdLineTest(unittest.TestCase): def test_directories(self): assert_python_failure('.') @@ -35,6 +36,7 @@ def test_directories(self): def verify_valid_flag(self, cmd_line): rc, out, err = assert_python_ok(*cmd_line) + self.assertEqual(rc, 0) self.assertTrue(out == b'' or out.endswith(b'\n')) self.assertNotIn(b'Traceback', out) self.assertNotIn(b'Traceback', err) @@ -62,6 +64,7 @@ def test_site_flag(self): def test_usage(self): rc, out, err = assert_python_ok('-h') + self.assertEqual(rc, 0) lines = out.splitlines() self.assertIn(b'usage', lines[0]) # The first line contains the program name, @@ -72,6 +75,7 @@ def test_version(self): version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii") for switch in '-V', '--version', '-VV': rc, out, err = assert_python_ok(switch) + self.assertEqual(rc, 0) self.assertFalse(err.startswith(version)) self.assertTrue(out.startswith(version)) @@ -105,7 +109,8 @@ def get_xoptions(*args): @unittest.skipIf(interpreter_requires_environment(), 'Cannot run -E tests when PYTHON env vars are required.') def test_unknown_xoptions(self): - _, out, err = assert_python_failure('-X', 'blech') + rc, out, err = assert_python_failure('-X', 'blech') + self.assertEqual(rc, 1) self.assertIn(b'Unknown value for option -X', err) msg = b'Fatal Python error: Unknown value for option -X (see --help-xoptions)' self.assertEqual(err.splitlines().count(msg), 1) @@ -183,7 +188,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 ./ @@ -907,6 +911,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, From a6573d6e1eaf266ba7b0a04f88efa879142d0d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Tue, 24 May 2022 19:47:07 +0200 Subject: [PATCH 17/26] remove duplicate check --- Lib/test/test_cmd_line.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index dceb2350cb77a9..e7cf553f7cacd2 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -35,8 +35,7 @@ def test_directories(self): assert_python_failure('< .') def verify_valid_flag(self, cmd_line): - rc, out, err = assert_python_ok(*cmd_line) - self.assertEqual(rc, 0) + _, 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) From da97a38495ea7cc09f9a1c8fa7779329d512cd65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Tue, 24 May 2022 19:49:02 +0200 Subject: [PATCH 18/26] fix some help texts in 80 columns --- Python/initconfig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index fc1c535cbabda2..53978272a47ab8 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -40,7 +40,7 @@ Options (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\ +--help-env : print help about Python environment variables and exit\n\ --help-xoptions : print help about implementation-specific -X options and exit\n\ --help-all : print complete help information and exit\n\ "; @@ -151,7 +151,7 @@ static const char usage_envvars4[] = "PYTHONNODEBUGRANGES: If this variable is set, it disables the inclusion of the \n" " tables mapping extra location information (end line, start column offset \n" " 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" +" when smaller code objects and pyc files are desired as well as suppressing the \n" " extra visual location indicators when the interpreter displays tracebacks.\n"; static const char usage_envvars5[] = "\ These variables have equivalent command-line parameters (see --help for details):\n\ From 98525b47c893989f8b25889b10e5e255a54e2f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 25 May 2022 11:35:01 +0200 Subject: [PATCH 19/26] remove needless checks --- Lib/test/test_cmd_line.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index e7cf553f7cacd2..566f92b3574198 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -35,7 +35,7 @@ def test_directories(self): assert_python_failure('< .') def verify_valid_flag(self, cmd_line): - _, 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) @@ -63,7 +63,6 @@ def test_site_flag(self): def test_usage(self): rc, out, err = assert_python_ok('-h') - self.assertEqual(rc, 0) lines = out.splitlines() self.assertIn(b'usage', lines[0]) # The first line contains the program name, @@ -74,7 +73,6 @@ def test_version(self): version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii") for switch in '-V', '--version', '-VV': rc, out, err = assert_python_ok(switch) - self.assertEqual(rc, 0) self.assertFalse(err.startswith(version)) self.assertTrue(out.startswith(version)) @@ -109,7 +107,6 @@ def get_xoptions(*args): 'Cannot run -E tests when PYTHON env vars are required.') def test_unknown_xoptions(self): rc, out, err = assert_python_failure('-X', 'blech') - self.assertEqual(rc, 1) self.assertIn(b'Unknown value for option -X', err) msg = b'Fatal Python error: Unknown value for option -X (see --help-xoptions)' self.assertEqual(err.splitlines().count(msg), 1) From 5585095e59815b0cba0c3a989c6262d45b473683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 25 May 2022 14:51:02 +0200 Subject: [PATCH 20/26] reformat and rearrange some help entries --- Misc/python.man | 14 +++++++- Python/initconfig.c | 83 +++++++++++++++++++++++++-------------------- 2 files changed, 60 insertions(+), 37 deletions(-) diff --git a/Misc/python.man b/Misc/python.man index 7c9e009beae0f3..e2f508d6710d8c 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -344,7 +344,19 @@ Set implementation-specific option. The following options are available: otherwise activate automatically). See PYTHONUTF8 for more details -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the - given directory instead of to the code tree. + given directory instead of to the code tree. + + -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None' + + -X no_debug_ranges: disable the inclusion of the tables mapping extra location + information (end line, start column offset and end column offset) to every + instruction in code objects. This is useful when smaller code objects and pyc + 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. + The default is "on" (or "off" if you are running a local build). + .TP .B \-x Skip the first line of the source. This is intended for a DOS diff --git a/Python/initconfig.c b/Python/initconfig.c index 53978272a47ab8..e9dcad171b691a 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -36,6 +36,8 @@ Options (and corresponding environment variables):\n\ and comparing bytes/bytearray with str. (-bb: issue errors)\n\ -B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\ -c cmd : program passed in as string (terminates option list)\n\ +--check-hash-based-pycs always|default|never :\n\ + control how Python invalidates hash-based .pyc files\n\ -d : turn on parser debugging output (for experts only, only works on\n\ debug builds); also PYTHONDEBUG=x\n\ -E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\ @@ -69,8 +71,6 @@ static const char usage_3[] = "\ 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\n\ ---check-hash-based-pycs always|default|never :\n\ - control how Python invalidates hash-based .pyc files\n\ "; static const char usage_4[] = "\ Arguments:\n\ @@ -81,40 +81,51 @@ arg ...: arguments passed to program in sys.argv[1:]\n\ static const char usage_xoptions[] = "\ 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\ - interactive interpreter. This only works on debug builds\n\ - -X tracemalloc: start tracing Python memory allocations using the\n\ - tracemalloc module. By default, only the most recent frame is stored in a\n\ - traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\ - traceback limit of NFRAME frames\n\ - -X importtime: show how long each import takes. It shows module name,\n\ - cumulative time (including nested imports) and self time (excluding\n\ - nested imports). Note that its output may be broken in multi-threaded\n\ - application. Typical usage is python3 -X importtime -c 'import asyncio'\n\ - -X dev: enable CPython's \"development mode\", introducing additional runtime\n\ - checks which are too expensive to be enabled by default. Effect of the\n\ - developer mode:\n\ - * Add default warning filter, as -W default\n\ - * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\ - * Enable the faulthandler module to dump the Python traceback on a crash\n\ - * Enable asyncio debug mode\n\ - * Set the dev_mode attribute of sys.flags to True\n\ - * io.IOBase destructor logs close() exceptions\n\ - -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\ - locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\ - otherwise activate automatically)\n\ - -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\ - given directory instead of to the code tree\n\ - -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None'\n\ - -X no_debug_ranges: disable the inclusion of the tables mapping extra location \n\ - information (end line, start column offset and end column offset) to every \n\ - instruction in code objects. This is useful when smaller code objects and pyc \n\ - 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\ +-X faulthandler: enable faulthandler\n\ +\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\ + interactive interpreter. This only works on debug builds\n\ +\n\ +-X tracemalloc: start tracing Python memory allocations using the\n\ + tracemalloc module. By default, only the most recent frame is stored in a\n\ + traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\ + traceback limit of NFRAME frames\n\ +\n\ +-X importtime: show how long each import takes. It shows module name,\n\ + cumulative time (including nested imports) and self time (excluding\n\ + nested imports). Note that its output may be broken in multi-threaded\n\ + application. Typical usage is python3 -X importtime -c 'import asyncio'\n\ +\n\ +-X dev: enable CPython's \"development mode\", introducing additional runtime\n\ + checks which are too expensive to be enabled by default. Effect of the\n\ + developer mode:\n\ + * Add default warning filter, as -W default\n\ + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks()\n\ + C function\n\ + * Enable the faulthandler module to dump the Python traceback on a crash\n\ + * Enable asyncio debug mode\n\ + * Set the dev_mode attribute of sys.flags to True\n\ + * io.IOBase destructor logs close() exceptions\n\ +\n\ +-X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\ + locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\ + otherwise activate automatically)\n\ +\n\ +-X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\ + given directory instead of to the code tree\n\ +\n\ +-X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None'\n\ +\n\ +-X no_debug_ranges: disable the inclusion of the tables mapping extra location \n\ + information (end line, start column offset and end column offset) to every \n\ + instruction in code objects. This is useful when smaller code objects and pyc \n\ + files are desired as well as suppressing the extra visual location indicators \n\ + when the interpreter displays tracebacks.\n\ +\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)."; /* Envvars that don't have equivalent command-line options are listed first */ static const char usage_envvars1[] = "\ From 24526bd8ad866804a7162b52a9904b0570584ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 25 May 2022 15:21:29 +0200 Subject: [PATCH 21/26] fix formatting issues and missing info in man page and --help --- Misc/python.man | 19 ++++++++++++++++--- Python/initconfig.c | 12 ++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Misc/python.man b/Misc/python.man index 69dab58a9aac26..c6628fe75f40ff 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -69,10 +69,10 @@ python \- an interpreted, interactive, object-oriented programming language .B \-x ] [ -[ .B \-X .I option ] +[ .B \-? ] .br @@ -310,7 +310,8 @@ Set implementation specific option. The following options are available: more verbose than the default if the code is correct: new warnings are only emitted when an issue is detected. Effect of the developer mode: * Add default warning filter, as -W default - * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() + C function * Enable the faulthandler module to dump the Python traceback on a crash * Enable asyncio debug mode * Set the dev_mode attribute of sys.flags to True @@ -321,7 +322,19 @@ Set implementation specific option. The following options are available: otherwise activate automatically). See PYTHONUTF8 for more details -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the - given directory instead of to the code tree. + given directory instead of to the code tree. + + -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None' + + -X no_debug_ranges: disable the inclusion of the tables mapping extra location + information (end line, start column offset and end column offset) to every + instruction in code objects. This is useful when smaller code objects and pyc + 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 + The default is "on" (or "off" if you are running a local build). + .TP .B \-x Skip the first line of the source. This is intended for a DOS diff --git a/Python/initconfig.c b/Python/initconfig.c index a623973f953734..d0329fa324ad60 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -35,10 +35,12 @@ Options and arguments (and corresponding environment variables):\n\ and comparing bytes/bytearray with str. (-bb: issue errors)\n\ -B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\ -c cmd : program passed in as string (terminates option list)\n\ +--check-hash-based-pycs always|default|never:\n\ + control how Python invalidates hash-based .pyc files\n\ -d : turn on parser debugging output (for experts only, only works on\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\ +-h : print this help message and exit (also --help or -?)\n\ "; static const char usage_2[] = "\ -i : inspect interactively after running script; forces a prompt even\n\ @@ -82,7 +84,8 @@ static const char usage_3[] = "\ checks which are too expensive to be enabled by default. Effect of the\n\ developer mode:\n\ * Add default warning filter, as -W default\n\ - * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\ + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks()\n\ + C function\n\ * Enable the faulthandler module to dump the Python traceback on a crash\n\ * Enable asyncio debug mode\n\ * Set the dev_mode attribute of sys.flags to True\n\ @@ -100,9 +103,6 @@ static const char usage_3[] = "\ 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\ @@ -141,7 +141,7 @@ static const char usage_6[] = "PYTHONNODEBUGRANGES: If this variable is set, it disables the inclusion of the \n" " tables mapping extra location information (end line, start column offset \n" " 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" +" when smaller code objects and pyc files are desired as well as suppressing the \n" " extra visual location indicators when the interpreter displays tracebacks.\n"; #if defined(MS_WINDOWS) From 0bb5dfa6b8888f41aef545ba13c5375e87356c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 25 May 2022 16:00:29 +0200 Subject: [PATCH 22/26] make new tests a bit more useful --- Lib/test/test_cmd_line.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 566f92b3574198..92e7ffe46031d7 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -39,20 +39,36 @@ def verify_valid_flag(self, 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_help(self): self.verify_valid_flag('-h') self.verify_valid_flag('-?') - self.verify_valid_flag('--help') + out = self.verify_valid_flag('--help') + lines = out.splitlines() + self.assertIn(b'usage', lines[0]) + self.assertNotIn(b'PYTHONPATH', out) + self.assertNotIn(b'-X dev', out) + self.assertLess(len(lines), 50) def test_help_env(self): - self.verify_valid_flag('--help-env') + out = self.verify_valid_flag('--help-env') + self.assertIn(b'PYTHONPATH', out) def test_help_xoptions(self): - self.verify_valid_flag('--help-xoptions') + out = self.verify_valid_flag('--help-xoptions') + self.assertIn(b'-X dev', out) def test_help_all(self): - self.verify_valid_flag('--help-all') + out = self.verify_valid_flag('--help-all') + lines = out.splitlines() + self.assertIn(b'usage', lines[0]) + self.assertIn(b'PYTHONPATH', 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') @@ -61,14 +77,6 @@ def test_optimize(self): def test_site_flag(self): self.verify_valid_flag('-S') - def test_usage(self): - rc, out, err = assert_python_ok('-h') - lines = out.splitlines() - self.assertIn(b'usage', lines[0]) - # The first line contains the program name, - # but the rest should be ASCII-only - b''.join(lines[1:]).decode('ascii') - def test_version(self): version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii") for switch in '-V', '--version', '-VV': From 8fa72f5bc3e4020fa83f36bc09f87760d018ae16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 25 May 2022 20:34:00 +0200 Subject: [PATCH 23/26] 512 bytes should be enough for everyone --- Python/initconfig.c | 59 ++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 38 deletions(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index e9dcad171b691a..a18c9643776a67 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -28,9 +28,9 @@ static const char usage_line[] = "usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n"; -/* Long help messages, split into parts < 512 bytes */ +/* Long help message */ /* Lines sorted by option name; keep in sync with usage_envvars* below */ -static const char usage_1[] = "\ +static const char usage_help[] = "\ 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\ @@ -45,8 +45,6 @@ Options (and corresponding environment variables):\n\ --help-env : print help about Python environment variables and exit\n\ --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[] = "\ -i : inspect interactively after running script; forces a prompt even\n\ if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\ -I : isolate Python from the user's environment (implies -E and -s)\n\ @@ -59,8 +57,6 @@ static const char usage_2[] = "\ -q : don't print version and copyright messages on interactive startup\n\ -s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\ -S : don't imply 'import site' on initialization\n\ -"; -static const char usage_3[] = "\ -u : force the stdout and stderr streams to be unbuffered;\n\ this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\ -v : verbose (trace import statements); also PYTHONVERBOSE=x\n\ @@ -71,8 +67,6 @@ static const char usage_3[] = "\ 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\n\ -"; -static const char usage_4[] = "\ Arguments:\n\ file : program read from script file\n\ - : program read from stdin (default; interactive mode if a tty)\n\ @@ -128,12 +122,11 @@ The following implementation-specific options are available:\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_envvars2[] = +static const char usage_envvars[] = +"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" "PYTHONSAFEPATH: don't prepend a potentially unsafe path to sys.path.\n" "PYTHONHOME : alternate directory (or %lc).\n" " The default module search path uses %s.\n" @@ -141,8 +134,7 @@ static const char usage_envvars2[] = "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_envvars3[] = +"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n" "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" @@ -152,8 +144,7 @@ static const char usage_envvars3[] = " 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."; -static const char usage_envvars4[] = +" locale coercion and locale compatibility warnings on stderr.\n" "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" @@ -163,17 +154,16 @@ static const char usage_envvars4[] = " tables mapping extra location information (end line, start column offset \n" " and end column offset) to every instruction in code objects. This is useful \n" " when smaller code objects and pyc files are desired as well as suppressing the \n" -" extra visual location indicators when the interpreter displays tracebacks.\n"; -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)"; +" extra visual location indicators when the interpreter displays tracebacks.\n" +"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 "\\python{major}{minor}" @@ -2269,21 +2259,14 @@ config_usage(int error, const wchar_t* program) if (error) fprintf(f, "Try `python -h' for more information.\n"); else { - fputs(usage_1, f); - fputs(usage_2, f); - fputs(usage_3, f); - fputs(usage_4, f); + fputs(usage_help, 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); + printf(usage_envvars, (wint_t)DELIM, (wint_t)DELIM, PYTHONHOMEHELP); } static void From 29d04a0edc44cb2e5949bbbc05202108ce2784b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Thu, 26 May 2022 12:34:49 +0200 Subject: [PATCH 24/26] keep long option at the end of help text --- Python/initconfig.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index d0329fa324ad60..0011c31a56fd12 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -35,8 +35,6 @@ Options and arguments (and corresponding environment variables):\n\ and comparing bytes/bytearray with str. (-bb: issue errors)\n\ -B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\ -c cmd : program passed in as string (terminates option list)\n\ ---check-hash-based-pycs always|default|never:\n\ - control how Python invalidates hash-based .pyc files\n\ -d : turn on parser debugging output (for experts only, only works on\n\ debug builds); also PYTHONDEBUG=x\n\ -E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\ @@ -67,7 +65,6 @@ static const char usage_3[] = "\ 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 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\ @@ -103,6 +100,8 @@ static const char usage_3[] = "\ 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\ +--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\ From ac1b5fbb445313bc69baff1fdbe910b04961379f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Thu, 26 May 2022 15:35:43 +0200 Subject: [PATCH 25/26] fix tests and output --- Lib/test/test_cmd_line.py | 2 +- Python/initconfig.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 92e7ffe46031d7..aff9cf4d3106f3 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -35,7 +35,7 @@ def test_directories(self): 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) diff --git a/Python/initconfig.c b/Python/initconfig.c index c82ba2c67584e2..510b8371cd5459 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -165,7 +165,7 @@ static const char usage_envvars[] = "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)"; +"PYTHONWARNINGS=arg : warning control (-W arg)\n"; #if defined(MS_WINDOWS) # define PYTHONHOMEHELP "\\python{major}{minor}" From 9bcea9514d0ae58e43f96e8bdca1852b516c1063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Thu, 26 May 2022 16:02:05 +0200 Subject: [PATCH 26/26] final fixes --- Lib/test/test_cmd_line.py | 6 +++--- Python/initconfig.c | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index aff9cf4d3106f3..83a357fe6b37d6 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -47,13 +47,13 @@ def test_help(self): out = self.verify_valid_flag('--help') lines = out.splitlines() self.assertIn(b'usage', lines[0]) - self.assertNotIn(b'PYTHONPATH', out) + self.assertNotIn(b'PYTHONHOME', out) self.assertNotIn(b'-X dev', out) self.assertLess(len(lines), 50) def test_help_env(self): out = self.verify_valid_flag('--help-env') - self.assertIn(b'PYTHONPATH', out) + self.assertIn(b'PYTHONHOME', out) def test_help_xoptions(self): out = self.verify_valid_flag('--help-xoptions') @@ -63,7 +63,7 @@ def test_help_all(self): out = self.verify_valid_flag('--help-all') lines = out.splitlines() self.assertIn(b'usage', lines[0]) - self.assertIn(b'PYTHONPATH', out) + self.assertIn(b'PYTHONHOME', out) self.assertIn(b'-X dev', out) # The first line contains the program name, diff --git a/Python/initconfig.c b/Python/initconfig.c index 510b8371cd5459..86dcdd9a8bd6bb 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -36,8 +36,6 @@ Options (and corresponding environment variables):\n\ and comparing bytes/bytearray with str. (-bb: issue errors)\n\ -B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\ -c cmd : program passed in as string (terminates option list)\n\ ---check-hash-based-pycs always|default|never :\n\ - control how Python invalidates hash-based .pyc files\n\ -d : turn on parser debugging output (for experts only, only works on\n\ debug builds); also PYTHONDEBUG=x\n\ -E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\