mirror of
https://github.com/python/cpython.git
synced 2026-01-06 07:22:09 +00:00
[3.11] gh-96005: Handle WASI ENOTCAPABLE in getpath (GH-96006) (GH-96034) (GH-96038)
- On WASI `ENOTCAPABLE` is now mapped to `PermissionError`. - The `errno` modules exposes the new error number. - `getpath.py` now ignores `PermissionError` when it cannot open landmark files `pybuilddir.txt` and `pyenv.cfg`.
This commit is contained in:
parent
c4cf745c72
commit
bc337a7766
7 changed files with 35 additions and 6 deletions
|
|
@ -657,3 +657,12 @@ defined by the module. The specific list of defined symbols is available as
|
|||
Interface output queue is full
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. data:: ENOTCAPABLE
|
||||
|
||||
Capabilities insufficient. This error is mapped to the exception
|
||||
:exc:`PermissionError`.
|
||||
|
||||
.. availability:: WASI, FreeBSD
|
||||
|
||||
.. versionadded:: 3.11.1
|
||||
|
|
|
|||
|
|
@ -746,7 +746,12 @@ depending on the system error code.
|
|||
|
||||
Raised when trying to run an operation without the adequate access
|
||||
rights - for example filesystem permissions.
|
||||
Corresponds to :c:data:`errno` :py:data:`~errno.EACCES` and :py:data:`~errno.EPERM`.
|
||||
Corresponds to :c:data:`errno` :py:data:`~errno.EACCES`,
|
||||
:py:data:`~errno.EPERM`, and :py:data:`~errno.ENOTCAPABLE`.
|
||||
|
||||
.. versionchanged:: 3.11.1
|
||||
WASI's :py:data:`~errno.ENOTCAPABLE` is now mapped to
|
||||
:exc:`PermissionError`.
|
||||
|
||||
.. exception:: ProcessLookupError
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ def test_select_error(self):
|
|||
+-- InterruptedError EINTR
|
||||
+-- IsADirectoryError EISDIR
|
||||
+-- NotADirectoryError ENOTDIR
|
||||
+-- PermissionError EACCES, EPERM
|
||||
+-- PermissionError EACCES, EPERM, ENOTCAPABLE
|
||||
+-- ProcessLookupError ESRCH
|
||||
+-- TimeoutError ETIMEDOUT
|
||||
"""
|
||||
|
|
@ -75,6 +75,8 @@ def _make_map(s):
|
|||
continue
|
||||
excname, _, errnames = line.partition(' ')
|
||||
for errname in filter(None, errnames.strip().split(', ')):
|
||||
if errname == "ENOTCAPABLE" and not hasattr(errno, errname):
|
||||
continue
|
||||
_map[getattr(errno, errname)] = getattr(builtins, excname)
|
||||
return _map
|
||||
_map = _make_map(_pep_map)
|
||||
|
|
@ -91,7 +93,7 @@ def test_errno_mapping(self):
|
|||
othercodes = set(errno.errorcode) - set(self._map)
|
||||
for errcode in othercodes:
|
||||
e = OSError(errcode, "Some message")
|
||||
self.assertIs(type(e), OSError)
|
||||
self.assertIs(type(e), OSError, repr(e))
|
||||
|
||||
def test_try_except(self):
|
||||
filename = "some_hopefully_non_existing_file"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
On WASI :data:`~errno.ENOTCAPABLE` is now mapped to :exc:`PermissionError`.
|
||||
The :mod:`errno` modules exposes the new error number. ``getpath.py`` now
|
||||
ignores :exc:`PermissionError` when it cannot open landmark files
|
||||
``pybuilddir.txt`` and ``pyenv.cfg``.
|
||||
|
|
@ -927,6 +927,10 @@ errno_exec(PyObject *module)
|
|||
#ifdef EQFULL
|
||||
add_errcode("EQFULL", EQFULL, "Interface output queue is full");
|
||||
#endif
|
||||
#ifdef ENOTCAPABLE
|
||||
// WASI extension
|
||||
add_errcode("ENOTCAPABLE", ENOTCAPABLE, "Capabilities insufficient");
|
||||
#endif
|
||||
|
||||
Py_DECREF(error_dict);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -351,11 +351,11 @@ def search_up(prefix, *landmarks, test=isfile):
|
|||
try:
|
||||
# Read pyvenv.cfg from one level above executable
|
||||
pyvenvcfg = readlines(joinpath(venv_prefix, VENV_LANDMARK))
|
||||
except FileNotFoundError:
|
||||
except (FileNotFoundError, PermissionError):
|
||||
# Try the same directory as executable
|
||||
pyvenvcfg = readlines(joinpath(venv_prefix2, VENV_LANDMARK))
|
||||
venv_prefix = venv_prefix2
|
||||
except FileNotFoundError:
|
||||
except (FileNotFoundError, PermissionError):
|
||||
venv_prefix = None
|
||||
pyvenvcfg = []
|
||||
|
||||
|
|
@ -475,7 +475,7 @@ def search_up(prefix, *landmarks, test=isfile):
|
|||
# File exists but is empty
|
||||
platstdlib_dir = real_executable_dir
|
||||
build_prefix = joinpath(real_executable_dir, VPATH)
|
||||
except FileNotFoundError:
|
||||
except (FileNotFoundError, PermissionError):
|
||||
if isfile(joinpath(real_executable_dir, BUILD_LANDMARK)):
|
||||
build_prefix = joinpath(real_executable_dir, VPATH)
|
||||
if os_name == 'nt':
|
||||
|
|
|
|||
|
|
@ -3644,6 +3644,11 @@ _PyExc_InitState(PyInterpreterState *interp)
|
|||
ADD_ERRNO(InterruptedError, EINTR);
|
||||
ADD_ERRNO(PermissionError, EACCES);
|
||||
ADD_ERRNO(PermissionError, EPERM);
|
||||
#ifdef ENOTCAPABLE
|
||||
// Extension for WASI capability-based security. Process lacks
|
||||
// capability to access a resource.
|
||||
ADD_ERRNO(PermissionError, ENOTCAPABLE);
|
||||
#endif
|
||||
ADD_ERRNO(ProcessLookupError, ESRCH);
|
||||
ADD_ERRNO(TimeoutError, ETIMEDOUT);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue