GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Optimize pathlib path construction · Issue #101362 · python/cpython

Optimize pathlib path construction #101362

New issue
Copy link
New issue
Copy link
Closed
Closed
Optimize pathlib path construction#101362
Copy link
Labels
performancePerformance or resource usagePerformance or resource usagetopic-pathlibtype-featureA feature request or enhancementA feature request or enhancement

Description

@barneygale
barneygale
opened on Jan 27, 2023
Issue body actions

Pathlib is slow. One of the most obvious symptoms is that pathlib.PurePath objects are slow to construct. We should be able to speed construction up without making other parts of pathlib slower.

Two possible approaches:

  1. Optimize the existing machinary of path construction: __new__(), _from_parts(), _parse_parts(), _parse_args().
  2. Perform less work in the constructor: defer parsing, joining and normalization until needed.

Linked PRs

  • GH-101362: Optimise pathlib by deferring path normalisation #101560
  • GH-101362: Check pathlib.Path flavour compatibility at import time #101664
  • GH-101362: Call join() only when >1 argument supplied to pathlib.PurePath() #101665
  • GH-101362: Optimise PurePath(PurePath(...)) #101667
  • GH-101362: Omit path anchor from pathlib.PurePath()._parts #102476
Reacted by Alex Waygood, sobolevn, Jacob Nilsson, ProgramRipper, sigma67, Gabriele N. Tornetta and tblazejczyk-qblox

Activity

Next
  1. barneygale
    added
    type-featureA feature request or enhancementA feature request or enhancement
    performancePerformance or resource usagePerformance or resource usage
    topic-pathlib
    on Jan 27, 2023
  2. barneygale commented on Jan 29, 2023

    @barneygale
    barneygale
    on Jan 29, 2023
    ContributorAuthor
    More actions

    I'd like to land #101363 before I put the first PR up for this issue.

  3. barneygale
    added 5 commits that reference this issue on Feb 4, 2023

    pythonGH-101362 - Optimise pathlib by deferring path normalisation

    b428069

    pythonGH-101362: Check pathlib.Path flavour compatibility at import time

    76dcd6d

    pythonGH-101362: Check pathlib.Path flavour compatibility at import time

    82fc553

    pythonGH-101362: Call join() only when >1 argument supplied to pathli…

    e0e9bd9

    pythonGH-101362: Optimise PurePath(PurePath(...))

    b01c352
  4. zooba commented on Feb 22, 2023

    @zooba
    zooba
    on Feb 22, 2023
    Member
    More actions

    Does the PR cope with WindowsPurePath and PosixPurePath and converting between them?

  5. barneygale commented on Feb 22, 2023

    @barneygale
    barneygale
    on Feb 22, 2023
    ContributorAuthor
    More actions

    Could you clarify? The PRs maintain the behaviour that attempting to instantiate pathlib.PurePath will give you a PureWindowsPath or a PurePosixPath depending on your platform, but pathlib doesn't support converting between Windows and POSIX paths as I understand it.

  6. zooba commented on Feb 24, 2023

    @zooba
    zooba
    on Feb 24, 2023
    Member
    More actions

    This behaviour should be preserved:

    Python 3.10.10 (tags/v3.10.10:aad5f6a, Feb  7 2023, 17:20:36) [MSC v.1929 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from pathlib import *
    >>> p = PureWindowsPath("a/b/c")
    >>> p
    PureWindowsPath('a/b/c')
    >>> PurePosixPath(p)
    PurePosixPath('a/b/c')
    >>> PurePath(p)
    PureWindowsPath('a/b/c')
    >>> PosixPath(p)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2800.0_x64__3847v3x7pw1km\lib\pathlib.py", line 962, in __new__
        raise NotImplementedError("cannot instantiate %r on your system"
    NotImplementedError: cannot instantiate 'PosixPath' on your system
    >>> WindowsPath(p)
    WindowsPath('a/b/c')
    >>>
    
    Reacted by Barney Gale
  7. barneygale commented on Feb 24, 2023

    @barneygale
    barneygale
    on Feb 24, 2023
    ContributorAuthor
    More actions

    Right! That will be broken by #101667 as things stand:

    >>> from os import fspath
    >>> from pathlib import *
    >>> p = PureWindowsPath("a/b/c")
    >>> p
    PureWindowsPath('a/b/c')
    >>> fspath(p)
    'a\\b\\c'
    >>> PurePosixPath(fspath(p))
    PurePosixPath('a\\b\\c')
    >>> PurePosixPath(p)
    PurePosixPath('a\\b\\c')

    It doesn't appear to be documented or tested behaviour, and it feels odd to me that PurePosixPath(p) can give a different result to PurePosixPath(fspath(p)). I'll try to find a good way forwards!

    Reacted by Steve Dower
  8. barneygale commented on Feb 24, 2023

    @barneygale
    barneygale
    on Feb 24, 2023
    ContributorAuthor
    More actions

    This feature doesn't really work with drives or roots:

    >>> PurePosixPath(PureWindowsPath('//server/share/dir'))
    PurePosixPath('\\\\server\\share\\/dir')
    >>> PurePosixPath(PureWindowsPath('c:/dir'))
    PurePosixPath('c:\\/dir')
    >>> PurePosixPath(PureWindowsPath('/dir'))
    PurePosixPath('\\/dir')

    As far as I can tell, no one has ever logged a bug about it.

    However, using PurePosixPath(PureWindowsPath(...).as_posix()) works everywhere:

    >>> PurePosixPath(PureWindowsPath('//server/share/dir').as_posix())
    PurePosixPath('//server/share/dir')
    >>> PurePosixPath(PureWindowsPath('c:/dir').as_posix())
    PurePosixPath('c:/dir')
    >>> PurePosixPath(PureWindowsPath('/dir').as_posix())
    PurePosixPath('/dir')

    So I'm tempted to conclude that converting with PurePosixPath(PureWindowsPath(...)) alone is not supported, and that it only happened to work in some limited circumstances. Users can add .as_posix() to signal their intent and make it work reliably. What do you reckon?

  9. zooba commented on Feb 24, 2023

    @zooba
    zooba
    on Feb 24, 2023
    Member
    More actions

    I think the direct conversion should either be consistent with fspath(p) or p.parts, but no strong preference which. As you say, neither makes a huge amount of sense, and the workaround (.as_posix()) has been there for a long time.

    Might be worth adding a short note to the docs warning that the constructor can't reliably convert from different pathlib objects, and maybe specify whether it will fspath or .parts them.

    On another perf note, is it possible that parsing the path up front isn't necessary? Obviously it'll save the most time to keep a single string literal around and parse it later, but I don't personally have a good feel for whether that's common or not. (Obviously if it's available pre-parsed then keep it.)

    Reacted by Barney Gale
  10. 7 remaining items

  11. hugovk
    added 2 commits that reference this issue on Mar 6, 2023

    pythonGH-101362: Check pathlib.Path flavour compatibility at import t…

    890f222

    pythonGH-101362: Optimise PurePath(PurePath(...)) (pythonGH-101667)

    c7c4d7a
  12. barneygale
    added a commit that references this issue on Mar 6, 2023

    pythonGH-101362: Omit path anchor from `pathlib.PurePath()._parts`

    8bf4600
  13. carljm
    added 2 commits that reference this issue on Mar 6, 2023

    Merge branch 'main' into nodeaddict

    33dda2a

    Merge branch 'main' into inlinecomp2

    ecb313c
  14. barneygale
    added a commit that references this issue on Mar 10, 2023

    Merge branch 'main' into pythongh-101362-exclude-anchor-from-parts

    ac26f84
  15. barneygale commented on Mar 22, 2023

    @barneygale
    barneygale
    on Mar 22, 2023
    ContributorAuthor
    More actions

    For anyone following along, I think this ticket can be resolved if/when this PR lands:

    • GH-101362: Omit path anchor from pathlib.PurePath()._parts #102476
  16. barneygale
    added 3 commits that reference this issue on Apr 3, 2023

    Merge branch 'main' into pythongh-101362-exclude-anchor-from-parts

    f529d51

    Merge branch 'main' into pythongh-101362-exclude-anchor-from-parts

    078ced9

    GH-101362: Omit path anchor from `pathlib.PurePath()._parts` (GH-102476)

    2c673d5
  17. barneygale commented on Apr 9, 2023

    @barneygale
    barneygale
    on Apr 9, 2023
    ContributorAuthor
    More actions

    Resolving this issue. It's now much cheaper to construct pathlib.PurePath and Path objects. Some operations like str() and joinpath() are also cheaper.

    Future work:

    • Optimize pathlib.PurePath.__fspath__() #102783
    • Path.rglob performance issues in deeply nested directories compared to glob.glob(recursive=True) #102613
    • Add C implementation of os.path.splitroot() #102511
    • Add C implementation of os.path.join()
    Reacted by Alex Waygood and skshetry
  18. barneygale
    closed this as completedon Apr 9, 2023
  19. warsaw
    added a commit that references this issue on Apr 11, 2023

    pythonGH-101362: Omit path anchor from `pathlib.PurePath()._parts` (p…

    f81083c
  20. aisk
    added a commit that references this issue on Apr 18, 2023

    pythonGH-101362: Omit path anchor from `pathlib.PurePath()._parts` (p…

    86b1904
  21. mih
    added a commit that references this issue on Nov 23, 2023

    Replace regex approach to ls-files output parsing

    3b01b01
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

    performancePerformance or resource usagePerformance or resource usagetopic-pathlibtype-featureA feature request or enhancementA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.