I have code that copies files. When it is doing so a cursor spins. This all works fine. However if I use Ctrl + C to stop the copy I expect the KeyboardInterrupt
to set the event and the cursor to stop spinning. The copy stops however the cursor spins forever, why is this?
I tried putting a print into the Interrupt and that did not get displayed, so it seems it is not being called?
def spinning_cursor(event):
for j in itertools.cycle('/-\|'):
if not event.is_set():
sys.stdout.write(j)
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write('\b')
else:
return
def copy_file(sfile, dfile, sync):
processing_flag = Event()
Thread(target = spinning_cursor, kwargs = {'event': processing_flag}).start()
if os.path.exists(sfile):
try:
shutil.copyfile(sfile, dfile)
processing_flag.set()
except KeyboardInterrupt:
processing_flag.set()
pass
...
It is not really an answer, because I cannot explain what really happens, but I could partially reproduce. It looks like copy_file
swallows the KeyboardInterrupt and raises another exception. If that happens, as the processing_flag.set()
is only in the normal and except KeyboardInterrupt
branches, control never passes there. As a consequence, the Event is never set and the child thread keeps on spinning (that's what I did to reproduce the behaviour...)
I could find 2 possible workarounds
use except
without any filtering:
try: shutil.copyfile(sfile, dfile) processing_flag.set() except: processing_flag.set() pass
that should be enough to catch any possible exception raised by copyfile
use a finally
block. I personally prefere that way, because it is really what finally
is aimed to: execute that branch whatever could happen. In that case, you could even remove the except
block and have just a try:... finally:...
:
try: shutil.copyfile(sfile, dfile) finally: processing_flag.set()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.