[Python-Dev] Updates to PEP 471, the os.scandir() proposal
Ethan Furman
ethan at stoneleaf.us
Fri Jul 11 05:26:05 CEST 2014
On 07/09/2014 09:02 PM, Nick Coghlan wrote:
> On 9 Jul 2014 17:14, "Ethan Furman" wrote:
>>
>> I like the 'onerror' API better primarily because it gives a single
>> point to deal with the errors. [...]
>
> The "onerror" approach can also deal with readdir failing, which the
> PEP currently glosses over.
Do we want this, though? I can see an error handler for individual entries, but if one of the *dir commands fails that
would seem to be fairly catastrophic.
> I'm somewhat inclined towards the current approach in the PEP, but I'd like to see an explanation of two aspects:
>
> 1. How a scandir variant with an 'onerror' option could be implemented given the version in the PEP
Here's a stab at it:
def scandir_error(path, info=None, onerror=None):
for entry in scandir(path):
if info == 'type':
try:
entry.is_dir()
except OSError as exc:
if onerror is None:
raise
if not onerror(exc, entry):
continue
elif info == 'lstat':
try:
entry.lstat()
except OSError as exc:
if onerror is None:
raise
if not onerror(exc, entry):
continue
yield entry
Here it is again with an attempt to deal with opendir/readdir/closedir exceptions:
def scandir_error(path, info=None, onerror=None):
entries = scandir(path)
try:
entry = next(entries)
except StopIteration:
# pass it through
raise
except Exception as exc:
if onerror is None:
raise
if not onerror(exc, 'what else here?'):
# what do we do on False?
# what do we do on True?
else:
for entry in scandir(path):
if info == 'type':
try:
entry.is_dir()
except OSError as exc:
if onerror is None:
raise
if not onerror(exc, entry):
continue
elif info == 'lstat':
try:
entry.lstat()
except OSError as exc:
if onerror is None:
raise
if not onerror(exc, entry):
continue
yield entry
> 2. How the existing scandir module handles the 'onerror' parameter to its directory walking function
Here's the first third of it from the repo:
def walk(top, topdown=True, onerror=None, followlinks=False):
"""Like os.walk(), but faster, as it uses scandir() internally."""
# Determine which are files and which are directories
dirs = []
nondirs = []
try:
for entry in scandir(top):
if entry.is_dir():
dirs.append(entry)
else:
nondirs.append(entry)
except OSError as error:
if onerror is not None:
onerror(error)
return
...
--
~Ethan~
More information about the Python-Dev
mailing list