Issue 738617: On Windows, os.listdir() throws incorrect exception (original) (raw)

Created on 2003-05-16 03:11 by mikethompson, last changed 2022-04-10 16:08 by admin. This issue is now closed.

Messages (4)

msg16036 - (view)

Author: Mike Thompson (mikethompson)

Date: 2003-05-16 03:11

ActivePython 2.2.2 Build 224 (ActiveState Corp.) based on Python 2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.

import os os.listdir('c:\IMPOSSIBLE') Traceback (most recent call last): File "", line 2, in ? WindowsError: [Errno 3] The system cannot find the path specified: 'c:\IMPOSSIBLE/.'

This is the wrong exception I would have thought.

AIUI, WindowsError is thrown for uniquely Windows types of problems. Path not found is not unique to Windows.

I would have expected an os.error exception to have been thrown together with an code of errno.ENOENT.
This is what happens if I try to open() a non existent file.

(Caution: I'm a python newbie and I could easily have missed something here -- If so sorry to waste your time)

The deadly part about this bug is that WindowsError subclasses os.error, just the code changes (3 instead of 2). So my "except os.error" worked to catch the exception ... just the error code seemed wrong. Took be ages to figure it all out.

msg16037 - (view)

Author: Jeff Epler (jepler)

Date: 2003-05-19 01:33

Logged In: YES user_id=2772

Python faithfully relays to you the information returned by the OS in these cases. I don't think it's planned for Python to try to rationalize the various errno/GetLastError() values based on what it thinks the actual error must have been.

msg16038 - (view)

Author: Mike Thompson (mikethompson)

Date: 2003-05-19 01:53

Logged In: YES user_id=630223

Yet, if I try to open() a non existent file, this mapping to a generic Python exception DOES occur (exception is os.error, code is errno.ENOENT)

And just as well it does too because otherwise cross-platform coding would be difficult.

Now, if its good enough for open(), why not for os.listdir()?

From the documentation, I got the impression that WindowError gets used for Windows specific problems for which generic cross-platform handling makes no sense, which is why WindowsError simply wraps errno/GetLastError () and sub-classes the standard exception.

msg16039 - (view)

Author: Tim Peters (tim.peters) * (Python committer)

Date: 2003-05-19 04:21

Logged In: YES user_id=31435

WindowsError gets raised when the implementation uses a native Win32 API function instead of a standard C library function: no native Win32 API function sets errno, and the error code we get is gotten from the Win32 GetLastError() function instead.. os.listdir() on Windows uses the Win32
FindFirstFile()/FindNextFile() API. That doesn't set errno.
When a path can't be found by FindFisrtFile(), GetLastError () returns 3, which is the Windows ERROR_PATH_NOT_FOUND. That's what we tell you.

On Unix systems, the POSIX opendir()/readdir()/closedir() API is used. That does set errno, and we return whatever errno it sets there.

On OS2, we use its DosFindFirst()/DosFindNext() API.

Etc. The reason this isn't uniform is that standard C doesn't define a way to list a directory, so how to get it done necessarily varies across platforms. In platform- specific code, we generally strive to give platform-natural error codes. open() is different because standard C defines what open() does, so it can be done the same way across platfroms.

There isn't "a bug" here, so I'm closing this. If you want to open a feature request asking that error codes be made uniform across all platforms, you can do so, but I'll tell you it's unlikely to happen -- there are cases where no cross- platform standard exists, and, e.g., to a Win32 programmer it wouldn't make sense for listdir() to return a POSIX errno code. It's not impossble for Python to make it do so anyway, but Python chose a different way at the start and changing now would break backward compatibility. A change here would therefore require a PEP too.