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 — GH-73991: Add `pathlib.Path.copytree()` by barneygale · Pull Request #120718 · python/cpython

Conversation

@barneygale

@barneygale barneygale commented Jun 19, 2024 •
edited by github-actions Bot
Loading

Uh oh!

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

Copy link
Copy Markdown
Contributor

Add pathlib.Path.copytree() method, which recursively copies one directory to another.

This differs from shutil.copytree() in the following respects:

  1. Our method has a follow_symlinks argument, whereas shutil's has a symlinks argument with an inverted meaning.
  2. Our method lacks something like a copy_function argument. It always uses Path.copy() to copy files.
  3. Our method lacks something like a ignore_dangling_symlinks argument. Instead, users can filter out danging symlinks with ignore, or ignore exceptions with on_error
  4. Our ignore argument is a callable that accepts a single path object, whereas shutil's accepts a path and a list of child filenames.
  5. We add an on_error argument, which is a callable that accepts an OSError instance. (Path.walk() also accepts such a callable). This is done instead of aggregating exceptions into an shutil.Error instance.
  • Issue: Support moving across filesystems in pathlib.Path, as shutil.move() does #73991

📚 Documentation preview 📚: https://cpython-previews--120718.org.readthedocs.build/

Sorry, something went wrong.

Uh oh!

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

All reactions
@barneygale
pythonGH-73991: Add pathlib.Path.copytree()
873fcc6
Add `pathlib.Path.copytree()` method, which recursively copies one
directory to another.

This differs from `shutil.copytree()` in the following respects:

1. Our method has a *follow_symlinks* argument, whereas shutil's has a
   *symlinks* argument with an inverted meaning.
2. Our method lacks something like a *copy_function* argument. It always
   uses `Path.copy()` to copy files.
3. Our method lacks something like a *ignore_dangling_symlinks* argument.
   Instead, users can filter out danging symlinks with *ignore*, or
   ignore exceptions with *on_error*
4. Our *ignore* argument is a callable that accepts a single path object,
   whereas shutil's accepts a path and a list of child filenames.
5. We add an *on_error* argument, which is a callable that accepts
   an `OSError` instance. (`Path.walk()` also accepts such a callable).
@barneygale barneygale added the topic-pathlib label Jun 19, 2024
@bedevere-app bedevere-app Bot mentioned this pull request Jun 19, 2024
Support moving across filesystems in pathlib.Path, as shutil.move() does #73991
Closed
@bedevere-app bedevere-app Bot added the awaiting core review label Jun 19, 2024
@barneygale

barneygale commented Jun 19, 2024

Copy link
Copy Markdown
Contributor Author

Some parts of the design aren't obvious, particularly the ignore and on_error arguments. Happy to adjust or even remove some arguments if we'd like to kick the can down the road - I don't think either of those arguments are essential to expose straight away.

All reactions

Sorry, something went wrong.

Uh oh!

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

@barneygale
barneygale requested a review from pfmoore June 19, 2024 02:31
@barneygale

barneygale commented Jun 19, 2024

Copy link
Copy Markdown
Contributor Author

@pfmoore I've requested your review as you've already given this idea some scrutiny on the forum! Hope that's alright, thank you.

All reactions

Sorry, something went wrong.

Uh oh!

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

nineteendo
nineteendo reviewed Jun 19, 2024
View reviewed changes
Comment thread Doc/library/pathlib.rst Resolved

Uh oh!

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

nineteendo
nineteendo reviewed Jun 19, 2024
View reviewed changes
Comment thread Lib/test/test_pathlib/test_pathlib.py Resolved

Uh oh!

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

Comment thread Lib/test/test_pathlib/test_pathlib_abc.py Resolved

Uh oh!

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

pfmoore
pfmoore reviewed Jun 19, 2024
View reviewed changes

@pfmoore pfmoore 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.

The code LGTM. I've dome a partial review of the tests, but I'll be honest I'm not entirely clear what the follow_symlinks argument does (it's not something I use myself) so I didn't really review those parts of the tests.

I'll try to find some time to do a more detailed review later.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Lib/test/test_pathlib/test_pathlib_abc.py Resolved

Uh oh!

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

Comment thread Lib/test/test_pathlib/test_pathlib_abc.py Resolved

Uh oh!

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

Comment thread Lib/test/test_pathlib/test_pathlib_abc.py Resolved

Uh oh!

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

@barneygale @nineteendo
Apply suggestions from code review
ab5fa4c
Co-authored-by: Nice Zombies <[email protected]>
nineteendo
nineteendo reviewed Jun 22, 2024
View reviewed changes
Comment thread Lib/test/test_pathlib/test_pathlib.py Resolved

Uh oh!

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

barneygale and others added 2 commits June 23, 2024 17:37
@barneygale @nineteendo
Update Lib/test/test_pathlib/test_pathlib.py
f9bfdc9
Co-authored-by: Nice Zombies <[email protected]>
@barneygale
Improve tests
8c453bb
@barneygale

barneygale commented Jun 23, 2024 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Contributor Author

Thanks for the reviews and fixes, both.

I'm not entirely clear what the follow_symlinks argument does (it's not something I use myself) so I didn't really review those parts of the tests.

The default behaviour (follow_symlinks=True) dereferences any symlinks in the source tree, so the final destination tree never contains symlinks. If you set follow_symlinks=False, any symlinks in the source tree will be re-created in the destination tree with the same targets.

Our forthcoming implementation of Path.move() will call source.copytree(target, follow_symlinks=False) then source.rmtree() (roughly), because users expect "move" operations to preserve symlinks (not follow them).

nineteendo reacted with heart emoji
All reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

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

pfmoore
pfmoore approved these changes Jun 23, 2024
View reviewed changes
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting core review labels Jun 23, 2024
@pfmoore

pfmoore commented Jun 23, 2024

Copy link
Copy Markdown
Member

Thanks for the explanation - that's the clearest I've seen it expressed, and for the first time (possibly ever) I get what's going on.

barneygale reacted with heart emoji
All reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

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

@barneygale
barneygale merged commit 35e998f into python:main Jun 23, 2024
@bedevere-app bedevere-app Bot removed the awaiting merge label Jun 23, 2024
mrahtz pushed a commit to mrahtz/cpython that referenced this pull request Jun 30, 2024
@barneygale @nineteendo @mrahtz
pythonGH-73991: Add pathlib.Path.copytree() (python#120718)
d25629a
Add `pathlib.Path.copytree()` method, which recursively copies one
directory to another.

This differs from `shutil.copytree()` in the following respects:

1. Our method has a *follow_symlinks* argument, whereas shutil's has a
   *symlinks* argument with an inverted meaning.
2. Our method lacks something like a *copy_function* argument. It always
   uses `Path.copy()` to copy files.
3. Our method lacks something like a *ignore_dangling_symlinks* argument.
   Instead, users can filter out danging symlinks with *ignore*, or
   ignore exceptions with *on_error*
4. Our *ignore* argument is a callable that accepts a single path object,
   whereas shutil's accepts a path and a list of child filenames.
5. We add an *on_error* argument, which is a callable that accepts
   an `OSError` instance. (`Path.walk()` also accepts such a callable).

Co-authored-by: Nice Zombies <[email protected]>
estyxx pushed a commit to estyxx/cpython that referenced this pull request Jul 17, 2024
@barneygale @nineteendo @estyxx
pythonGH-73991: Add pathlib.Path.copytree() (python#120718)
e524c61
Add `pathlib.Path.copytree()` method, which recursively copies one
directory to another.

This differs from `shutil.copytree()` in the following respects:

1. Our method has a *follow_symlinks* argument, whereas shutil's has a
   *symlinks* argument with an inverted meaning.
2. Our method lacks something like a *copy_function* argument. It always
   uses `Path.copy()` to copy files.
3. Our method lacks something like a *ignore_dangling_symlinks* argument.
   Instead, users can filter out danging symlinks with *ignore*, or
   ignore exceptions with *on_error*
4. Our *ignore* argument is a callable that accepts a single path object,
   whereas shutil's accepts a path and a list of child filenames.
5. We add an *on_error* argument, which is a callable that accepts
   an `OSError` instance. (`Path.walk()` also accepts such a callable).

Co-authored-by: Nice Zombies <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@pfmoore pfmoore pfmoore approved these changes
+1 more reviewer
@nineteendo nineteendo nineteendo left review comments
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

topic-pathlib

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.

3 participants

@barneygale @pfmoore @nineteendo
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.