Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
6ff3e37a
Commit
6ff3e37a
authored
Jan 26, 2015
by
Serhiy Storchaka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #11578: Backported test for the timeit module.
parent
a43a9e72
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
314 additions
and
3 deletions
+314
-3
Lib/test/test_sundry.py
Lib/test/test_sundry.py
+0
-1
Lib/test/test_timeit.py
Lib/test/test_timeit.py
+304
-0
Lib/timeit.py
Lib/timeit.py
+8
-2
Misc/NEWS
Misc/NEWS
+2
-0
No files found.
Lib/test/test_sundry.py
View file @
6ff3e37a
...
...
@@ -71,7 +71,6 @@ class TestUntestedModules(unittest.TestCase):
import
sunaudio
import
symbol
import
tabnanny
import
timeit
import
toaiff
import
token
try
:
...
...
Lib/test/test_timeit.py
0 → 100644
View file @
6ff3e37a
import
timeit
import
unittest
import
sys
from
StringIO
import
StringIO
import
time
from
textwrap
import
dedent
from
test.support
import
run_unittest
from
test.support
import
captured_stdout
from
test.support
import
captured_stderr
# timeit's default number of iterations.
DEFAULT_NUMBER
=
1000000
# timeit's default number of repetitions.
DEFAULT_REPEAT
=
3
# XXX: some tests are commented out that would improve the coverage but take a
# long time to run because they test the default number of loops, which is
# large. The tests could be enabled if there was a way to override the default
# number of loops during testing, but this would require changing the signature
# of some functions that use the default as a default argument.
class
FakeTimer
:
BASE_TIME
=
42.0
def
__init__
(
self
,
seconds_per_increment
=
1.0
):
self
.
count
=
0
self
.
setup_calls
=
0
self
.
seconds_per_increment
=
seconds_per_increment
timeit
.
_fake_timer
=
self
def
__call__
(
self
):
return
self
.
BASE_TIME
+
self
.
count
*
self
.
seconds_per_increment
def
inc
(
self
):
self
.
count
+=
1
def
setup
(
self
):
self
.
setup_calls
+=
1
def
wrap_timer
(
self
,
timer
):
"""Records 'timer' and returns self as callable timer."""
self
.
saved_timer
=
timer
return
self
class
TestTimeit
(
unittest
.
TestCase
):
def
tearDown
(
self
):
try
:
del
timeit
.
_fake_timer
except
AttributeError
:
pass
def
test_reindent_empty
(
self
):
self
.
assertEqual
(
timeit
.
reindent
(
""
,
0
),
""
)
self
.
assertEqual
(
timeit
.
reindent
(
""
,
4
),
""
)
def
test_reindent_single
(
self
):
self
.
assertEqual
(
timeit
.
reindent
(
"pass"
,
0
),
"pass"
)
self
.
assertEqual
(
timeit
.
reindent
(
"pass"
,
4
),
"pass"
)
def
test_reindent_multi_empty
(
self
):
self
.
assertEqual
(
timeit
.
reindent
(
"
\
n
\
n
"
,
0
),
"
\
n
\
n
"
)
self
.
assertEqual
(
timeit
.
reindent
(
"
\
n
\
n
"
,
4
),
"
\
n
\
n
"
)
def
test_reindent_multi
(
self
):
self
.
assertEqual
(
timeit
.
reindent
(
"print()
\
n
pass
\
n
break"
,
0
),
"print()
\
n
pass
\
n
break"
)
self
.
assertEqual
(
timeit
.
reindent
(
"print()
\
n
pass
\
n
break"
,
4
),
"print()
\
n
pass
\
n
break"
)
def
test_timer_invalid_stmt
(
self
):
self
.
assertRaises
(
ValueError
,
timeit
.
Timer
,
stmt
=
None
)
def
test_timer_invalid_setup
(
self
):
self
.
assertRaises
(
ValueError
,
timeit
.
Timer
,
setup
=
None
)
fake_setup
=
"import timeit; timeit._fake_timer.setup()"
fake_stmt
=
"import timeit; timeit._fake_timer.inc()"
def
fake_callable_setup
(
self
):
self
.
fake_timer
.
setup
()
def
fake_callable_stmt
(
self
):
self
.
fake_timer
.
inc
()
def
timeit
(
self
,
stmt
,
setup
,
number
=
None
):
self
.
fake_timer
=
FakeTimer
()
t
=
timeit
.
Timer
(
stmt
=
stmt
,
setup
=
setup
,
timer
=
self
.
fake_timer
)
kwargs
=
{}
if
number
is
None
:
number
=
DEFAULT_NUMBER
else
:
kwargs
[
'number'
]
=
number
delta_time
=
t
.
timeit
(
**
kwargs
)
self
.
assertEqual
(
self
.
fake_timer
.
setup_calls
,
1
)
self
.
assertEqual
(
self
.
fake_timer
.
count
,
number
)
self
.
assertEqual
(
delta_time
,
number
)
# Takes too long to run in debug build.
#def test_timeit_default_iters(self):
# self.timeit(self.fake_stmt, self.fake_setup)
def
test_timeit_zero_iters
(
self
):
self
.
timeit
(
self
.
fake_stmt
,
self
.
fake_setup
,
number
=
0
)
def
test_timeit_few_iters
(
self
):
self
.
timeit
(
self
.
fake_stmt
,
self
.
fake_setup
,
number
=
3
)
def
test_timeit_callable_stmt
(
self
):
self
.
timeit
(
self
.
fake_callable_stmt
,
self
.
fake_setup
,
number
=
3
)
def
test_timeit_callable_stmt_and_setup
(
self
):
self
.
timeit
(
self
.
fake_callable_stmt
,
self
.
fake_callable_setup
,
number
=
3
)
# Takes too long to run in debug build.
#def test_timeit_function(self):
# delta_time = timeit.timeit(self.fake_stmt, self.fake_setup,
# timer=FakeTimer())
# self.assertEqual(delta_time, DEFAULT_NUMBER)
def
test_timeit_function_zero_iters
(
self
):
delta_time
=
timeit
.
timeit
(
self
.
fake_stmt
,
self
.
fake_setup
,
number
=
0
,
timer
=
FakeTimer
())
self
.
assertEqual
(
delta_time
,
0
)
def
repeat
(
self
,
stmt
,
setup
,
repeat
=
None
,
number
=
None
):
self
.
fake_timer
=
FakeTimer
()
t
=
timeit
.
Timer
(
stmt
=
stmt
,
setup
=
setup
,
timer
=
self
.
fake_timer
)
kwargs
=
{}
if
repeat
is
None
:
repeat
=
DEFAULT_REPEAT
else
:
kwargs
[
'repeat'
]
=
repeat
if
number
is
None
:
number
=
DEFAULT_NUMBER
else
:
kwargs
[
'number'
]
=
number
delta_times
=
t
.
repeat
(
**
kwargs
)
self
.
assertEqual
(
self
.
fake_timer
.
setup_calls
,
repeat
)
self
.
assertEqual
(
self
.
fake_timer
.
count
,
repeat
*
number
)
self
.
assertEqual
(
delta_times
,
repeat
*
[
float
(
number
)])
# Takes too long to run in debug build.
#def test_repeat_default(self):
# self.repeat(self.fake_stmt, self.fake_setup)
def
test_repeat_zero_reps
(
self
):
self
.
repeat
(
self
.
fake_stmt
,
self
.
fake_setup
,
repeat
=
0
)
def
test_repeat_zero_iters
(
self
):
self
.
repeat
(
self
.
fake_stmt
,
self
.
fake_setup
,
number
=
0
)
def
test_repeat_few_reps_and_iters
(
self
):
self
.
repeat
(
self
.
fake_stmt
,
self
.
fake_setup
,
repeat
=
3
,
number
=
5
)
def
test_repeat_callable_stmt
(
self
):
self
.
repeat
(
self
.
fake_callable_stmt
,
self
.
fake_setup
,
repeat
=
3
,
number
=
5
)
def
test_repeat_callable_stmt_and_setup
(
self
):
self
.
repeat
(
self
.
fake_callable_stmt
,
self
.
fake_callable_setup
,
repeat
=
3
,
number
=
5
)
# Takes too long to run in debug build.
#def test_repeat_function(self):
# delta_times = timeit.repeat(self.fake_stmt, self.fake_setup,
# timer=FakeTimer())
# self.assertEqual(delta_times, DEFAULT_REPEAT * [float(DEFAULT_NUMBER)])
def
test_repeat_function_zero_reps
(
self
):
delta_times
=
timeit
.
repeat
(
self
.
fake_stmt
,
self
.
fake_setup
,
repeat
=
0
,
timer
=
FakeTimer
())
self
.
assertEqual
(
delta_times
,
[])
def
test_repeat_function_zero_iters
(
self
):
delta_times
=
timeit
.
repeat
(
self
.
fake_stmt
,
self
.
fake_setup
,
number
=
0
,
timer
=
FakeTimer
())
self
.
assertEqual
(
delta_times
,
DEFAULT_REPEAT
*
[
0.0
])
def
assert_exc_string
(
self
,
exc_string
,
expected_exc_name
):
exc_lines
=
exc_string
.
splitlines
()
self
.
assertGreater
(
len
(
exc_lines
),
2
)
self
.
assertTrue
(
exc_lines
[
0
].
startswith
(
'Traceback'
))
self
.
assertTrue
(
exc_lines
[
-
1
].
startswith
(
expected_exc_name
))
def
test_print_exc
(
self
):
s
=
StringIO
()
t
=
timeit
.
Timer
(
"1/0"
)
try
:
t
.
timeit
()
except
:
t
.
print_exc
(
s
)
self
.
assert_exc_string
(
s
.
getvalue
(),
'ZeroDivisionError'
)
MAIN_DEFAULT_OUTPUT
=
"10 loops, best of 3: 1 sec per loop
\
n
"
def
run_main
(
self
,
seconds_per_increment
=
1.0
,
switches
=
None
,
timer
=
None
):
if
timer
is
None
:
timer
=
FakeTimer
(
seconds_per_increment
=
seconds_per_increment
)
if
switches
is
None
:
args
=
[]
else
:
args
=
switches
[:]
args
.
append
(
self
.
fake_stmt
)
# timeit.main() modifies sys.path, so save and restore it.
orig_sys_path
=
sys
.
path
[:]
with
captured_stdout
()
as
s
:
timeit
.
main
(
args
=
args
,
_wrap_timer
=
timer
.
wrap_timer
)
sys
.
path
[:]
=
orig_sys_path
[:]
return
s
.
getvalue
()
def
test_main_bad_switch
(
self
):
s
=
self
.
run_main
(
switches
=
[
'--bad-switch'
])
self
.
assertEqual
(
s
,
dedent
(
"""
\
option --bad-switch not recognized
use -h/--help for command line help
"""
))
def
test_main_seconds
(
self
):
s
=
self
.
run_main
(
seconds_per_increment
=
5.5
)
self
.
assertEqual
(
s
,
"10 loops, best of 3: 5.5 sec per loop
\
n
"
)
def
test_main_milliseconds
(
self
):
s
=
self
.
run_main
(
seconds_per_increment
=
0.0055
)
self
.
assertEqual
(
s
,
"100 loops, best of 3: 5.5 msec per loop
\
n
"
)
def
test_main_microseconds
(
self
):
s
=
self
.
run_main
(
seconds_per_increment
=
0.0000025
,
switches
=
[
'-n100'
])
self
.
assertEqual
(
s
,
"100 loops, best of 3: 2.5 usec per loop
\
n
"
)
def
test_main_fixed_iters
(
self
):
s
=
self
.
run_main
(
seconds_per_increment
=
2.0
,
switches
=
[
'-n35'
])
self
.
assertEqual
(
s
,
"35 loops, best of 3: 2 sec per loop
\
n
"
)
def
test_main_setup
(
self
):
s
=
self
.
run_main
(
seconds_per_increment
=
2.0
,
switches
=
[
'-n35'
,
'-s'
,
'print("CustomSetup")'
])
self
.
assertEqual
(
s
,
"CustomSetup
\
n
"
*
3
+
"35 loops, best of 3: 2 sec per loop
\
n
"
)
def
test_main_fixed_reps
(
self
):
s
=
self
.
run_main
(
seconds_per_increment
=
60.0
,
switches
=
[
'-r9'
])
self
.
assertEqual
(
s
,
"10 loops, best of 9: 60 sec per loop
\
n
"
)
def
test_main_negative_reps
(
self
):
s
=
self
.
run_main
(
seconds_per_increment
=
60.0
,
switches
=
[
'-r-5'
])
self
.
assertEqual
(
s
,
"10 loops, best of 1: 60 sec per loop
\
n
"
)
@
unittest
.
skipIf
(
sys
.
flags
.
optimize
>=
2
,
"need __doc__"
)
def
test_main_help
(
self
):
s
=
self
.
run_main
(
switches
=
[
'-h'
])
self
.
assertEqual
(
s
,
timeit
.
__doc__
)
def
test_main_using_time
(
self
):
fake_timer
=
FakeTimer
()
s
=
self
.
run_main
(
switches
=
[
'-t'
],
timer
=
fake_timer
)
self
.
assertEqual
(
s
,
self
.
MAIN_DEFAULT_OUTPUT
)
self
.
assertIs
(
fake_timer
.
saved_timer
,
time
.
time
)
def
test_main_using_clock
(
self
):
fake_timer
=
FakeTimer
()
s
=
self
.
run_main
(
switches
=
[
'-c'
],
timer
=
fake_timer
)
self
.
assertEqual
(
s
,
self
.
MAIN_DEFAULT_OUTPUT
)
self
.
assertIs
(
fake_timer
.
saved_timer
,
time
.
clock
)
def
test_main_verbose
(
self
):
s
=
self
.
run_main
(
switches
=
[
'-v'
])
self
.
assertEqual
(
s
,
dedent
(
"""
\
10 loops -> 10 secs
raw times: 10 10 10
10 loops, best of 3: 1 sec per loop
"""
))
def
test_main_very_verbose
(
self
):
s
=
self
.
run_main
(
seconds_per_increment
=
0.000050
,
switches
=
[
'-vv'
])
self
.
assertEqual
(
s
,
dedent
(
"""
\
10 loops -> 0.0005 secs
100 loops -> 0.005 secs
1000 loops -> 0.05 secs
10000 loops -> 0.5 secs
raw times: 0.5 0.5 0.5
10000 loops, best of 3: 50 usec per loop
"""
))
def
test_main_exception
(
self
):
with
captured_stderr
()
as
error_stringio
:
s
=
self
.
run_main
(
switches
=
[
'1/0'
])
self
.
assert_exc_string
(
error_stringio
.
getvalue
(),
'ZeroDivisionError'
)
def
test_main_exception_fixed_reps
(
self
):
with
captured_stderr
()
as
error_stringio
:
s
=
self
.
run_main
(
switches
=
[
'-n1'
,
'1/0'
])
self
.
assert_exc_string
(
error_stringio
.
getvalue
(),
'ZeroDivisionError'
)
def
test_main
():
run_unittest
(
TestTimeit
)
if
__name__
==
'__main__'
:
test_main
()
Lib/timeit.py
View file @
6ff3e37a
...
...
@@ -234,10 +234,10 @@ def repeat(stmt="pass", setup="pass", timer=default_timer,
"""Convenience function to create Timer object and call repeat method."""
return
Timer
(
stmt
,
setup
,
timer
).
repeat
(
repeat
,
number
)
def
main
(
args
=
None
):
def
main
(
args
=
None
,
_wrap_timer
=
None
):
"""Main program, used when run as a script.
The optional argument specifies the command line to be parsed,
The optional
'args'
argument specifies the command line to be parsed,
defaulting to sys.argv[1:].
The return value is an exit code to be passed to sys.exit(); it
...
...
@@ -246,6 +246,10 @@ def main(args=None):
When an exception happens during timing, a traceback is printed to
stderr and the return value is 1. Exceptions at other times
(including the template compilation) are not caught.
'_wrap_timer' is an internal interface used for unit testing. If it
is not None, it must be a callable that accepts a timer function
and returns another timer function (used for unit testing).
"""
if
args
is
None
:
args
=
sys
.
argv
[
1
:]
...
...
@@ -291,6 +295,8 @@ def main(args=None):
# directory)
import
os
sys
.
path
.
insert
(
0
,
os
.
curdir
)
if
_wrap_timer
is
not
None
:
timer
=
_wrap_timer
(
timer
)
t
=
Timer
(
stmt
,
setup
,
timer
)
if
number
==
0
:
# determine number so that 0.2 <= total time < 2.0
...
...
Misc/NEWS
View file @
6ff3e37a
...
...
@@ -83,6 +83,8 @@ Tools/Demos
Tests
-----
-
Issue
#
11578
:
Backported
test
for
the
timeit
module
.
-
Issue
#
22943
:
bsddb
tests
are
locale
independend
now
.
IDLE
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment