Skip to content

Commit c214dde

Browse files
committed
Add tests
1 parent fbf7d38 commit c214dde

2 files changed

Lines changed: 81 additions & 12 deletions

File tree

‎Lib/test/test_cmd_line.py‎

Lines changed: 77 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from test import support
1515
from test.support import os_helper
1616
from test.support import force_not_colorized
17+
from test.support import import_helper
1718
from test.support import threading_helper
1819
from test.support.script_helper import (
1920
spawn_python, kill_python, assert_python_ok, assert_python_failure,
@@ -60,14 +61,17 @@ def verify_valid_flag(self, cmd_line):
6061
@support.cpython_only
6162
@support.force_not_colorized
6263
def test_help(self):
63-
self.verify_valid_flag('-h')
64-
self.verify_valid_flag('-?')
65-
out = self.verify_valid_flag('--help')
66-
lines = out.splitlines()
67-
self.assertIn(b'usage', lines[0])
68-
self.assertNotIn(b'PYTHONHOME', out)
69-
self.assertNotIn(b'-X dev', out)
70-
self.assertLess(len(lines), 50)
64+
options = ['-h', '-?', '--help']
65+
if support.MS_WINDOWS:
66+
options.append('/?')
67+
for opt in options:
68+
with self.subTest(opt=opt):
69+
out = self.verify_valid_flag(opt)
70+
lines = out.splitlines()
71+
self.assertIn(b'usage', lines[0])
72+
self.assertNotIn(b'PYTHONHOME', out)
73+
self.assertNotIn(b'-X dev', out)
74+
self.assertLess(len(lines), 50)
7175

7276
@support.cpython_only
7377
@support.force_not_colorized
@@ -1403,6 +1407,71 @@ def test_dump_path_config(self):
14031407
self.assertIn(b'Python path configuration:', proc.err)
14041408
self.assertIn(f"PYTHONHOME = '{nonexistent}'".encode(), proc.err)
14051409

1410+
def test_short_options(self):
1411+
# Skip the test if _testcapi cannot be imported:
1412+
# the test uses _testcapi.config_get().
1413+
import_helper.import_module('_testcapi')
1414+
1415+
# Test short command line options
1416+
def check(option, config_name, expr, expected):
1417+
if isinstance(option, str):
1418+
option = (option,)
1419+
code = (
1420+
'from _testcapi import config_get; '
1421+
'import sys; '
1422+
f'print(config_get({config_name!a}), {expr})'
1423+
)
1424+
args = option + ("-c", code)
1425+
proc = assert_python_ok(*args)
1426+
self.assertEqual(proc.out.rstrip(), expected.encode())
1427+
1428+
def check_ignored(option):
1429+
# Just test that passing the option doesn't fail
1430+
assert_python_ok(option, "-c", "pass")
1431+
1432+
check('-b', 'bytes_warning', 'sys.flags.bytes_warning', '1 1')
1433+
check('-bb', 'bytes_warning', 'sys.flags.bytes_warning', '2 2')
1434+
check('-B', 'write_bytecode', 'sys.dont_write_bytecode', 'False True')
1435+
check('-d', 'parser_debug', 'sys.flags.debug', 'True 1')
1436+
check('-E', 'use_environment', 'sys.flags.ignore_environment', 'False 1')
1437+
check('-i', 'inspect',
1438+
'config_get("interactive"), sys.flags.inspect, sys.flags.interactive',
1439+
'True True 1 1')
1440+
check('-I', 'isolated', 'sys.flags.isolated', 'True 1')
1441+
check('-O', 'optimization_level', 'sys.flags.optimize', '1 1')
1442+
check('-OO', 'optimization_level', 'sys.flags.optimize', '2 2')
1443+
check('-P', 'safe_path', 'sys.flags.safe_path', 'True True')
1444+
check('-q', 'quiet', 'sys.flags.quiet', 'True 1')
1445+
check('-R', 'use_hash_seed', 'sys.flags.hash_randomization', 'False 1')
1446+
check('-s', 'user_site_directory', 'sys.flags.no_user_site', 'False 1')
1447+
check('-S', 'site_import', 'sys.flags.no_site', 'False 1')
1448+
check_ignored('-t')
1449+
check('-u', 'buffered_stdio', 'sys.stdout.write_through', 'False True')
1450+
check('-v', 'verbose', 'sys.flags.verbose', '1 1')
1451+
check('-Wignore', 'warnoptions', 'sys.warnoptions',
1452+
"['ignore'] ['ignore']")
1453+
check('-x', 'skip_source_first_line', '', 'True')
1454+
check(('-X', 'xoption=value'), 'xoptions', 'sys._xoptions',
1455+
# assert_python_ok() adds -X faulthandler
1456+
"{'faulthandler': True, 'xoption': 'value'} "
1457+
"{'faulthandler': True, 'xoption': 'value'}")
1458+
1459+
# -c, -h, -m, -V and -? are tested elsewhere
1460+
1461+
def test_long_options(self):
1462+
# Test long command line options
1463+
1464+
# Test --check-hash-based-pycs option
1465+
code = 'import _imp; print(_imp.check_hash_based_pycs)'
1466+
opt = f"--check-hash-based-pycs"
1467+
for value in ('always', 'never', 'default'):
1468+
with self.subTest(value=value):
1469+
proc = assert_python_ok(opt, value, "-c", code)
1470+
self.assertEqual(proc.out.rstrip(), value.encode())
1471+
1472+
# Other long options --help-all, --help-env and --help-xoptions
1473+
# are tested elsewhere
1474+
14061475

14071476
@unittest.skipIf(interpreter_requires_environment(),
14081477
'Cannot run -I tests when PYTHON env vars are required.')

‎Python/initconfig.c‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3051,7 +3051,7 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
30513051
switch (c) {
30523052
// Integers represent long options, see Python/getopt.c
30533053
case 1:
3054-
// check-hash-based-pycs
3054+
// --check-hash-based-pycs option
30553055
if (wcscmp(getopt.arg, L"always") == 0
30563056
|| wcscmp(getopt.arg, L"never") == 0
30573057
|| wcscmp(getopt.arg, L"default") == 0)
@@ -3067,17 +3067,17 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
30673067
break;
30683068

30693069
case 2:
3070-
// help-all
3070+
// --help-all option
30713071
DEFER_OPTION(c);
30723072
break;
30733073

30743074
case 3:
3075-
// help-env
3075+
// --help-env option
30763076
DEFER_OPTION(c);
30773077
break;
30783078

30793079
case 4:
3080-
// help-xoptions
3080+
// --help-xoptions option
30813081
DEFER_OPTION(c);
30823082
break;
30833083

0 commit comments

Comments
 (0)