[New-bugs-announce] [issue34541] pathlib.Path.iterdir doesn't throw an exception until you start iterating
Paul Pinterits
report at bugs.python.org
Wed Aug 29 04:20:21 EDT 2018
New submission from Paul Pinterits <rawing7 at gmail.com>:
The fact that `Path.iterdir()` only throws exceptions once you start iterating over it makes it very difficult to write correct code.
Let's look at an example: We'll iterate over all children of a directory and print their file size.
If we try to do it like this, the `try...except` has no effect whatsoever:
try:
children = path_that_doesnt_exist.iterdir()
except FileNotFoundError:
print("directory doesn't exist")
for path in children:
print(path.stat().st_size)
If we explicitly check whether the path exists (and is a directory), we end up with a race condition:
if path_that_doesnt_exist.is_dir():
print("directory doesn't exist")
else:
for path in children:
print(path.stat().st_size)
We can wrap the whole loop in a `try...except`, but then we might end up catching exceptions we didn't intend to catch. (For example, the exception that's thrown when we try to get the size of a broken symlink.)
try:
for path in path_that_doesnt_exist.iterdir():
print(path.stat().st_size) # this can also throw FileNotFoundError
except FileNotFoundError:
print("directory doesn't exist")
We can manually call `next` on the iterator inside of a `try..except` block, but that's awfully verbose and requires knowledge about iterators and the `next` function:
children = iter(path_that_doesnt_exist.iterdir())
while True:
try:
path = next(children)
except FileNotFoundError:
print("directory doesn't exist")
break
print(path.stat().st_size)
Or we can turn the iterator into a list inside of a `try...except`, which seems to be the best option, but completely defeats the point of having an iterator:
try:
children = list(path_that_doesnt_exist.iterdir())
except FileNotFoundError:
print("directory doesn't exist")
else:
for path in children:
print(path.stat().st_size)
As you can see, writing correct (and good) code with `iterdir` is more difficult than it has any right to be. Please change this behavior so that exceptions are thrown immediately when `iterdir` is called.
----------
components: Library (Lib)
messages: 324307
nosy: Paul Pinterits
priority: normal
severity: normal
status: open
title: pathlib.Path.iterdir doesn't throw an exception until you start iterating
type: behavior
versions: Python 3.4, Python 3.5, Python 3.6, Python 3.7
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue34541>
_______________________________________
More information about the New-bugs-announce
mailing list