Skip to content

Refactor nt._path_is* & nt._path_[l]exists #118507

Description

@nineteendo

Feature or enhancement

Proposal:

Quoting @eryksun:

I agree that all of these _path_is* and _path_[l]exists helpers are a lot of code to maintain, taken together. It could be refactored into smaller inline helper functions that can be reused, which would also make the code more readable.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

Linked PRs

Activity

  1. nineteendo commented on May 6, 2024

    @nineteendo
    ContributorAuthor

    Eryk, do you have any ideas to clean them up (besides the simpler error handling)?

  2. eryksun commented on May 7, 2024

    @eryksun
  3. nineteendo commented on May 7, 2024

    @nineteendo
    ContributorAuthor

    Good start, we probably need a follow_symlinks option for _testFileTypeByName to use LSTAT() though.

  4. eryksun commented on May 7, 2024

    @eryksun
  5. eryksun commented on May 7, 2024

    @eryksun
  6. nineteendo commented on May 8, 2024

    @nineteendo
    ContributorAuthor

    Did you speed something up, because it's only 3 lines less than the old code.

  7. eryksun commented on May 8, 2024

    @eryksun
    Contributor

    My goal was to remove duplicated code and divide the work into two separate operations that can be understood and modified independently, written in a way that I think is easy to understand. This reduces the maintenance burden. I also added internal support for checking for mount points, in case we implement _path_isjunction().

    I added a GetFileType() check in the by-handle code. When combined with the diskOnly parameter, the GetFileType() check makes it safer to check an open file descriptor since the check is implemented directly in the I/O manager without trying to acquire the file lock. If GetFileInformationByHandleEx() is called on a handle for a synchronous-mode pipe, it could block indefinitely. For example, with the current implementation in 3.12:

    >>> pr, pw = os.pipe()
    >>> threading.Thread(target=os.read, args=(pr, 1)).start()
    >>> os.path.isfile(pr)
    ^C

    Also, given the system's named-pipe filesystem (NPFS) support for basic file information (anonymous pipes are also in NPFS, but they're like unlinked open files in POSIX), the GetFileType() check avoids classifying pipes as regular files. Again, with the current implementation in 3.12:

    >>> pr, pw = os.pipe()
    >>> os.path.isfile(pr)
    True
  8. nineteendo commented on May 8, 2024

    @nineteendo
    ContributorAuthor

    OK, that explains why the code isn't much shorter. I added a test for the second issue. The first one seems difficult to test.

  9. added a commit that references this issue on May 21, 2024
  10. added a commit that references this issue on May 21, 2024
  11. added a commit that references this issue on May 22, 2024
  12. added a commit that references this issue on May 22, 2024
  13. added a commit that references this issue on May 22, 2024
  14. added 3 commits that reference this issue on Jul 4, 2024
  15. added a commit that references this issue on Jul 11, 2024
  16. added 2 commits that reference this issue on Jul 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions