Why exception from os.path.exists()?

Rick Johnson rantingrickjohnson at gmail.com
Sun Jun 10 13:56:07 EDT 2018


Marko Rauhamaa wrote:
> Chris Angelico <rosuav at gmail.com>:
> 
> > Marko Rauhamaa <marko at pacujo.net> wrote:
> >>
> >> This surprising exception can even be a security issue:
> >>
> >>    >>> os.path.exists("\0")
> >>    Traceback (most recent call last):
> >>      File "<stdin>", line 1, in <module>
> >>      File "/usr/lib64/python3.6/genericpath.py", line 19, in exists
> >>        os.stat(path)
> >>    ValueError: embedded null byte
> >
> > [...]
> >
> > A Unix path name cannot contain a null byte, so what you
> > have is a fundamentally invalid name. ValueError is
> > perfectly acceptable.
> 
> At the very least, that should be emphasized in the
> documentation. The pathname may come from an external
> source. It is routine to check for "/", "." and ".." but
> most developers (!?) would not think of checking for "\0".
> That means few test suites would catch this issue and few
> developers would think of catching ValueError here. The end
> result is unpredictable.

I'd have to agree with this assessment. Either a filepath
exists, or it doesn't. Therefore, in the "worldview" of
os.path.exist, there should be no consideration of
conformity, as it is blatantly obvious that any malformed
path would _not_ and could _not_ possibly, exist. In fact,
the only case in which the method in question should raise
an Exception is when a non-stringy argument is passed. Which
-- at least in 2.x version -- i can confirm (with limited
testing) it does this correctly!

    ## PYTHON 2.X SESSION ##
    py> os.path.exists('')
    False
    py> os.path.exists(None)
    Traceback (most recent call last):
      File "<pyshell#5>", line 1, in <module>
        os.path.exists(None)
      File "C:\Python27\lib\genericpath.py", line 26, in exists
        os.stat(path)
    TypeError: coercing to Unicode: need string or buffer, NoneType found
    >>> os.path.exists(1)
    Traceback (most recent call last):
      File "<pyshell#6>", line 1, in <module>
        os.path.exists(1)
      File "C:\Python27\lib\genericpath.py", line 26, in exists
        os.stat(path)
    TypeError: coercing to Unicode: need string or buffer, int found

But if the argument is a string, either it exists as a
filepath or it doesn't. Case closed. Anything less would
constitute type discrimination. Which is not only
inconsistent, it's unethical.



More information about the Python-list mailing list