Why exception from os.path.exists()?

Chris Angelico rosuav at gmail.com
Fri Jun 1 18:50:38 EDT 2018


On Sat, Jun 2, 2018 at 8:10 AM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> But it *isn't* the wrong type. It is the same type:
>
>
> py> type("abc") is type("a\0c")
> True
>
>
> So TypeError is out, since the type is right, only the value is wrong.

I agree with you so far. This parallels the fact that math.asin(5)
doesn't raise TypeError, since an integer is perfectly valid input to
the arcsine function.

> But ValueError is wrong too:
>
> What does os.path.exists return when given "the wrong value" (i.e. a
> string that doesn't match an existing path)? It returns False, not raise
> an exception.

Hang on, how is "a string that doesn't match an existing path" the
wrong value? The point is to ask if a path exists. A path that doesn't
exist is still valid. There are four possibilities:

1) You're asking a question that doesn't even make sense, like
os.path.exists(Ellipsis)

2) You're asking about a path that exists and you can prove that it
does. Return True.

3) You're asking about a path that doesn't exist and you can prove
that it doesn't. Return False.

4) You're asking about a path that you can't be sure about - maybe
there's a permissions error.

With perms errors, it's less clear what's the right thing to do. I
think letting an OSError bubble up would be appropriate here, but
others may disagree. Similarly if you try to access a network mount
that is currently disconnected, a device that has crashed, etc.
Returning False (as in the current implementation) is plausible; I
don't think it's the ideal, but since it would break backward
compatibility to change it now, I'm not advocating making that change.

The real question is whether os.path.exists("a\0c") is more akin to
os.path.exists(Ellipsis) or to os.path.exists("/mnt/broken/spam"). It
is never going to be valid to ask whether Ellipsis exists, and it is
never going to be valid to ask whether a\0c exists. The broken mount
might potentially become valid, and the same path name could change in
meaning if you are chrooted, so it is a sane question to ask.

My ideal preference would be for True to mean "we know for certain
that this exists" and False "we know for certain that this doesn't
exist" (which might be because one of its parent components doesn't
exist - if /spam doesn't exist, then /spam/ham doesn't either, and
that's just straight False). Everything else should raise an
exception. That said, though, I'm not hugely fussed and don't have
actual use-cases here, beyond the back-of-the-mind feeling that saying
"no that doesn't exist" is deceptively confident about something that
isn't actually certain.

ChrisA



More information about the Python-list mailing list