Mercurial > repos > rliterman > csp2
comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/unittest/main.py @ 68:5028fdace37b
planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author | jpayne |
---|---|
date | Tue, 18 Mar 2025 16:23:26 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
67:0e9998148a16 | 68:5028fdace37b |
---|---|
1 """Unittest main program""" | |
2 | |
3 import sys | |
4 import argparse | |
5 import os | |
6 | |
7 from . import loader, runner | |
8 from .signals import installHandler | |
9 | |
10 __unittest = True | |
11 | |
12 MAIN_EXAMPLES = """\ | |
13 Examples: | |
14 %(prog)s test_module - run tests from test_module | |
15 %(prog)s module.TestClass - run tests from module.TestClass | |
16 %(prog)s module.Class.test_method - run specified test method | |
17 %(prog)s path/to/test_file.py - run tests from test_file.py | |
18 """ | |
19 | |
20 MODULE_EXAMPLES = """\ | |
21 Examples: | |
22 %(prog)s - run default set of tests | |
23 %(prog)s MyTestSuite - run suite 'MyTestSuite' | |
24 %(prog)s MyTestCase.testSomething - run MyTestCase.testSomething | |
25 %(prog)s MyTestCase - run all 'test*' test methods | |
26 in MyTestCase | |
27 """ | |
28 | |
29 def _convert_name(name): | |
30 # on Linux / Mac OS X 'foo.PY' is not importable, but on | |
31 # Windows it is. Simpler to do a case insensitive match | |
32 # a better check would be to check that the name is a | |
33 # valid Python module name. | |
34 if os.path.isfile(name) and name.lower().endswith('.py'): | |
35 if os.path.isabs(name): | |
36 rel_path = os.path.relpath(name, os.getcwd()) | |
37 if os.path.isabs(rel_path) or rel_path.startswith(os.pardir): | |
38 return name | |
39 name = rel_path | |
40 # on Windows both '\' and '/' are used as path | |
41 # separators. Better to replace both than rely on os.path.sep | |
42 return name[:-3].replace('\\', '.').replace('/', '.') | |
43 return name | |
44 | |
45 def _convert_names(names): | |
46 return [_convert_name(name) for name in names] | |
47 | |
48 | |
49 def _convert_select_pattern(pattern): | |
50 if not '*' in pattern: | |
51 pattern = '*%s*' % pattern | |
52 return pattern | |
53 | |
54 | |
55 class TestProgram(object): | |
56 """A command-line program that runs a set of tests; this is primarily | |
57 for making test modules conveniently executable. | |
58 """ | |
59 # defaults for testing | |
60 module=None | |
61 verbosity = 1 | |
62 failfast = catchbreak = buffer = progName = warnings = testNamePatterns = None | |
63 _discovery_parser = None | |
64 | |
65 def __init__(self, module='__main__', defaultTest=None, argv=None, | |
66 testRunner=None, testLoader=loader.defaultTestLoader, | |
67 exit=True, verbosity=1, failfast=None, catchbreak=None, | |
68 buffer=None, warnings=None, *, tb_locals=False): | |
69 if isinstance(module, str): | |
70 self.module = __import__(module) | |
71 for part in module.split('.')[1:]: | |
72 self.module = getattr(self.module, part) | |
73 else: | |
74 self.module = module | |
75 if argv is None: | |
76 argv = sys.argv | |
77 | |
78 self.exit = exit | |
79 self.failfast = failfast | |
80 self.catchbreak = catchbreak | |
81 self.verbosity = verbosity | |
82 self.buffer = buffer | |
83 self.tb_locals = tb_locals | |
84 if warnings is None and not sys.warnoptions: | |
85 # even if DeprecationWarnings are ignored by default | |
86 # print them anyway unless other warnings settings are | |
87 # specified by the warnings arg or the -W python flag | |
88 self.warnings = 'default' | |
89 else: | |
90 # here self.warnings is set either to the value passed | |
91 # to the warnings args or to None. | |
92 # If the user didn't pass a value self.warnings will | |
93 # be None. This means that the behavior is unchanged | |
94 # and depends on the values passed to -W. | |
95 self.warnings = warnings | |
96 self.defaultTest = defaultTest | |
97 self.testRunner = testRunner | |
98 self.testLoader = testLoader | |
99 self.progName = os.path.basename(argv[0]) | |
100 self.parseArgs(argv) | |
101 self.runTests() | |
102 | |
103 def usageExit(self, msg=None): | |
104 if msg: | |
105 print(msg) | |
106 if self._discovery_parser is None: | |
107 self._initArgParsers() | |
108 self._print_help() | |
109 sys.exit(2) | |
110 | |
111 def _print_help(self, *args, **kwargs): | |
112 if self.module is None: | |
113 print(self._main_parser.format_help()) | |
114 print(MAIN_EXAMPLES % {'prog': self.progName}) | |
115 self._discovery_parser.print_help() | |
116 else: | |
117 print(self._main_parser.format_help()) | |
118 print(MODULE_EXAMPLES % {'prog': self.progName}) | |
119 | |
120 def parseArgs(self, argv): | |
121 self._initArgParsers() | |
122 if self.module is None: | |
123 if len(argv) > 1 and argv[1].lower() == 'discover': | |
124 self._do_discovery(argv[2:]) | |
125 return | |
126 self._main_parser.parse_args(argv[1:], self) | |
127 if not self.tests: | |
128 # this allows "python -m unittest -v" to still work for | |
129 # test discovery. | |
130 self._do_discovery([]) | |
131 return | |
132 else: | |
133 self._main_parser.parse_args(argv[1:], self) | |
134 | |
135 if self.tests: | |
136 self.testNames = _convert_names(self.tests) | |
137 if __name__ == '__main__': | |
138 # to support python -m unittest ... | |
139 self.module = None | |
140 elif self.defaultTest is None: | |
141 # createTests will load tests from self.module | |
142 self.testNames = None | |
143 elif isinstance(self.defaultTest, str): | |
144 self.testNames = (self.defaultTest,) | |
145 else: | |
146 self.testNames = list(self.defaultTest) | |
147 self.createTests() | |
148 | |
149 def createTests(self, from_discovery=False, Loader=None): | |
150 if self.testNamePatterns: | |
151 self.testLoader.testNamePatterns = self.testNamePatterns | |
152 if from_discovery: | |
153 loader = self.testLoader if Loader is None else Loader() | |
154 self.test = loader.discover(self.start, self.pattern, self.top) | |
155 elif self.testNames is None: | |
156 self.test = self.testLoader.loadTestsFromModule(self.module) | |
157 else: | |
158 self.test = self.testLoader.loadTestsFromNames(self.testNames, | |
159 self.module) | |
160 | |
161 def _initArgParsers(self): | |
162 parent_parser = self._getParentArgParser() | |
163 self._main_parser = self._getMainArgParser(parent_parser) | |
164 self._discovery_parser = self._getDiscoveryArgParser(parent_parser) | |
165 | |
166 def _getParentArgParser(self): | |
167 parser = argparse.ArgumentParser(add_help=False) | |
168 | |
169 parser.add_argument('-v', '--verbose', dest='verbosity', | |
170 action='store_const', const=2, | |
171 help='Verbose output') | |
172 parser.add_argument('-q', '--quiet', dest='verbosity', | |
173 action='store_const', const=0, | |
174 help='Quiet output') | |
175 parser.add_argument('--locals', dest='tb_locals', | |
176 action='store_true', | |
177 help='Show local variables in tracebacks') | |
178 if self.failfast is None: | |
179 parser.add_argument('-f', '--failfast', dest='failfast', | |
180 action='store_true', | |
181 help='Stop on first fail or error') | |
182 self.failfast = False | |
183 if self.catchbreak is None: | |
184 parser.add_argument('-c', '--catch', dest='catchbreak', | |
185 action='store_true', | |
186 help='Catch Ctrl-C and display results so far') | |
187 self.catchbreak = False | |
188 if self.buffer is None: | |
189 parser.add_argument('-b', '--buffer', dest='buffer', | |
190 action='store_true', | |
191 help='Buffer stdout and stderr during tests') | |
192 self.buffer = False | |
193 if self.testNamePatterns is None: | |
194 parser.add_argument('-k', dest='testNamePatterns', | |
195 action='append', type=_convert_select_pattern, | |
196 help='Only run tests which match the given substring') | |
197 self.testNamePatterns = [] | |
198 | |
199 return parser | |
200 | |
201 def _getMainArgParser(self, parent): | |
202 parser = argparse.ArgumentParser(parents=[parent]) | |
203 parser.prog = self.progName | |
204 parser.print_help = self._print_help | |
205 | |
206 parser.add_argument('tests', nargs='*', | |
207 help='a list of any number of test modules, ' | |
208 'classes and test methods.') | |
209 | |
210 return parser | |
211 | |
212 def _getDiscoveryArgParser(self, parent): | |
213 parser = argparse.ArgumentParser(parents=[parent]) | |
214 parser.prog = '%s discover' % self.progName | |
215 parser.epilog = ('For test discovery all test modules must be ' | |
216 'importable from the top level directory of the ' | |
217 'project.') | |
218 | |
219 parser.add_argument('-s', '--start-directory', dest='start', | |
220 help="Directory to start discovery ('.' default)") | |
221 parser.add_argument('-p', '--pattern', dest='pattern', | |
222 help="Pattern to match tests ('test*.py' default)") | |
223 parser.add_argument('-t', '--top-level-directory', dest='top', | |
224 help='Top level directory of project (defaults to ' | |
225 'start directory)') | |
226 for arg in ('start', 'pattern', 'top'): | |
227 parser.add_argument(arg, nargs='?', | |
228 default=argparse.SUPPRESS, | |
229 help=argparse.SUPPRESS) | |
230 | |
231 return parser | |
232 | |
233 def _do_discovery(self, argv, Loader=None): | |
234 self.start = '.' | |
235 self.pattern = 'test*.py' | |
236 self.top = None | |
237 if argv is not None: | |
238 # handle command line args for test discovery | |
239 if self._discovery_parser is None: | |
240 # for testing | |
241 self._initArgParsers() | |
242 self._discovery_parser.parse_args(argv, self) | |
243 | |
244 self.createTests(from_discovery=True, Loader=Loader) | |
245 | |
246 def runTests(self): | |
247 if self.catchbreak: | |
248 installHandler() | |
249 if self.testRunner is None: | |
250 self.testRunner = runner.TextTestRunner | |
251 if isinstance(self.testRunner, type): | |
252 try: | |
253 try: | |
254 testRunner = self.testRunner(verbosity=self.verbosity, | |
255 failfast=self.failfast, | |
256 buffer=self.buffer, | |
257 warnings=self.warnings, | |
258 tb_locals=self.tb_locals) | |
259 except TypeError: | |
260 # didn't accept the tb_locals argument | |
261 testRunner = self.testRunner(verbosity=self.verbosity, | |
262 failfast=self.failfast, | |
263 buffer=self.buffer, | |
264 warnings=self.warnings) | |
265 except TypeError: | |
266 # didn't accept the verbosity, buffer or failfast arguments | |
267 testRunner = self.testRunner() | |
268 else: | |
269 # it is assumed to be a TestRunner instance | |
270 testRunner = self.testRunner | |
271 self.result = testRunner.run(self.test) | |
272 if self.exit: | |
273 sys.exit(not self.result.wasSuccessful()) | |
274 | |
275 main = TestProgram |