Skip to content

Commit b8cb837

Browse files
authored
[3.14] gh-145990: sort --help-env sections by environment variable name (GH-146001)
* sort --help-env alphabetically by name. * add a sorting regression test in test_help_env. manual backport of GH-145997
1 parent 36805f6 commit b8cb837

File tree

3 files changed

+36
-27
lines changed

3 files changed

+36
-27
lines changed

Lib/test/test_cmd_line.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ def test_help(self):
6060
def test_help_env(self):
6161
out = self.verify_valid_flag('--help-env')
6262
self.assertIn(b'PYTHONHOME', out)
63+
# Env vars in each section should be sorted alphabetically
64+
# (ignoring underscores so PYTHON_FOO and PYTHONFOO intermix naturally)
65+
sort_key = lambda name: name.replace(b'_', b'').lower()
66+
sections = out.split(b'These variables have equivalent')
67+
for section in sections:
68+
envvars = re.findall(rb'^(PYTHON\w+)', section, re.MULTILINE)
69+
self.assertEqual(envvars, sorted(envvars, key=sort_key),
70+
"env vars should be sorted alphabetically")
6371

6472
@support.cpython_only
6573
def test_help_xoptions(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
``python --help-env`` sections are now sorted by environment variable name.

Python/initconfig.c

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -363,49 +363,51 @@ The following implementation-specific options are available:\n\
363363
/* Envvars that don't have equivalent command-line options are listed first */
364364
static const char usage_envvars[] =
365365
"Environment variables that change behavior:\n"
366-
"PYTHONSTARTUP : file executed on interactive startup (no default)\n"
367-
"PYTHONPATH : '%lc'-separated list of directories prefixed to the\n"
368-
" default module search path. The result is sys.path.\n"
369-
"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
370-
" The default module search path uses %s.\n"
371-
"PYTHONPLATLIBDIR: override sys.platlibdir\n"
366+
"PYTHONASYNCIODEBUG: enable asyncio debug mode\n"
367+
"PYTHON_BASIC_REPL: use the traditional parser-based REPL\n"
368+
"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
369+
" debugger. It can be set to the callable of your debugger of\n"
370+
" choice.\n"
372371
"PYTHONCASEOK : ignore case in 'import' statements (Windows)\n"
373-
"PYTHONIOENCODING: encoding[:errors] used for stdin/stdout/stderr\n"
374-
"PYTHONHASHSEED : if this variable is set to 'random', a random value is used\n"
375-
" to seed the hashes of str and bytes objects. It can also be\n"
376-
" set to an integer in the range [0,4294967295] to get hash\n"
377-
" values with a predictable seed.\n"
378-
"PYTHONMALLOC : set the Python memory allocators and/or install debug hooks\n"
379-
" on Python memory allocators. Use PYTHONMALLOC=debug to\n"
380-
" install debug hooks.\n"
381-
"PYTHONMALLOCSTATS: print memory allocator statistics\n"
382372
"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
383373
" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request\n"
384374
" display of locale coercion and locale compatibility warnings\n"
385375
" on stderr.\n"
386-
"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
387-
" debugger. It can be set to the callable of your debugger of\n"
388-
" choice.\n"
389376
"PYTHON_COLORS : if this variable is set to 1, the interpreter will colorize\n"
390377
" various kinds of output. Setting it to 0 deactivates\n"
391378
" this behavior.\n"
392-
"PYTHON_HISTORY : the location of a .python_history file.\n"
393-
"PYTHONASYNCIODEBUG: enable asyncio debug mode\n"
394379
#ifdef Py_TRACE_REFS
395380
"PYTHONDUMPREFS : dump objects and reference counts still alive after shutdown\n"
396381
"PYTHONDUMPREFSFILE: dump objects and reference counts to the specified file\n"
397382
#endif
398383
#ifdef __APPLE__
399384
"PYTHONEXECUTABLE: set sys.argv[0] to this value (macOS only)\n"
400385
#endif
386+
"PYTHONHASHSEED : if this variable is set to 'random', a random value is used\n"
387+
" to seed the hashes of str and bytes objects. It can also be\n"
388+
" set to an integer in the range [0,4294967295] to get hash\n"
389+
" values with a predictable seed.\n"
390+
"PYTHON_HISTORY : the location of a .python_history file.\n"
391+
"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
392+
" The default module search path uses %s.\n"
393+
"PYTHONIOENCODING: encoding[:errors] used for stdin/stdout/stderr\n"
401394
#ifdef MS_WINDOWS
402395
"PYTHONLEGACYWINDOWSFSENCODING: use legacy \"mbcs\" encoding for file system\n"
403396
"PYTHONLEGACYWINDOWSSTDIO: use legacy Windows stdio\n"
404397
#endif
398+
"PYTHONMALLOC : set the Python memory allocators and/or install debug hooks\n"
399+
" on Python memory allocators. Use PYTHONMALLOC=debug to\n"
400+
" install debug hooks.\n"
401+
"PYTHONMALLOCSTATS: print memory allocator statistics\n"
402+
"PYTHONPATH : '%lc'-separated list of directories prefixed to the\n"
403+
" default module search path. The result is sys.path.\n"
404+
"PYTHONPLATLIBDIR: override sys.platlibdir\n"
405+
"PYTHONSTARTUP : file executed on interactive startup (no default)\n"
405406
"PYTHONUSERBASE : defines the user base directory (site.USER_BASE)\n"
406-
"PYTHON_BASIC_REPL: use the traditional parser-based REPL\n"
407407
"\n"
408408
"These variables have equivalent command-line options (see --help for details):\n"
409+
"PYTHON_CONTEXT_AWARE_WARNINGS: if true (1), enable thread-safe warnings\n"
410+
" module behaviour (-X context_aware_warnings)\n"
409411
"PYTHON_CPU_COUNT: override the return value of os.cpu_count() (-X cpu_count)\n"
410412
"PYTHONDEBUG : enable parser debug mode (-d)\n"
411413
"PYTHONDEVMODE : enable Python Development Mode (-X dev)\n"
@@ -424,9 +426,9 @@ static const char usage_envvars[] =
424426
" (-X no_debug_ranges)\n"
425427
"PYTHONNOUSERSITE: disable user site directory (-s)\n"
426428
"PYTHONOPTIMIZE : enable level 1 optimizations (-O)\n"
427-
"PYTHONPERFSUPPORT: support the Linux \"perf\" profiler (-X perf)\n"
428429
"PYTHON_PERF_JIT_SUPPORT: enable Linux \"perf\" profiler support with JIT\n"
429430
" (-X perf_jit)\n"
431+
"PYTHONPERFSUPPORT: support the Linux \"perf\" profiler (-X perf)\n"
430432
#ifdef Py_DEBUG
431433
"PYTHON_PRESITE: import this module before site (-X presite)\n"
432434
#endif
@@ -437,13 +439,11 @@ static const char usage_envvars[] =
437439
#ifdef Py_STATS
438440
"PYTHONSTATS : turns on statistics gathering (-X pystats)\n"
439441
#endif
442+
"PYTHON_THREAD_INHERIT_CONTEXT: if true (1), threads inherit context vars\n"
443+
" (-X thread_inherit_context)\n"
440444
#ifdef Py_GIL_DISABLED
441445
"PYTHON_TLBC : when set to 0, disables thread-local bytecode (-X tlbc)\n"
442446
#endif
443-
"PYTHON_THREAD_INHERIT_CONTEXT: if true (1), threads inherit context vars\n"
444-
" (-X thread_inherit_context)\n"
445-
"PYTHON_CONTEXT_AWARE_WARNINGS: if true (1), enable thread-safe warnings module\n"
446-
" behaviour (-X context_aware_warnings)\n"
447447
"PYTHONTRACEMALLOC: trace Python memory allocations (-X tracemalloc)\n"
448448
"PYTHONUNBUFFERED: disable stdout/stderr buffering (-u)\n"
449449
"PYTHONUTF8 : control the UTF-8 mode (-X utf8)\n"
@@ -2840,7 +2840,7 @@ config_usage(int error, const wchar_t* program)
28402840
static void
28412841
config_envvars_usage(void)
28422842
{
2843-
printf(usage_envvars, (wint_t)DELIM, (wint_t)DELIM, PYTHONHOMEHELP);
2843+
printf(usage_envvars, (wint_t)DELIM, PYTHONHOMEHELP, (wint_t)DELIM);
28442844
}
28452845

28462846
static void

0 commit comments

Comments
 (0)