Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python file existence checks loop crashes - unless I add a print statement

I'm porting a program from Python2 (don't know the exact version used) to Python3.3 and updating a few things, but this loop that checks the existence of a set of recently accessed file paths against the actual files crashes.

for index in range(story.recentFiles.GetCount()):
    try:
        if not os.path.exists(story.recentFiles.GetHistoryFile(index)): pass
    except IOError:
        self.RemoveRecentFile(story, index)
        break

Accessing a single file works fine, so it's something to do with the loop. If I step through the loop with a debugger, the code works fine, but if I just run the application, it crashes on a "python.exe has stopped responding" error.

The weirdest part, though, has got to be that when I add a print statement before the os.path.exists, it works on a regular runthrough:

for index in range(story.recentFiles.GetCount()):
    try:
        print('test') # Why does printing this make it not crash??
        if not os.path.exists(story.recentFiles.GetHistoryFile(index)): pass
    except IOError:
        self.RemoveRecentFile(story, index)
        break

What is up with that? I'm assuming it has some kind of relation to the speed of the loop versus file access times or something since stepping through slowly allows it to execute fine, but I honestly have no idea what the issue is.

like image 393
Way Spurr-Chen Avatar asked Jul 06 '13 23:07

Way Spurr-Chen


2 Answers

It is hard to say much with more details, but here is a theory: when you add print, this actually raises an IOError (this is possible, as documented), which is caught, and os.path.exists(story.recentFiles.GetHistoryFile(index)) is not executed, so your program does not hang.

You can test this with a test like the following (before the code you quote):

try:
    print('test')
except IOError:
    with open('ioerror_raised.txt', 'w'):
        pass

which will create a file ioerror_raised.txt if the print raised IOError.

This could explain why adding a print makes the code run.

(If this is the case, then os.path.exists(story.recentFiles.GetHistoryFile(index)) should obviously be debugged.)

like image 130
Eric O Lebigot Avatar answered Nov 15 '22 19:11

Eric O Lebigot


You create a static list of valid indexes (with range()) at the beginning of the loop, but you are removing files from the list (RemoveRecentFile) within the loop.

So your problem might be, that you start the loop with 10 files, removed one file (eg index 4) because you can't access it, and then try to access file the 10th file (index 9) which is not there anymore because you have moved 5->4, 6->5, 7->6, 8->7, 9->8

like image 42
Ruediger Jungbeck Avatar answered Nov 15 '22 17:11

Ruediger Jungbeck