I am running unit tests on a CI server using py.test. Tests use external resources fetched over network. Sometimes test runner takes too long, causing test runner to be aborted. I cannot repeat the issues locally.
Is there a way to make py.test print out execution times of (slow) test, so pinning down problematic tests become easier?
Printing test execution times and pinning down slow tests with py.test abort: Questions
How do I abort the execution of a Python script?
1 answers
I have a simple Python script that I want to stop executing if a condition is met.
For example:
done = True
if done:
# quit/stop/exit
else:
# do other stuff
Essentially, I am looking for something that behaves equivalently to the "return" keyword in the body of a function which allows the flow of the code to exit the function and not execute the remaining code.
Answer #1
To exit a script you can use,
import sys
sys.exit()
You can also provide an exit status value, usually an integer.
import sys
sys.exit(0)
Exits with zero, which is generally interpreted as success. Non-zero codes are usually treated as errors. The default is to exit with zero.
import sys
sys.exit("aa! errors!")
Prints "aa! errors!" and exits with a status code of 1.
There is also an _exit() function in the os module. The sys.exit() function raises a SystemExit exception to exit the program, so try statements and cleanup code can execute. The os._exit() version doesn"t do this. It just ends the program without doing any cleanup or flushing output buffers, so it shouldn"t normally be used.
The Python docs indicate that os._exit() is the normal way to end a child process created with a call to os.fork(), so it does have a use in certain circumstances.
Printing test execution times and pinning down slow tests with py.test repeat: Questions
Create list of single item repeated N times
5 answers
I want to create a series of lists, all of varying lengths. Each list will contain the same element e
, repeated n
times (where n
= length of the list).
How do I create the lists, without using a list comprehension [e for number in xrange(n)]
for each list?
Answer #1
You can also write:
[e] * n
You should note that if e is for example an empty list you get a list with n references to the same list, not n independent empty lists.
Performance testing
At first glance it seems that repeat is the fastest way to create a list with n identical elements:
>>> timeit.timeit("itertools.repeat(0, 10)", "import itertools", number = 1000000)
0.37095273281943264
>>> timeit.timeit("[0] * 10", "import itertools", number = 1000000)
0.5577236771712819
But wait - it"s not a fair test...
>>> itertools.repeat(0, 10)
repeat(0, 10) # Not a list!!!
The function itertools.repeat
doesn"t actually create the list, it just creates an object that can be used to create a list if you wish! Let"s try that again, but converting to a list:
>>> timeit.timeit("list(itertools.repeat(0, 10))", "import itertools", number = 1000000)
1.7508119747063233
So if you want a list, use [e] * n
. If you want to generate the elements lazily, use repeat
.
What is the best way to repeatedly execute a function every x seconds?
5 answers
I want to repeatedly execute a function in Python every 60 seconds forever (just like an NSTimer in Objective C). This code will run as a daemon and is effectively like calling the python script every minute using a cron, but without requiring that to be set up by the user.
In this question about a cron implemented in Python, the solution appears to effectively just sleep() for x seconds. I don"t need such advanced functionality so perhaps something like this would work
while True:
# Code executed here
time.sleep(60)
Are there any foreseeable problems with this code?
Answer #1
If your program doesn"t have a event loop already, use the sched module, which implements a general purpose event scheduler.
import sched, time
s = sched.scheduler(time.time, time.sleep)
def do_something(sc):
print("Doing stuff...")
# do your stuff
s.enter(60, 1, do_something, (sc,))
s.enter(60, 1, do_something, (s,))
s.run()
If you"re already using an event loop library like asyncio
, trio
, tkinter
, PyQt5
, gobject
, kivy
, and many others - just schedule the task using your existing event loop library"s methods, instead.
Answer #2
Lock your time loop to the system clock like this:
import time
starttime = time.time()
while True:
print "tick"
time.sleep(60.0 - ((time.time() - starttime) % 60.0))