Skip to content

Commit dbdb9a9

Browse files
committed
fix handling of --
1 parent 4e4fba1 commit dbdb9a9

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

Lib/test/test_timeit.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,11 @@ def run_main(self, seconds_per_increment=1.0, switches=None, timer=None):
246246
args.append(self.fake_stmt)
247247
# timeit.main() modifies sys.path, so save and restore it.
248248
orig_sys_path = sys.path[:]
249-
with captured_stdout() as s:
250-
timeit.main(args=args, _wrap_timer=timer.wrap_timer)
251-
sys.path[:] = orig_sys_path[:]
249+
try:
250+
with captured_stdout() as s:
251+
timeit.main(args=args, _wrap_timer=timer.wrap_timer)
252+
finally:
253+
sys.path[:] = orig_sys_path[:]
252254
return s.getvalue()
253255

254256
def test_main_bad_switch(self):
@@ -353,6 +355,17 @@ def test_main_exception_fixed_reps(self):
353355
s = self.run_main(switches=['-n1', '1/0'])
354356
self.assert_exc_string(error_stringio.getvalue(), 'ZeroDivisionError')
355357

358+
def test_main_without_option_separator(self):
359+
out = self.run_main(switches=['-n2', '-r2', '1'])
360+
self.assertEqual(out, "2 loops, best of 2: 1 sec per loop\n")
361+
362+
def test_main_with_option_separator(self):
363+
with self.assertRaises(SyntaxError):
364+
self.run_main(switches=['--', '1 + 1', '--'])
365+
366+
out = self.run_main(switches=['-n2', '-r2', '--', '1'])
367+
self.assertEqual(out, "2 loops, best of 2: 1 sec per loop\n")
368+
356369
def test_main_with_option_like_at_the_end(self):
357370
with captured_stderr() as s:
358371
self.run_main(switches=['-n1', '1 + 1', '-n1'])

Lib/timeit.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ def _make_parser():
227227
argument in quotes and using leading spaces. Multiple -s options are
228228
treated similarly.
229229
230+
Use "--" to separate command-line options from actual statements,
231+
or when a statement starts with '-'.
232+
230233
If -n is not given, a suitable number of loops is calculated by trying
231234
increasing numbers from the sequence 1, 2, 5, 10, 20, 50, ... until the
232235
total time is at least 0.2 seconds.
@@ -265,13 +268,9 @@ def _make_parser():
265268
"-v", "--verbose", action="count", default=0,
266269
help="print raw timing results; repeat for more digits precision",
267270
)
268-
# add a dummy option to document '--'
269-
group.add_argument(
270-
"--", dest="_", action="store_const", const=None,
271-
help="separate options from statement; "
272-
"use when statement starts with -",
273-
)
274-
# use argparse.REMAINDER to ignore option-like argument found at the end
271+
# Use argparse.REMAINDER to ignore option-like argument found at the end.
272+
# If '--' is being specified as the "first" statement, it will be ignored
273+
# and used to separate the options from the list of statements.
275274
group.add_argument(
276275
"statement", nargs=argparse.REMAINDER,
277276
help="statement to be timed (default: 'pass')",
@@ -300,6 +299,8 @@ def main(args=None, *, _wrap_timer=None):
300299
args = parser.parse_args(args)
301300

302301
setup = "\n".join(args.setup) or "pass"
302+
if args.statement and args.statement[0] == '--':
303+
args.statement.pop(0)
303304
stmt = "\n".join(args.statement) or "pass"
304305
timer = time.process_time if args.process else default_timer
305306
number = args.number # will be deduced if 0

0 commit comments

Comments
 (0)