classification
Title: os.walk recurses down even with dirnames deleted
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.4, Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Sworddragon, ned.deily
Priority: normal Keywords:

Created on 2014-02-25 04:26 by Sworddragon, last changed 2014-02-26 03:49 by ned.deily. This issue is now closed.

Files
File name Uploaded Description Edit
test.py Sworddragon, 2014-02-25 04:26 Testcase
Messages (4)
msg212159 - (view) Author: (Sworddragon) Date: 2014-02-25 04:26
The following was tested on Linux. In the attachments is the example code and here is my output:

sworddragon@ubuntu:/tmp$ ./test.py
1


I'm deleting the list of directories on every recursion and skipping if I'm directly in /proc (which is theoretically already unneeded). Also the default value for topdown is True and followlinks is False. I have already read the documentation but I'm not seeing any way how the condition could be True so I'm assuming this is a bug.
msg212163 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2014-02-25 05:50
I think you are misunderstanding how del and mutable sequences work.  In your code snippet, the del unbinds the name "root_dir" but it does not alter the dirnames list object returned by os.path.  Try replacing "del root_dir" with "del root_dir[:]" or "root_dir.clear()".

http://docs.python.org/3/reference/simple_stmts.html#the-del-statement
http://docs.python.org/3/library/stdtypes.html#mutable-sequence-types
msg212237 - (view) Author: (Sworddragon) Date: 2014-02-26 03:33
It sounds like me that "del dir_list" does only delete the copied list while "del dir_list[:]" accesses the reference and deletes this list. If I'm not wrong with this assumption I think you was meaning dir_list instead of root_dir in your post.

But thanks for the help as I have not expected this on reading just the documentation of os.walk().
msg212239 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2014-02-26 03:49
Yes, I did indeed mean "dir_list", not "root_dir".  Sorry for the confusion.  One point: there is no "copied list".  "del dir_list" merely deletes the binding between the name "dir_list" and the list object returned by "os.walk"; the list object itself is unaltered but can no longer be referenced by the name dir_list.  "del dir_list[:]" mutates the list object pointed to by dir_list by deleting the references to all of its member elements, turning it into an empty list; the binding of the list object to the name dir_list remains.
History
Date User Action Args
2014-02-26 03:49:56ned.deilysetmessages: + msg212239
2014-02-26 03:33:22Sworddragonsetmessages: + msg212237
2014-02-25 05:50:23ned.deilysetstatus: open -> closed

nosy: + ned.deily
messages: + msg212163

resolution: not a bug
stage: resolved
2014-02-25 04:26:55Sworddragoncreate