17db96d56Sopenharmony_ciimport argparse
27db96d56Sopenharmony_ciimport os
37db96d56Sopenharmony_ciimport shlex
47db96d56Sopenharmony_ciimport sys
57db96d56Sopenharmony_cifrom test.support import os_helper
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci
87db96d56Sopenharmony_ciUSAGE = """\
97db96d56Sopenharmony_cipython -m test [options] [test_name1 [test_name2 ...]]
107db96d56Sopenharmony_cipython path/to/Lib/test/regrtest.py [options] [test_name1 [test_name2 ...]]
117db96d56Sopenharmony_ci"""
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ciDESCRIPTION = """\
147db96d56Sopenharmony_ciRun Python regression tests.
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ciIf no arguments or options are provided, finds all files matching
177db96d56Sopenharmony_cithe pattern "test_*" in the Lib/test subdirectory and runs
187db96d56Sopenharmony_cithem in alphabetical order (but see -M and -u, below, for exceptions).
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ciFor more rigorous testing, it is useful to use the following
217db96d56Sopenharmony_cicommand line:
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_cipython -E -Wd -m test [options] [test_name1 ...]
247db96d56Sopenharmony_ci"""
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ciEPILOG = """\
277db96d56Sopenharmony_ciAdditional option details:
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ci-r randomizes test execution order. You can use --randseed=int to provide an
307db96d56Sopenharmony_ciint seed value for the randomizer; this is useful for reproducing troublesome
317db96d56Sopenharmony_citest orders.
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci-s On the first invocation of regrtest using -s, the first test file found
347db96d56Sopenharmony_cior the first test file given on the command line is run, and the name of
357db96d56Sopenharmony_cithe next test is recorded in a file named pynexttest.  If run from the
367db96d56Sopenharmony_ciPython build directory, pynexttest is located in the 'build' subdirectory,
377db96d56Sopenharmony_ciotherwise it is located in tempfile.gettempdir().  On subsequent runs,
387db96d56Sopenharmony_cithe test in pynexttest is run, and the next test is written to pynexttest.
397db96d56Sopenharmony_ciWhen the last test has been run, pynexttest is deleted.  In this way it
407db96d56Sopenharmony_ciis possible to single step through the test files.  This is useful when
417db96d56Sopenharmony_cidoing memory analysis on the Python interpreter, which process tends to
427db96d56Sopenharmony_ciconsume too many resources to run the full regression test non-stop.
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ci-S is used to continue running tests after an aborted run.  It will
457db96d56Sopenharmony_cimaintain the order a standard run (ie, this assumes -r is not used).
467db96d56Sopenharmony_ciThis is useful after the tests have prematurely stopped for some external
477db96d56Sopenharmony_cireason and you want to start running from where you left off rather
487db96d56Sopenharmony_cithan starting from the beginning.
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_ci-f reads the names of tests from the file given as f's argument, one
517db96d56Sopenharmony_cior more test names per line.  Whitespace is ignored.  Blank lines and
527db96d56Sopenharmony_cilines beginning with '#' are ignored.  This is especially useful for
537db96d56Sopenharmony_ciwhittling down failures involving interactions among tests.
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci-L causes the leaks(1) command to be run just before exit if it exists.
567db96d56Sopenharmony_cileaks(1) is available on Mac OS X and presumably on some other
577db96d56Sopenharmony_ciFreeBSD-derived systems.
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_ci-R runs each test several times and examines sys.gettotalrefcount() to
607db96d56Sopenharmony_cisee if the test appears to be leaking references.  The argument should
617db96d56Sopenharmony_cibe of the form stab:run:fname where 'stab' is the number of times the
627db96d56Sopenharmony_citest is run to let gettotalrefcount settle down, 'run' is the number
637db96d56Sopenharmony_ciof times further it is run and 'fname' is the name of the file the
647db96d56Sopenharmony_cireports are written to.  These parameters all have defaults (5, 4 and
657db96d56Sopenharmony_ci"reflog.txt" respectively), and the minimal invocation is '-R :'.
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci-M runs tests that require an exorbitant amount of memory. These tests
687db96d56Sopenharmony_citypically try to ascertain containers keep working when containing more than
697db96d56Sopenharmony_ci2 billion objects, which only works on 64-bit systems. There are also some
707db96d56Sopenharmony_citests that try to exhaust the address space of the process, which only makes
717db96d56Sopenharmony_cisense on 32-bit systems with at least 2Gb of memory. The passed-in memlimit,
727db96d56Sopenharmony_ciwhich is a string in the form of '2.5Gb', determines how much memory the
737db96d56Sopenharmony_citests will limit themselves to (but they may go slightly over.) The number
747db96d56Sopenharmony_cishouldn't be more memory than the machine has (including swap memory). You
757db96d56Sopenharmony_cishould also keep in mind that swap memory is generally much, much slower
767db96d56Sopenharmony_cithan RAM, and setting memlimit to all available RAM or higher will heavily
777db96d56Sopenharmony_citax the machine. On the other hand, it is no use running these tests with a
787db96d56Sopenharmony_cilimit of less than 2.5Gb, and many require more than 20Gb. Tests that expect
797db96d56Sopenharmony_cito use more than memlimit memory will be skipped. The big-memory tests
807db96d56Sopenharmony_cigenerally run very, very long.
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_ci-u is used to specify which special resource intensive tests to run,
837db96d56Sopenharmony_cisuch as those requiring large file support or network connectivity.
847db96d56Sopenharmony_ciThe argument is a comma-separated list of words indicating the
857db96d56Sopenharmony_ciresources to test.  Currently only the following are defined:
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci    all -       Enable all special resources.
887db96d56Sopenharmony_ci
897db96d56Sopenharmony_ci    none -      Disable all special resources (this is the default).
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ci    audio -     Tests that use the audio device.  (There are known
927db96d56Sopenharmony_ci                cases of broken audio drivers that can crash Python or
937db96d56Sopenharmony_ci                even the Linux kernel.)
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci    curses -    Tests that use curses and will modify the terminal's
967db96d56Sopenharmony_ci                state and output modes.
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_ci    largefile - It is okay to run some test that may create huge
997db96d56Sopenharmony_ci                files.  These tests can take a long time and may
1007db96d56Sopenharmony_ci                consume >2 GiB of disk space temporarily.
1017db96d56Sopenharmony_ci
1027db96d56Sopenharmony_ci    network -   It is okay to run tests that use external network
1037db96d56Sopenharmony_ci                resource, e.g. testing SSL support for sockets.
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_ci    decimal -   Test the decimal module against a large suite that
1067db96d56Sopenharmony_ci                verifies compliance with standards.
1077db96d56Sopenharmony_ci
1087db96d56Sopenharmony_ci    cpu -       Used for certain CPU-heavy tests.
1097db96d56Sopenharmony_ci
1107db96d56Sopenharmony_ci    subprocess  Run all tests for the subprocess module.
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ci    urlfetch -  It is okay to download files required on testing.
1137db96d56Sopenharmony_ci
1147db96d56Sopenharmony_ci    gui -       Run tests that require a running GUI.
1157db96d56Sopenharmony_ci
1167db96d56Sopenharmony_ci    tzdata -    Run tests that require timezone data.
1177db96d56Sopenharmony_ci
1187db96d56Sopenharmony_ciTo enable all resources except one, use '-uall,-<resource>'.  For
1197db96d56Sopenharmony_ciexample, to run all the tests except for the gui tests, give the
1207db96d56Sopenharmony_cioption '-uall,-gui'.
1217db96d56Sopenharmony_ci
1227db96d56Sopenharmony_ci--matchfile filters tests using a text file, one pattern per line.
1237db96d56Sopenharmony_ciPattern examples:
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_ci- test method: test_stat_attributes
1267db96d56Sopenharmony_ci- test class: FileTests
1277db96d56Sopenharmony_ci- test identifier: test_os.FileTests.test_stat_attributes
1287db96d56Sopenharmony_ci"""
1297db96d56Sopenharmony_ci
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ciALL_RESOURCES = ('audio', 'curses', 'largefile', 'network',
1327db96d56Sopenharmony_ci                 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui')
1337db96d56Sopenharmony_ci
1347db96d56Sopenharmony_ci# Other resources excluded from --use=all:
1357db96d56Sopenharmony_ci#
1367db96d56Sopenharmony_ci# - extralagefile (ex: test_zipfile64): really too slow to be enabled
1377db96d56Sopenharmony_ci#   "by default"
1387db96d56Sopenharmony_ci# - tzdata: while needed to validate fully test_datetime, it makes
1397db96d56Sopenharmony_ci#   test_datetime too slow (15-20 min on some buildbots) and so is disabled by
1407db96d56Sopenharmony_ci#   default (see bpo-30822).
1417db96d56Sopenharmony_ciRESOURCE_NAMES = ALL_RESOURCES + ('extralargefile', 'tzdata')
1427db96d56Sopenharmony_ci
1437db96d56Sopenharmony_ci
1447db96d56Sopenharmony_ciclass Namespace(argparse.Namespace):
1457db96d56Sopenharmony_ci    def __init__(self, **kwargs) -> None:
1467db96d56Sopenharmony_ci        self.testdir = None
1477db96d56Sopenharmony_ci        self.verbose = 0
1487db96d56Sopenharmony_ci        self.quiet = False
1497db96d56Sopenharmony_ci        self.exclude = False
1507db96d56Sopenharmony_ci        self.single = False
1517db96d56Sopenharmony_ci        self.randomize = False
1527db96d56Sopenharmony_ci        self.fromfile = None
1537db96d56Sopenharmony_ci        self.fail_env_changed = False
1547db96d56Sopenharmony_ci        self.use_resources = None
1557db96d56Sopenharmony_ci        self.trace = False
1567db96d56Sopenharmony_ci        self.coverdir = 'coverage'
1577db96d56Sopenharmony_ci        self.runleaks = False
1587db96d56Sopenharmony_ci        self.huntrleaks = False
1597db96d56Sopenharmony_ci        self.verbose2 = False
1607db96d56Sopenharmony_ci        self.verbose3 = False
1617db96d56Sopenharmony_ci        self.print_slow = False
1627db96d56Sopenharmony_ci        self.random_seed = None
1637db96d56Sopenharmony_ci        self.use_mp = None
1647db96d56Sopenharmony_ci        self.forever = False
1657db96d56Sopenharmony_ci        self.header = False
1667db96d56Sopenharmony_ci        self.failfast = False
1677db96d56Sopenharmony_ci        self.match_tests = None
1687db96d56Sopenharmony_ci        self.ignore_tests = None
1697db96d56Sopenharmony_ci        self.pgo = False
1707db96d56Sopenharmony_ci        self.pgo_extended = False
1717db96d56Sopenharmony_ci
1727db96d56Sopenharmony_ci        super().__init__(**kwargs)
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_ci
1757db96d56Sopenharmony_ciclass _ArgParser(argparse.ArgumentParser):
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ci    def error(self, message):
1787db96d56Sopenharmony_ci        super().error(message + "\nPass -h or --help for complete help.")
1797db96d56Sopenharmony_ci
1807db96d56Sopenharmony_ci
1817db96d56Sopenharmony_cidef _create_parser():
1827db96d56Sopenharmony_ci    # Set prog to prevent the uninformative "__main__.py" from displaying in
1837db96d56Sopenharmony_ci    # error messages when using "python -m test ...".
1847db96d56Sopenharmony_ci    parser = _ArgParser(prog='regrtest.py',
1857db96d56Sopenharmony_ci                        usage=USAGE,
1867db96d56Sopenharmony_ci                        description=DESCRIPTION,
1877db96d56Sopenharmony_ci                        epilog=EPILOG,
1887db96d56Sopenharmony_ci                        add_help=False,
1897db96d56Sopenharmony_ci                        formatter_class=argparse.RawDescriptionHelpFormatter)
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ci    # Arguments with this clause added to its help are described further in
1927db96d56Sopenharmony_ci    # the epilog's "Additional option details" section.
1937db96d56Sopenharmony_ci    more_details = '  See the section at bottom for more details.'
1947db96d56Sopenharmony_ci
1957db96d56Sopenharmony_ci    group = parser.add_argument_group('General options')
1967db96d56Sopenharmony_ci    # We add help explicitly to control what argument group it renders under.
1977db96d56Sopenharmony_ci    group.add_argument('-h', '--help', action='help',
1987db96d56Sopenharmony_ci                       help='show this help message and exit')
1997db96d56Sopenharmony_ci    group.add_argument('--timeout', metavar='TIMEOUT', type=float,
2007db96d56Sopenharmony_ci                        help='dump the traceback and exit if a test takes '
2017db96d56Sopenharmony_ci                             'more than TIMEOUT seconds; disabled if TIMEOUT '
2027db96d56Sopenharmony_ci                             'is negative or equals to zero')
2037db96d56Sopenharmony_ci    group.add_argument('--wait', action='store_true',
2047db96d56Sopenharmony_ci                       help='wait for user input, e.g., allow a debugger '
2057db96d56Sopenharmony_ci                            'to be attached')
2067db96d56Sopenharmony_ci    group.add_argument('--worker-args', metavar='ARGS')
2077db96d56Sopenharmony_ci    group.add_argument('-S', '--start', metavar='START',
2087db96d56Sopenharmony_ci                       help='the name of the test at which to start.' +
2097db96d56Sopenharmony_ci                            more_details)
2107db96d56Sopenharmony_ci    group.add_argument('-p', '--python', metavar='PYTHON',
2117db96d56Sopenharmony_ci                       help='Command to run Python test subprocesses with.')
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_ci    group = parser.add_argument_group('Verbosity')
2147db96d56Sopenharmony_ci    group.add_argument('-v', '--verbose', action='count',
2157db96d56Sopenharmony_ci                       help='run tests in verbose mode with output to stdout')
2167db96d56Sopenharmony_ci    group.add_argument('-w', '--verbose2', action='store_true',
2177db96d56Sopenharmony_ci                       help='re-run failed tests in verbose mode')
2187db96d56Sopenharmony_ci    group.add_argument('-W', '--verbose3', action='store_true',
2197db96d56Sopenharmony_ci                       help='display test output on failure')
2207db96d56Sopenharmony_ci    group.add_argument('-q', '--quiet', action='store_true',
2217db96d56Sopenharmony_ci                       help='no output unless one or more tests fail')
2227db96d56Sopenharmony_ci    group.add_argument('-o', '--slowest', action='store_true', dest='print_slow',
2237db96d56Sopenharmony_ci                       help='print the slowest 10 tests')
2247db96d56Sopenharmony_ci    group.add_argument('--header', action='store_true',
2257db96d56Sopenharmony_ci                       help='print header with interpreter info')
2267db96d56Sopenharmony_ci
2277db96d56Sopenharmony_ci    group = parser.add_argument_group('Selecting tests')
2287db96d56Sopenharmony_ci    group.add_argument('-r', '--randomize', action='store_true',
2297db96d56Sopenharmony_ci                       help='randomize test execution order.' + more_details)
2307db96d56Sopenharmony_ci    group.add_argument('--randseed', metavar='SEED',
2317db96d56Sopenharmony_ci                       dest='random_seed', type=int,
2327db96d56Sopenharmony_ci                       help='pass a random seed to reproduce a previous '
2337db96d56Sopenharmony_ci                            'random run')
2347db96d56Sopenharmony_ci    group.add_argument('-f', '--fromfile', metavar='FILE',
2357db96d56Sopenharmony_ci                       help='read names of tests to run from a file.' +
2367db96d56Sopenharmony_ci                            more_details)
2377db96d56Sopenharmony_ci    group.add_argument('-x', '--exclude', action='store_true',
2387db96d56Sopenharmony_ci                       help='arguments are tests to *exclude*')
2397db96d56Sopenharmony_ci    group.add_argument('-s', '--single', action='store_true',
2407db96d56Sopenharmony_ci                       help='single step through a set of tests.' +
2417db96d56Sopenharmony_ci                            more_details)
2427db96d56Sopenharmony_ci    group.add_argument('-m', '--match', metavar='PAT',
2437db96d56Sopenharmony_ci                       dest='match_tests', action='append',
2447db96d56Sopenharmony_ci                       help='match test cases and methods with glob pattern PAT')
2457db96d56Sopenharmony_ci    group.add_argument('-i', '--ignore', metavar='PAT',
2467db96d56Sopenharmony_ci                       dest='ignore_tests', action='append',
2477db96d56Sopenharmony_ci                       help='ignore test cases and methods with glob pattern PAT')
2487db96d56Sopenharmony_ci    group.add_argument('--matchfile', metavar='FILENAME',
2497db96d56Sopenharmony_ci                       dest='match_filename',
2507db96d56Sopenharmony_ci                       help='similar to --match but get patterns from a '
2517db96d56Sopenharmony_ci                            'text file, one pattern per line')
2527db96d56Sopenharmony_ci    group.add_argument('--ignorefile', metavar='FILENAME',
2537db96d56Sopenharmony_ci                       dest='ignore_filename',
2547db96d56Sopenharmony_ci                       help='similar to --matchfile but it receives patterns '
2557db96d56Sopenharmony_ci                            'from text file to ignore')
2567db96d56Sopenharmony_ci    group.add_argument('-G', '--failfast', action='store_true',
2577db96d56Sopenharmony_ci                       help='fail as soon as a test fails (only with -v or -W)')
2587db96d56Sopenharmony_ci    group.add_argument('-u', '--use', metavar='RES1,RES2,...',
2597db96d56Sopenharmony_ci                       action='append', type=resources_list,
2607db96d56Sopenharmony_ci                       help='specify which special resource intensive tests '
2617db96d56Sopenharmony_ci                            'to run.' + more_details)
2627db96d56Sopenharmony_ci    group.add_argument('-M', '--memlimit', metavar='LIMIT',
2637db96d56Sopenharmony_ci                       help='run very large memory-consuming tests.' +
2647db96d56Sopenharmony_ci                            more_details)
2657db96d56Sopenharmony_ci    group.add_argument('--testdir', metavar='DIR',
2667db96d56Sopenharmony_ci                       type=relative_filename,
2677db96d56Sopenharmony_ci                       help='execute test files in the specified directory '
2687db96d56Sopenharmony_ci                            '(instead of the Python stdlib test suite)')
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci    group = parser.add_argument_group('Special runs')
2717db96d56Sopenharmony_ci    group.add_argument('-L', '--runleaks', action='store_true',
2727db96d56Sopenharmony_ci                       help='run the leaks(1) command just before exit.' +
2737db96d56Sopenharmony_ci                            more_details)
2747db96d56Sopenharmony_ci    group.add_argument('-R', '--huntrleaks', metavar='RUNCOUNTS',
2757db96d56Sopenharmony_ci                       type=huntrleaks,
2767db96d56Sopenharmony_ci                       help='search for reference leaks (needs debug build, '
2777db96d56Sopenharmony_ci                            'very slow).' + more_details)
2787db96d56Sopenharmony_ci    group.add_argument('-j', '--multiprocess', metavar='PROCESSES',
2797db96d56Sopenharmony_ci                       dest='use_mp', type=int,
2807db96d56Sopenharmony_ci                       help='run PROCESSES processes at once')
2817db96d56Sopenharmony_ci    group.add_argument('-T', '--coverage', action='store_true',
2827db96d56Sopenharmony_ci                       dest='trace',
2837db96d56Sopenharmony_ci                       help='turn on code coverage tracing using the trace '
2847db96d56Sopenharmony_ci                            'module')
2857db96d56Sopenharmony_ci    group.add_argument('-D', '--coverdir', metavar='DIR',
2867db96d56Sopenharmony_ci                       type=relative_filename,
2877db96d56Sopenharmony_ci                       help='directory where coverage files are put')
2887db96d56Sopenharmony_ci    group.add_argument('-N', '--nocoverdir',
2897db96d56Sopenharmony_ci                       action='store_const', const=None, dest='coverdir',
2907db96d56Sopenharmony_ci                       help='put coverage files alongside modules')
2917db96d56Sopenharmony_ci    group.add_argument('-t', '--threshold', metavar='THRESHOLD',
2927db96d56Sopenharmony_ci                       type=int,
2937db96d56Sopenharmony_ci                       help='call gc.set_threshold(THRESHOLD)')
2947db96d56Sopenharmony_ci    group.add_argument('-n', '--nowindows', action='store_true',
2957db96d56Sopenharmony_ci                       help='suppress error message boxes on Windows')
2967db96d56Sopenharmony_ci    group.add_argument('-F', '--forever', action='store_true',
2977db96d56Sopenharmony_ci                       help='run the specified tests in a loop, until an '
2987db96d56Sopenharmony_ci                            'error happens; imply --failfast')
2997db96d56Sopenharmony_ci    group.add_argument('--list-tests', action='store_true',
3007db96d56Sopenharmony_ci                       help="only write the name of tests that will be run, "
3017db96d56Sopenharmony_ci                            "don't execute them")
3027db96d56Sopenharmony_ci    group.add_argument('--list-cases', action='store_true',
3037db96d56Sopenharmony_ci                       help='only write the name of test cases that will be run'
3047db96d56Sopenharmony_ci                            ' , don\'t execute them')
3057db96d56Sopenharmony_ci    group.add_argument('-P', '--pgo', dest='pgo', action='store_true',
3067db96d56Sopenharmony_ci                       help='enable Profile Guided Optimization (PGO) training')
3077db96d56Sopenharmony_ci    group.add_argument('--pgo-extended', action='store_true',
3087db96d56Sopenharmony_ci                       help='enable extended PGO training (slower training)')
3097db96d56Sopenharmony_ci    group.add_argument('--fail-env-changed', action='store_true',
3107db96d56Sopenharmony_ci                       help='if a test file alters the environment, mark '
3117db96d56Sopenharmony_ci                            'the test as failed')
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_ci    group.add_argument('--junit-xml', dest='xmlpath', metavar='FILENAME',
3147db96d56Sopenharmony_ci                       help='writes JUnit-style XML results to the specified '
3157db96d56Sopenharmony_ci                            'file')
3167db96d56Sopenharmony_ci    group.add_argument('--tempdir', metavar='PATH',
3177db96d56Sopenharmony_ci                       help='override the working directory for the test run')
3187db96d56Sopenharmony_ci    group.add_argument('--cleanup', action='store_true',
3197db96d56Sopenharmony_ci                       help='remove old test_python_* directories')
3207db96d56Sopenharmony_ci    return parser
3217db96d56Sopenharmony_ci
3227db96d56Sopenharmony_ci
3237db96d56Sopenharmony_cidef relative_filename(string):
3247db96d56Sopenharmony_ci    # CWD is replaced with a temporary dir before calling main(), so we
3257db96d56Sopenharmony_ci    # join it with the saved CWD so it ends up where the user expects.
3267db96d56Sopenharmony_ci    return os.path.join(os_helper.SAVEDCWD, string)
3277db96d56Sopenharmony_ci
3287db96d56Sopenharmony_ci
3297db96d56Sopenharmony_cidef huntrleaks(string):
3307db96d56Sopenharmony_ci    args = string.split(':')
3317db96d56Sopenharmony_ci    if len(args) not in (2, 3):
3327db96d56Sopenharmony_ci        raise argparse.ArgumentTypeError(
3337db96d56Sopenharmony_ci            'needs 2 or 3 colon-separated arguments')
3347db96d56Sopenharmony_ci    nwarmup = int(args[0]) if args[0] else 5
3357db96d56Sopenharmony_ci    ntracked = int(args[1]) if args[1] else 4
3367db96d56Sopenharmony_ci    fname = args[2] if len(args) > 2 and args[2] else 'reflog.txt'
3377db96d56Sopenharmony_ci    return nwarmup, ntracked, fname
3387db96d56Sopenharmony_ci
3397db96d56Sopenharmony_ci
3407db96d56Sopenharmony_cidef resources_list(string):
3417db96d56Sopenharmony_ci    u = [x.lower() for x in string.split(',')]
3427db96d56Sopenharmony_ci    for r in u:
3437db96d56Sopenharmony_ci        if r == 'all' or r == 'none':
3447db96d56Sopenharmony_ci            continue
3457db96d56Sopenharmony_ci        if r[0] == '-':
3467db96d56Sopenharmony_ci            r = r[1:]
3477db96d56Sopenharmony_ci        if r not in RESOURCE_NAMES:
3487db96d56Sopenharmony_ci            raise argparse.ArgumentTypeError('invalid resource: ' + r)
3497db96d56Sopenharmony_ci    return u
3507db96d56Sopenharmony_ci
3517db96d56Sopenharmony_ci
3527db96d56Sopenharmony_cidef _parse_args(args, **kwargs):
3537db96d56Sopenharmony_ci    # Defaults
3547db96d56Sopenharmony_ci    ns = Namespace()
3557db96d56Sopenharmony_ci    for k, v in kwargs.items():
3567db96d56Sopenharmony_ci        if not hasattr(ns, k):
3577db96d56Sopenharmony_ci            raise TypeError('%r is an invalid keyword argument '
3587db96d56Sopenharmony_ci                            'for this function' % k)
3597db96d56Sopenharmony_ci        setattr(ns, k, v)
3607db96d56Sopenharmony_ci    if ns.use_resources is None:
3617db96d56Sopenharmony_ci        ns.use_resources = []
3627db96d56Sopenharmony_ci
3637db96d56Sopenharmony_ci    parser = _create_parser()
3647db96d56Sopenharmony_ci    # Issue #14191: argparse doesn't support "intermixed" positional and
3657db96d56Sopenharmony_ci    # optional arguments. Use parse_known_args() as workaround.
3667db96d56Sopenharmony_ci    ns.args = parser.parse_known_args(args=args, namespace=ns)[1]
3677db96d56Sopenharmony_ci    for arg in ns.args:
3687db96d56Sopenharmony_ci        if arg.startswith('-'):
3697db96d56Sopenharmony_ci            parser.error("unrecognized arguments: %s" % arg)
3707db96d56Sopenharmony_ci            sys.exit(1)
3717db96d56Sopenharmony_ci
3727db96d56Sopenharmony_ci    if ns.single and ns.fromfile:
3737db96d56Sopenharmony_ci        parser.error("-s and -f don't go together!")
3747db96d56Sopenharmony_ci    if ns.use_mp is not None and ns.trace:
3757db96d56Sopenharmony_ci        parser.error("-T and -j don't go together!")
3767db96d56Sopenharmony_ci    if ns.python is not None:
3777db96d56Sopenharmony_ci        if ns.use_mp is None:
3787db96d56Sopenharmony_ci            parser.error("-p requires -j!")
3797db96d56Sopenharmony_ci        # The "executable" may be two or more parts, e.g. "node python.js"
3807db96d56Sopenharmony_ci        ns.python = shlex.split(ns.python)
3817db96d56Sopenharmony_ci    if ns.failfast and not (ns.verbose or ns.verbose3):
3827db96d56Sopenharmony_ci        parser.error("-G/--failfast needs either -v or -W")
3837db96d56Sopenharmony_ci    if ns.pgo and (ns.verbose or ns.verbose2 or ns.verbose3):
3847db96d56Sopenharmony_ci        parser.error("--pgo/-v don't go together!")
3857db96d56Sopenharmony_ci    if ns.pgo_extended:
3867db96d56Sopenharmony_ci        ns.pgo = True  # pgo_extended implies pgo
3877db96d56Sopenharmony_ci
3887db96d56Sopenharmony_ci    if ns.nowindows:
3897db96d56Sopenharmony_ci        print("Warning: the --nowindows (-n) option is deprecated. "
3907db96d56Sopenharmony_ci              "Use -vv to display assertions in stderr.", file=sys.stderr)
3917db96d56Sopenharmony_ci
3927db96d56Sopenharmony_ci    if ns.quiet:
3937db96d56Sopenharmony_ci        ns.verbose = 0
3947db96d56Sopenharmony_ci    if ns.timeout is not None:
3957db96d56Sopenharmony_ci        if ns.timeout <= 0:
3967db96d56Sopenharmony_ci            ns.timeout = None
3977db96d56Sopenharmony_ci    if ns.use_mp is not None:
3987db96d56Sopenharmony_ci        if ns.use_mp <= 0:
3997db96d56Sopenharmony_ci            # Use all cores + extras for tests that like to sleep
4007db96d56Sopenharmony_ci            ns.use_mp = 2 + (os.cpu_count() or 1)
4017db96d56Sopenharmony_ci    if ns.use:
4027db96d56Sopenharmony_ci        for a in ns.use:
4037db96d56Sopenharmony_ci            for r in a:
4047db96d56Sopenharmony_ci                if r == 'all':
4057db96d56Sopenharmony_ci                    ns.use_resources[:] = ALL_RESOURCES
4067db96d56Sopenharmony_ci                    continue
4077db96d56Sopenharmony_ci                if r == 'none':
4087db96d56Sopenharmony_ci                    del ns.use_resources[:]
4097db96d56Sopenharmony_ci                    continue
4107db96d56Sopenharmony_ci                remove = False
4117db96d56Sopenharmony_ci                if r[0] == '-':
4127db96d56Sopenharmony_ci                    remove = True
4137db96d56Sopenharmony_ci                    r = r[1:]
4147db96d56Sopenharmony_ci                if remove:
4157db96d56Sopenharmony_ci                    if r in ns.use_resources:
4167db96d56Sopenharmony_ci                        ns.use_resources.remove(r)
4177db96d56Sopenharmony_ci                elif r not in ns.use_resources:
4187db96d56Sopenharmony_ci                    ns.use_resources.append(r)
4197db96d56Sopenharmony_ci    if ns.random_seed is not None:
4207db96d56Sopenharmony_ci        ns.randomize = True
4217db96d56Sopenharmony_ci    if ns.verbose:
4227db96d56Sopenharmony_ci        ns.header = True
4237db96d56Sopenharmony_ci    if ns.huntrleaks and ns.verbose3:
4247db96d56Sopenharmony_ci        ns.verbose3 = False
4257db96d56Sopenharmony_ci        print("WARNING: Disable --verbose3 because it's incompatible with "
4267db96d56Sopenharmony_ci              "--huntrleaks: see http://bugs.python.org/issue27103",
4277db96d56Sopenharmony_ci              file=sys.stderr)
4287db96d56Sopenharmony_ci    if ns.match_filename:
4297db96d56Sopenharmony_ci        if ns.match_tests is None:
4307db96d56Sopenharmony_ci            ns.match_tests = []
4317db96d56Sopenharmony_ci        with open(ns.match_filename) as fp:
4327db96d56Sopenharmony_ci            for line in fp:
4337db96d56Sopenharmony_ci                ns.match_tests.append(line.strip())
4347db96d56Sopenharmony_ci    if ns.ignore_filename:
4357db96d56Sopenharmony_ci        if ns.ignore_tests is None:
4367db96d56Sopenharmony_ci            ns.ignore_tests = []
4377db96d56Sopenharmony_ci        with open(ns.ignore_filename) as fp:
4387db96d56Sopenharmony_ci            for line in fp:
4397db96d56Sopenharmony_ci                ns.ignore_tests.append(line.strip())
4407db96d56Sopenharmony_ci    if ns.forever:
4417db96d56Sopenharmony_ci        # --forever implies --failfast
4427db96d56Sopenharmony_ci        ns.failfast = True
4437db96d56Sopenharmony_ci
4447db96d56Sopenharmony_ci    return ns
445