Ignoring system folders when doing an os.listdir
Recently a very interesting bug has been reported agains Ubuntu One on Windows. Apparently we try to sync a number of system folders that are present on Windows 7 to be backward compatible.
The actual problem in the code is that we are using os.listdir. While lisdir on python does return system folders (at the end of the day, they are there) os.walk does not, for example, lets imaging hat we have the following scenario:
Documents My Pictures (System folder) My Videos (System folder) Random dir Random Text.txt
If we run os.listdir we would have the following:
import os >> os.listdir('Documents') ['My Pictures', 'My Videos', 'Random dir', 'Random Text.txt']
While if we use os.walk we have:
import os path, dirs, files = os.walk('Documents') print dirs >> ['Random dir'] print files >> ['Random Text.txt']
The fix is very simple, simply filter the result from os.listdir using the following function:
import win32file INVALID_FILE_ATTRIBUTES = -1 def is_system_path(path): """Return if the function is a system path.""" attrs = win32file.GetFileAttributesW(path) if attrs == INVALID_FILE_ATTRIBUTES: return False return win32file.FILE_ATTRIBUTE_SYSTEM & attrs == win32file.FILE_ATTRIBUTE_SYSTEM
File system events
An interesting question to ask after the above is, how does ReadDirectoryChangesW work with systen directories? Well, thankfully it works correctly. What does that mean? Well, it means the following:
- Changes in the system folders do not get notified.
- Moves from a watch directory to a system folder is not a MOVE_TO, MOVE_FROM couple but a FILE_DELETED
The above means that if you have a system folder in a watch path you do not need to worry since the events will work correctly, which are very very good news.