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 — bpo-46227: Add pathlib.Path.walk method by zmievsa · Pull Request #30340 · python/cpython

Conversation

@zmievsa

@zmievsa zmievsa commented Jan 2, 2022 •
edited by bedevere-bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

https://bugs.python.org/issue46227

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@the-knights-who-say-ni

the-knights-who-say-ni commented Jan 2, 2022

Copy link
Copy Markdown

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept this contribution by verifying everyone involved has signed the PSF contributor agreement (CLA).

CLA Missing

Our records indicate the following people have not signed the CLA:

@Ovsyanka83

For legal reasons we need all the people listed to sign the CLA before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue.

If you have recently signed the CLA, please wait at least one business day
before our records are updated.

You can check yourself to see if the CLA has been received.

Thanks again for the contribution, we look forward to reviewing it!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@the-knights-who-say-ni the-knights-who-say-ni added the CLA not signed label Jan 2, 2022
@bedevere-bot bedevere-bot added the awaiting review label Jan 2, 2022
@AlexWaygood AlexWaygood added the type-feature A feature request or enhancement label Jan 2, 2022
sobolevn
sobolevn reviewed Jan 2, 2022
View reviewed changes

@sobolevn sobolevn left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for submitting a PR!

Please, note that testing newly added code is probably a must. Adding tests will increase your chances to get this new feature accepted.

If you have any problems with CLA (which is also required), please, feel free to ping me - I will try to help you 🙂

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

AlexWaygood and zmievsa reacted with thumbs up emoji
All reactions
  • 👍 2 reactions
Comment thread Misc/NEWS.d/next/Library/2022-01-02-21-41-52.bpo-46277.NquRZl.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

@AlexWaygood

AlexWaygood commented Jan 2, 2022

Copy link
Copy Markdown
Member

+1 to what @sobolevn said — there's a great guide to writing tests here. New tests for this should probably be added to this file.

zmievsa reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@barneygale

barneygale commented Jan 3, 2022 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

I'd support adding some way to walk a directory hierarchy in pathlib.

But I'm not a huge fan of the os.walk() API, specifically the fact that it's a Generator[Tuple[str,list[str],list[str]], which is clunky if you haven't already memorized it. Pathlib usually smooths over stuff like that.

Here's a possible API for discussion, still using os.walk() under the hood:

diff --git a/Lib/pathlib.py b/Lib/pathlib.py
index f1a33178e2..23de30abc6 100644
--- a/Lib/pathlib.py
+++ b/Lib/pathlib.py
@@ -1008,15 +1008,19 @@ def samefile(self, other_path):
             other_st = self._accessor.stat(other_path)
         return os.path.samestat(st, other_st)
 
-    def iterdir(self):
+    def iterdir(self, recurse=False, dirs=True, files=True):
         """Iterate over the files in this directory.  Does not yield any
         result for the special paths '.' and '..'.
         """
-        for name in self._accessor.listdir(self):
-            if name in {'.', '..'}:
-                # Yielding a path object for these makes little sense
-                continue
-            yield self._make_child_relpath(name)
+        for root, dirnames, filenames in os.walk(self):
+            if dirs:
+                for name in dirnames:
+                    yield type(self)(root, name)
+            if files:
+                for name in filenames:
+                    yield type(self)(root, name)
+            if not recurse:
+                break
 
     def glob(self, pattern):
         """Iterate over this subtree and yield all existing files (of any
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@the-knights-who-say-ni the-knights-who-say-ni added CLA signed and removed CLA not signed labels Jan 3, 2022
@zmievsa

zmievsa commented Jan 4, 2022 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

@barneygale I agree that os.walk API seems pretty clunky. I do, however, believe that the one you're offering is basically Path.glob("**/*") or [p for p in Path.glob("**/*") if p.is_file()]. Your approach would also require us to add 6 arguments to iterdir (the ones you offered + the ones os.walk already has), some of which (like followlinks=True and recurse=False, or recurse=False and onerrors=None) contradict each other.

So I believe that we should not add walk's logic into iterdir. We could make something like iterwalk that does all the same things as os.walk with a bit of a simpler api. However, I am not sure how to simplify os.walk API without losing its core features.

There's the issue that os.walk provides you with dir-by-dir iteration by yielding root which is pretty useful in many situations while your solution does not.

Also, os.walk distinguishes between dirs and files so you don't have to and provides you with a simple way to prevent recursion into certain subtrees by removing elements from dirs list, which is pretty hard to get with any simpler APIs. I will commit the changes that add this feature into my implementation tomorrow.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@barneygale

barneygale commented Jan 4, 2022 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Thanks. I didn't know you could edit the list of directories to prevent recursion - neat!

One more thing to consider: in part for performance reasons, pathlib internally represents a path as a drive, root, and list of string parts. This avoids some costly splitting and joining on directory separators -- for example, Path.parent doesn't parse anything or create any new string objects, whereas os.path.dirname() does.

Pathlib has historically re-implemented algorithms like os.path.realpath(), os.path.expanduser() etc, and modified them to work with the (drive, root, parts) representation. The idea that this is faster than round-tripping via strings (and hence re-parsing / re-normalising).

In the last couple releases I've removed pathlib's own realpath() and expanduser() implementations, and made it call through to os.path instead. This solved a couple minor bugs and removed a bit of duplication in the CPython codebase, but might have cost some performance. More recently I've been wondering where to draw the line on that sort of thing.

In that case of your patch, the key line is root_path = Path(root). By using the main Path initialiser you're asking pathlib to re-parse and re-normalise a path. Compare this to the Path.glob() implementation, which does everything it can to avoid re-parsing paths.

I suspect this is all fine, and that practicality beats purity here.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@zmievsa

zmievsa commented Jan 4, 2022 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

My implementation certainly requires quite a bit of review -- I've never commited to pathlib or to CPython in general. Implementation-wise, I could just reimplement os.walk or just fix the issues in my implementation -- either way is fine with me. But I think the most important issue at hand is the API for the Path.walk.

barneygale reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@zmievsa

zmievsa commented Jan 8, 2022

Copy link
Copy Markdown
Contributor Author

Added the changes I've mentioned. All the features of os.walk are supported now. Let's move our discussion here:
https://discuss.python.org/t/add-pathlib-path-walk-method/

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@zmievsa

zmievsa commented Jan 8, 2022

Copy link
Copy Markdown
Contributor Author

I will add the tests soon. If anyone has any ideas about what tests we need specifically, I'd love to hear them.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions

github-actions Bot commented Feb 8, 2022

Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Feb 8, 2022
MaxwellDupre
MaxwellDupre suggested changes Feb 26, 2022
View reviewed changes

@MaxwellDupre MaxwellDupre left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add some text to docs, please?
Otherwise how will users know this is available and how to use.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-bot bedevere-bot added awaiting core review and removed awaiting review labels Feb 26, 2022
@zmievsa zmievsa closed this May 8, 2022
@zmievsa
zmievsa force-pushed the bpo-46227/add-pathlib.Path.walk-method branch from ebf6811 to a82baed Compare May 8, 2022 14:39
@bedevere-bot

bedevere-bot commented May 8, 2022

Copy link
Copy Markdown

Every change to Python requires a NEWS entry.

Please, add it using the blurb_it Web app or the blurb command-line tool.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Ovsyanka83 Ovsyanka83 mannequin mentioned this pull request May 8, 2022
add pathlib.Path.walk method #90385
Closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@sobolevn sobolevn sobolevn left review comments
+1 more reviewer
@MaxwellDupre MaxwellDupre MaxwellDupre requested changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting core review stale Stale PR or inactive for long period of time. type-feature A feature request or enhancement

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

7 participants

@zmievsa @the-knights-who-say-ni @AlexWaygood @barneygale @bedevere-bot @sobolevn @MaxwellDupre
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.
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.