You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
os.path.realpath raises a ValueError when path contains a null byte #117596
I do not think there is a bug. Functions like os.path.exists() answer the question "is there a node (of the specified type) with such path?" Since the valid path cannot contain the null character, the answer is "no". You get the same answer for a path containing non-encodable characters. os.path.realpath() answers the different question -- "what is the real path of the specified node?"
os.path.realpath() ignores some OSError in non-strict mode. This allows it to process paths to non-existent nodes. These errors can be fixed by making a change to the file system. But no matter what you do with the file system, an invalid path (a path containing the null characters or non-encodable characters) will remain invalid.
I guess my selection of examples was not very good. os.path.basename, os.path.dirname, os.fspath, os.path.abspath, os.path.relpath ... (list is not complete) also do not raise a ValueError when given a path with a null byte.
All the methods do not raise a ValueError when given a path with a null byte, they just accept it as part of the path.
I would except consistency across all path operations, but I found only os.path.realpath with another behaviour. So I assumed this is the one with the bug.
os.path.dirname and os.path.relpath do not work with filesystem. They could check for the null character etc, but nobody is interesting in making them intentionally slower. In functions which interact with OS, it happens as the part of conversion to OS-specific representation.
exists and is* functions should return False if the path contains NUL
functions that deal with the OS should raise ValueError (before handing the path to an OS call)
functions that manipulate the path should either raise ValueError (if they can detect it easily), or treat NUL as a normal character (the same way as an invalid character like | is handled in ntpath.dirname)
But, it looks like that's not what we do on Windows.
I added some tests for realpath() with invalid paths in PR #134147. Then I decided that this issue was a better fit and separated the tests into a separate PR #134189. And added more tests.
Now, whatever we decide, there are already tests that will show changes in behavior.
The rest cases failed by ValueError instead of FileNotFoundError as above log shows.
Further verification:
>>> import os
>>> os.lstat(b'/\xff')
Traceback (most recent call last):
File "<python-input-3>", line 1, in <module>
os.lstat(b'/\xff')
~~~~~~~~^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: b'/\xff'
>>> os.lstat('/nonexistent/x\x00')
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
os.lstat('/nonexistent/x\x00')
~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
ValueError: lstat: embedded null character in path
>>> os.lstat(b'/nonexistent/\xff')
Traceback (most recent call last):
File "<python-input-4>", line 1, in <module>
os.lstat(b'/nonexistent/\xff')
~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 13] Permission denied: b'/nonexistent/\xff'
When I tried on some random online IDE (e.g. https://www.online-python.com/) and macOS, I do see the behavior changed, b'/\xff' and '/nonexistent/x\x00' get the same outcome as above, but b'/nonexistent/\xff' gets the expected FileNotFoundError.
I sent a very customized PR that handles the specific exception my environment raises.
Activity
stefanhoelzl commentedon Apr 7, 2024
I already created a PR #117573 for this issue
serhiy-storchaka commentedon Apr 7, 2024
I do not think there is a bug. Functions like
os.path.exists()answer the question "is there a node (of the specified type) with such path?" Since the valid path cannot contain the null character, the answer is "no". You get the same answer for a path containing non-encodable characters.os.path.realpath()answers the different question -- "what is the real path of the specified node?"os.path.realpath()ignores some OSError in non-strict mode. This allows it to process paths to non-existent nodes. These errors can be fixed by making a change to the file system. But no matter what you do with the file system, an invalid path (a path containing the null characters or non-encodable characters) will remain invalid.stefanhoelzl commentedon Apr 7, 2024
In case of
os.path.existsI can agree.I guess my selection of examples was not very good.
os.path.basename,os.path.dirname,os.fspath,os.path.abspath,os.path.relpath... (list is not complete) also do not raise aValueErrorwhen given a path with a null byte.All the methods do not raise a
ValueErrorwhen given a path with a null byte, they just accept it as part of the path.I would except consistency across all path operations, but I found only
os.path.realpathwith another behaviour. So I assumed this is the one with the bug.serhiy-storchaka commentedon Apr 7, 2024
os.path.dirnameandos.path.relpathdo not work with filesystem. They could check for the null character etc, but nobody is interesting in making them intentionally slower. In functions which interact with OS, it happens as the part of conversion to OS-specific representation.encukou commentedon Apr 8, 2024
Serhiy's model sounds good to me. To summarize:
ValueError(before handing the path to an OS call)ValueError(if they can detect it easily), or treat NUL as a normal character (the same way as an invalid character like|is handled inntpath.dirname)But, it looks like that's not what we do on Windows.
pythongh-117596: Add more tests for os.path with invalid paths
serhiy-storchaka commentedon May 18, 2025
I added some tests for
realpath()with invalid paths in PR #134147. Then I decided that this issue was a better fit and separated the tests into a separate PR #134189. And added more tests.Now, whatever we decide, there are already tests that will show changes in behavior.
gh-117596: Add more tests for os.path with invalid paths (GH-134189)
pythongh-117596: Add more tests for os.path with invalid paths (pytho…
pythongh-117596: Add more tests for os.path with invalid paths (pytho…
[3.13] gh-117596: Add more tests for os.path with invalid paths (GH-1…
[3.14] gh-117596: Add more tests for os.path with invalid paths (GH-1…
pythongh-117596: Add more tests for os.path with invalid paths (pytho…
pythongh-117596: Add more tests for os.path with invalid paths (pytho…
gkirchou commentedon Dec 8, 2025
I am hitting a similar issue related this one in my linux.
In Lib/test/test_posixpath.py, most tests with
FileNotFoundErrorhits something like this:Those seems all related to
st_mode = lstat(newpath).st_modein posixpath.py#L460.FileNotFoundErrorcorrectly.PermissionErrordifferently.ValueErrorinstead ofFileNotFoundErroras above log shows.Further verification:
When I tried on some random online IDE (e.g. https://www.online-python.com/) and macOS, I do see the behavior changed,
b'/\xff'and'/nonexistent/x\x00'get the same outcome as above, butb'/nonexistent/\xff'gets the expectedFileNotFoundError.I sent a very customized PR that handles the specific exception my environment raises.
Merge branch 'main' into pythongh-117596
serhiy-storchaka commentedon Dec 8, 2025
Do you have directory
/nonexistent?gkirchou commentedon Dec 9, 2025
[Updated] I somehow found my machine has the folder /nonexistent...
Let me address this in the PR. (I removed PermissionError for L604 and L605, the rest changes are kept.)
Merge branch 'main' into pythongh-117596
serhiy-storchaka commentedon Jun 4, 2026
I suggest to close this issue as "not a bug".