Skip to content
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

Open() on path that exceeds 248 char limit results in "FileNotFoundError: [Errno 2] No such file or directory" #99954

Open
day22 opened this issue Dec 2, 2022 · 2 comments
Labels
OS-windows type-bug An unexpected behavior, bug, or error

Comments

@day22
Copy link

day22 commented Dec 2, 2022

Bug report

Attempting to open or appending paths to sys.path with paths that length exceed the 248 character limit results in incorrect errors. In the case of opening paths that exceeded the limit, rather than an error pointing to the path length being exceeded we see a file not found. A similar error handling issue is prevalent with appending paths that exceed the limit to sys.path. In this case when trying to access the module you will receive a module not found error. I am now aware the path limit can be disabled on installation or later but these false flags led me astray while debugging.

Reproduction Steps:

  • Create a text file whose path exceeds 248 characters
  • Attempt to read/write from that file
    or
  • Create a Python module whose path exceeds 248 characters
  • Attempt to import that module from an external directory by appending the path to sys.path

Environment

  • CPython versions tested on: 3.10.4
  • Operating system and architecture: Windows x64
@day22 day22 added the type-bug An unexpected behavior, bug, or error label Dec 2, 2022
@eryksun
Copy link
Contributor

eryksun commented Dec 2, 2022

The legacy path length limit is MAX_PATH - 1 (259) characters. When creating a directory, the legacy limit is MAX_PATH - 12 (248) characters because the system reserves space for a short filename in the directory.

The length limit with long paths enabled -- or for a "\\?\" prefixed path (backslashes only; no forward slashes) -- is about 32760 characters. The length limit for a symlink target is about 4080 characters.

In the case of opening paths that exceeded the limit, rather than an error pointing to the path length being exceeded we see a file not found.

If a path is too long, some WinAPI functions such as SetCurrentDirectoryW() set the last error to ERROR_FILENAME_EXCED_RANGE (206). Other WinAPI functions such as CreateFileW() set the last error to ERROR_PATH_NOT_FOUND (3). The error set for a missing file or directory is ERROR_FILE_NOT_FOUND (2).

The C runtime maps all of these error codes, among others, to the errno value ENOENT, for which Python raises FileNotFoundError.

For example (with support for long paths disabled):

>>> os.chdir('a'*255)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [WinError 206] The filename or extension is too long: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'

>>> os.stat('a'*255)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'

@rudradesai200
Copy link

Hi,
I would like to work on this issue. It looks like an easy one and can be taken on by a beginner.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OS-windows type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

3 participants