[Python-Dev] os.access versus os.exist

Robert Brewer fumanchu at amor.org
Mon Nov 15 21:02:28 CET 2004


It would be awfully nice (on posix platforms, for my use-case) to find
out whether a file is inaccessible due to permission restrictions, or
due to non-existence.

Poking around in posixmodule.c, it seems os.access() uses
posix_access(PyObject *self, PyObject *args), which calls
_access/_waccess as described here:
http://msdn.microsoft.com/library/en-us/vclib/html/_crt__access.2c_._wac
cess.asp


Run-Time Library Reference 	 
_access, _waccess

Determine file-access permission.

int _access( 
   const char *path, 
   int mode 
);
int _waccess( 
   const wchar_t *path, 
   int mode 
);

Parameters

path
    File or directory path.
mode
    Permission setting.

Return Value

Each function returns 0 if the file has the given mode. The function
returns -1 if the named file does not exist or is not accessible in the
given mode; in this case, errno is set as follows:

EACCES
    Access denied: file's permission setting does not allow specified
access.
ENOENT
    Filename or path not found.

-----------------

Here's the current posixmodule.posix_access (rev 2.329):

static PyObject *
posix_access(PyObject *self, PyObject *args)
{
	char *path;
	int mode;
	int res;

#ifdef Py_WIN_WIDE_FILENAMES
	if (unicode_file_names()) {
		PyUnicodeObject *po;
		if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
			Py_BEGIN_ALLOW_THREADS
			/* PyUnicode_AS_UNICODE OK without thread lock
as
			   it is a simple dereference. */
			res = _waccess(PyUnicode_AS_UNICODE(po), mode);
			Py_END_ALLOW_THREADS
			return(PyBool_FromLong(res == 0));
		}
		/* Drop the argument parsing error as narrow strings
		   are also valid. */
		PyErr_Clear();
	}
#endif
	if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
		return NULL;
	Py_BEGIN_ALLOW_THREADS
	res = access(path, mode);
	Py_END_ALLOW_THREADS
	return(PyBool_FromLong(res == 0));
}

-----------------

It seems to me that, if EACCES and ENOENT were made available (in a
future version of Python), I could solve my problem easily. One way
would be to raise OSError within os.access if the result of _waccess ==
ENOENT, but this would cause problems with old code which depends upon
the old behavior. Can we add an optional "error_if_not_found" arg to
os.access? Return the result of _waccess instead of True/False? Make a
new os function with the desired behavior?

The next issue, then, is other platforms: is similar functionality
available in OS/2, unix, etc.?

Finally, if anyone has any immediate workarounds for me ;) answer in
private or on c.l.p.


Robert Brewer
MIS
Amor Ministries
fumanchu at amor.org


More information about the Python-Dev mailing list