-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
gh-122353: Handle ValueError during imports
#122389
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
picnixz
wants to merge
22
commits into
python:main
Choose a base branch
from
picnixz:handle-valueerror-on-imports
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+90
−38
Draft
Changes from 3 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
d4336d8
handle ValueError
picnixz a7e34ca
add tests
picnixz a14a08a
blurb
picnixz b4619f0
relax guards
picnixz 16c22b9
use a (safe) bare except
picnixz 9aa048d
remove file extension in test
picnixz b554b2c
update docs
picnixz f0fb424
keep the correct guard!
picnixz 622d3a1
simplify docs
picnixz b2b1190
simplify
picnixz ef21e28
fixup! comment
picnixz aa99397
fixup! even better
picnixz b039c62
use imperative style
picnixz 3a27cb0
narrow exceptions guards in `SourceFileLoader.set_data`
picnixz 06cf720
Merge branch 'main' into handle-valueerror-on-imports
picnixz f2b269a
guard against permissions and EROFS errors
picnixz 482a716
Merge branch 'handle-valueerror-on-imports' of github.com:picnixz/cpy…
picnixz cbce6d3
guard against permissions and EROFS errors
picnixz 24c95a5
fixup indentation
picnixz e9283f5
Merge branch 'main' into handle-valueerror-on-imports
picnixz 1825481
Merge branch 'main' into handle-valueerror-on-imports
picnixz 65c576b
Merge branch 'main' into handle-valueerror-on-imports
brettcannon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -148,6 +148,7 @@ def _path_stat(path): | |
| Made a separate function to make it easier to override in experiments | ||
| (e.g. cache stat results). | ||
|
|
||
| This function may raise OSError or ValueError. | ||
| """ | ||
| return _os.stat(path) | ||
|
|
||
|
|
@@ -156,7 +157,7 @@ def _path_is_mode_type(path, mode): | |
| """Test whether the path is the specified mode type.""" | ||
| try: | ||
| stat_info = _path_stat(path) | ||
| except OSError: | ||
| except (OSError, ValueError): | ||
| return False | ||
| return (stat_info.st_mode & 0o170000) == mode | ||
|
|
||
|
|
@@ -211,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: | ||
| except (OSError, ValueError): | ||
| try: | ||
| _os.unlink(path_tmp) | ||
| except OSError: | ||
| except (OSError, ValueError): | ||
picnixz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| pass | ||
| raise | ||
|
|
||
|
|
@@ -654,7 +655,7 @@ def _calc_mode(path): | |
| """Calculate the mode permissions for a bytecode file.""" | ||
| try: | ||
| mode = _path_stat(path).st_mode | ||
| except OSError: | ||
| except (OSError, ValueError): | ||
| mode = 0o666 | ||
| # We always ensure write access so we can update cached files | ||
| # later even when the source files are read-only on Windows (#6074) | ||
|
|
@@ -990,7 +991,7 @@ def find_spec(cls, fullname, path=None, target=None): | |
| return None | ||
| try: | ||
| _path_stat(filepath) | ||
| except OSError: | ||
| except (OSError, ValueError): | ||
| return None | ||
| for loader, suffixes in _get_supported_file_loaders(): | ||
| if filepath.endswith(tuple(suffixes)): | ||
|
|
@@ -1036,7 +1037,7 @@ def path_mtime(self, path): | |
| """Optional method that returns the modification time (an int) for the | ||
| specified path (a str). | ||
|
|
||
| Raises OSError when the path cannot be handled. | ||
| Raises OSError or ValueError when the path cannot be handled. | ||
| """ | ||
| raise OSError | ||
|
|
||
|
|
@@ -1050,7 +1051,7 @@ def path_stats(self, path): | |
| - 'size' (optional) is the size in bytes of the source code. | ||
|
|
||
| Implementing this method allows the loader to read bytecode files. | ||
| Raises OSError when the path cannot be handled. | ||
| Raises OSError or ValueError when the path cannot be handled. | ||
| """ | ||
| return {'mtime': self.path_mtime(path)} | ||
|
|
||
|
|
@@ -1076,7 +1077,7 @@ def get_source(self, fullname): | |
| path = self.get_filename(fullname) | ||
| try: | ||
| source_bytes = self.get_data(path) | ||
| except OSError as exc: | ||
| except (OSError, ValueError) as exc: | ||
picnixz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| raise ImportError('source not available through get_data()', | ||
| name=fullname) from exc | ||
| return decode_source(source_bytes) | ||
|
|
@@ -1109,13 +1110,13 @@ def get_code(self, fullname): | |
| else: | ||
| try: | ||
| st = self.path_stats(source_path) | ||
| except OSError: | ||
| except (OSError, ValueError): | ||
| pass | ||
| else: | ||
| source_mtime = int(st['mtime']) | ||
| try: | ||
| data = self.get_data(bytecode_path) | ||
| except OSError: | ||
| except (OSError, ValueError): | ||
| pass | ||
| else: | ||
| exc_details = { | ||
|
|
@@ -1211,7 +1212,10 @@ def get_filename(self, fullname): | |
| return self.path | ||
|
|
||
| def get_data(self, path): | ||
| """Return the data from path as raw bytes.""" | ||
| """Return the data from path as raw bytes. | ||
|
|
||
| This may raise an OSError or a ValueError if the path is invalid. | ||
picnixz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """ | ||
| if isinstance(self, (SourceLoader, ExtensionFileLoader)): | ||
| with _io.open_code(str(path)) as file: | ||
| return file.read() | ||
|
|
@@ -1255,19 +1259,20 @@ def set_data(self, path, data, *, _mode=0o666): | |
| except FileExistsError: | ||
| # Probably another Python process already created the dir. | ||
| continue | ||
| except OSError as exc: | ||
| # Could be a permission error, read-only filesystem: just forget | ||
| # about writing the data. | ||
| except (OSError, ValueError) as exc: | ||
|
||
| # Could be a permission error, read-only filesystem, or | ||
| # an invalid path name: just forget about writing the data. | ||
| _bootstrap._verbose_message('could not create {!r}: {!r}', | ||
| parent, exc) | ||
| return | ||
| try: | ||
| _write_atomic(path, data, _mode) | ||
| _bootstrap._verbose_message('created {!r}', path) | ||
| except OSError as exc: | ||
| except (OSError, ValueError) as exc: | ||
|
||
| # Same as above: just don't write the bytecode. | ||
| _bootstrap._verbose_message('could not create {!r}: {!r}', path, | ||
| exc) | ||
| else: | ||
| _bootstrap._verbose_message('created {!r}', path) | ||
|
|
||
|
|
||
| class SourcelessFileLoader(FileLoader, _LoaderBasics): | ||
|
|
@@ -1631,6 +1636,9 @@ def find_spec(self, fullname, target=None): | |
| mtime = _path_stat(self.path or _os.getcwd()).st_mtime | ||
| except OSError: | ||
| mtime = -1 | ||
| except ValueError: | ||
| # Invalid paths will never be usable even if mtime = -1. | ||
| return None | ||
| if mtime != self._path_mtime: | ||
| self._fill_cache() | ||
| self._path_mtime = mtime | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
Misc/NEWS.d/next/Library/2024-07-29-11-21-39.gh-issue-122353.ESrsyI.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Handle :exc:`ValueError`\s raised by OS-related functions during import if | ||
| ``sys.path`` contains invalid path names. Patch by Bénédikt Tran. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.