Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions Doc/library/importlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -416,12 +416,16 @@ ABC hierarchy::
Loaders that have a file-like storage back-end
that allows storing arbitrary data
can implement this abstract method to give direct access
to the data stored. :exc:`OSError` is to be raised if the *path* cannot
be found. The *path* is expected to be constructed using a module's
:attr:`__file__` attribute or an item from a package's :attr:`__path__`.
to the data stored.

An :exc:`OSError` is to be raised if the *path* cannot be found, and
a :exc:`ValueError` is raised if the *path* cannot be handled (e.g.,
the *path* contains null characters or the *path* is too long). The
*path* is expected to be constructed using a module's :attr:`__file__`
attribute or an item from a package's :attr:`__path__`.

.. versionchanged:: 3.4
Raises :exc:`OSError` instead of :exc:`NotImplementedError`.
Raise :exc:`OSError` by default instead of :exc:`NotImplementedError`.


.. class:: InspectLoader
Expand Down Expand Up @@ -551,6 +555,9 @@ ABC hierarchy::

Reads *path* as a binary file and returns the bytes from it.

An :exc:`OSError` is to be raised if the *path* cannot be found, and
a :exc:`ValueError` is raised if the *path* is invalid (e.g., *path*
contains null characters or is too long).

.. class:: SourceLoader

Expand Down Expand Up @@ -582,12 +589,13 @@ ABC hierarchy::
- ``'size'`` (optional): the size in bytes of the source code.

Any other keys in the dictionary are ignored, to allow for future
extensions. If the path cannot be handled, :exc:`OSError` is raised.
extensions. If the path cannot be handled, raises an :exc:`OSError`
or a :exc:`ValueError` depending on the reason.

.. versionadded:: 3.3

.. versionchanged:: 3.4
Raise :exc:`OSError` instead of :exc:`NotImplementedError`.
Raise :exc:`OSError` by default instead of :exc:`NotImplementedError`.

.. method:: path_mtime(path)

Expand All @@ -597,20 +605,21 @@ ABC hierarchy::
.. deprecated:: 3.3
This method is deprecated in favour of :meth:`path_stats`. You don't
have to implement it, but it is still available for compatibility
purposes. Raise :exc:`OSError` if the path cannot be handled.
purposes. If the path cannot be handled, raises an :exc:`OSError`
or a :exc:`ValueError` depending on the reason.

.. versionchanged:: 3.4
Raise :exc:`OSError` instead of :exc:`NotImplementedError`.
Raise :exc:`OSError` by default instead of :exc:`NotImplementedError`.

.. method:: set_data(path, data)

Optional abstract method which writes the specified bytes to a file
path. Any intermediate directories which do not exist are to be created
automatically.

When writing to the path fails because the path is read-only
(:const:`errno.EACCES`/:exc:`PermissionError`), do not propagate the
exception.
When writing to the path fails by raising an :class:`OSError` (e.g.,
the path is read-only (:const:`errno.EACCES`/:exc:`PermissionError`)
or a :class:`ValueError`, the exception is not propagated.

.. versionchanged:: 3.4
No longer raises :exc:`NotImplementedError` when called.
Expand Down
6 changes: 3 additions & 3 deletions Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,10 @@ def _write_atomic(path, data, mode=0o666):
with _io.FileIO(fd, 'wb') as file:
file.write(data)
_os.replace(path_tmp, path)
except (OSError, ValueError):
except:
try:
_os.unlink(path_tmp)
except (OSError, ValueError):
except OSError:
pass
raise

Expand Down Expand Up @@ -1267,7 +1267,7 @@ def set_data(self, path, data, *, _mode=0o666):
return
try:
_write_atomic(path, data, _mode)
except (OSError, ValueError) as exc:
except OSError as exc:
# Same as above: just don't write the bytecode.
_bootstrap._verbose_message('could not create {!r}: {!r}', path,
exc)
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_importlib/import_/test_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def test_invalid_names_in_sys_path(self):
(f'Top{os.sep}Mid\x00', 'path with embedded NUL bytes'),
# A filename with surrogate codes. A UnicodeEncodeError is raised
# by os.stat() upon querying, which is a subclass of ValueError.
("\uD834\uDD1E.py", 'surrogate codes (MUSICAL SYMBOL G CLEF)'),
("\uD834\uDD1E", 'surrogate codes (MUSICAL SYMBOL G CLEF)'),
# For POSIX platforms, an OSError will be raised but for Windows
# platforms, a ValueError is raised due to the path_t converter.
# See: https://github.com/python/cpython/issues/122353
Expand Down