# Incrementally move high-level path operations from shutil to pathlib

**URL:** <https://discuss.python.org/t/incrementally-move-high-level-path-operations-from-shutil-to-pathlib/19208>\
**Category:** Ideas\
**Created:** [September 17, 2022, 10:30pm UTC](https://discuss.python.org/t/incrementally-move-high-level-path-operations-from-shutil-to-pathlib/19208 "2022-09-17T22:30:17Z")\
**Posts on this page:** 1\
**Showing post:** 32

<div class="post-metadata">

**Author:** ![barneygale](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/barneygale/32/1882_2.png) [@barneygale](https://discuss.python.org/u/barneygale)\
**Post date:** [May 17, 2024, 7:28pm UTC](https://discuss.python.org/t/incrementally-move-high-level-path-operations-from-shutil-to-pathlib/19208/32 "2024-05-17T19:28:11Z")

</div>

There’s some interesting discussion on the tracker about whether it makes sense for `pathlib` to import `shutil.copy2`, and whether `copy2()` and friends are best placed in `shutil` or some other module.

> <https://github.com/python/cpython/issues/73991>
>
> BPO | \[29805\](https://bugs.python.org/issue29805)
> \--- | :---
> Nosy | @brettcannon…, @pfmoore, @ericvsmith, @tjguk, @zware, @eryksun, @zooba
> 
> \<sup\>\*Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.\*\</sup\>
> 
> \<details\>\<summary\>Show more details\</summary\>\<p\>
> 
> GitHub fields:
> \`\`\`python
> assignee = None
> closed\_at = None
> created\_at = \<Date 2017-03-13.21:03:44.694\>
> labels = \['3.8', 'type-feature', 'library', '3.9', '3.10'\]
> title = 'Support moving across filesystems in pathlib.Path, as shutil.move() does'
> updated\_at = \<Date 2021-03-15.21:26:30.922\>
> user = 'https://bugs.python.org/LaurentMazuel'
> \`\`\`
> 
> bugs.python.org fields:
> \`\`\`python
> activity = \<Date 2021-03-15.21:26:30.922\>
> actor = 'eryksun'
> assignee = 'none'
> closed = False
> closed\_date = None
> closer = None
> components = \['Library (Lib)'\]
> creation = \<Date 2017-03-13.21:03:44.694\>
> creator = 'Laurent.Mazuel'
> dependencies = \[\]
> files = \[\]
> hgrepos = \[\]
> issue\_num = 29805
> keywords = \[\]
> message\_count = 6.0
> messages = \['289549', '289552', '289559', '289630', '289687', '289688'\]
> nosy\_count = 8.0
> nosy\_names = \['brett.cannon', 'paul.moore', 'eric.smith', 'tim.golden', 'Laurent.Mazuel', 'zach.ware', 'eryksun', 'steve.dower'\]
> pr\_nums = \[\]
> priority = 'normal'
> resolution = None
> stage = None
> status = 'open'
> superseder = None
> type = 'enhancement'
> url = 'https://bugs.python.org/issue29805'
> versions = \['Python 3.8', 'Python 3.9', 'Python 3.10'\]
> \`\`\`
> 
> \</p\>\</details\>
> 
> 
> 
> \### Linked PRs
> \* gh-30650
> \* gh-119058
> \* gh-119060
> \* gh-119079

> <https://github.com/python/cpython/pull/119079>
>
> Move these low-level file copy functions from \`shutil\` to \`os\`:
> 
> \- \`copyfileob…j()\`
> \- \`copyfile()\`
> \- \`copymode()\`
> \- \`copystat()\`
> \- \`copy2()\` (as \`copy()\`, minus support for copying into a destination directory)
> 
> The names remain in \`shutil\` for backwards compatibility.
> 
> 
> 
> \* Issue: gh-73991
> 
> 
> 
> 
> \----
> 📚 Documentation preview 📚: https://cpython-previews--119079.org.readthedocs.build/

I think it makes sense to continue the discussion here. My take:

The implementations of `shutil.copy2()`, `copyfile()`, and `copystat()` deal with some low-level OS and filesystem details ([code](https://github.com/python/cpython/blob/31a28cbae0989f57ad01b428c007dade24d9593a/Lib/shutil.py#L42-L470)), whereas pathlib normally delegates all that stuff to `os` and `os.path`. In these instances, shutil seems _lower-level_ than anything in pathlib.

The implementations of `shutil.copytree()`, `rmtree()` and `move()` are mostly without any OS-specific details - they string together the lower-level `copy()` functions, and other functions from `os`, in just the right way. They seem to be on about the same conceptual level as pathlib’s features, like `Path.glob()` and `Path.walk()`.

The archiving functions provided by `shutil` seem to be on a higher level still, as they provide a generic interface to multiple formats. I’d say they’re higher level than anything in pathlib.

What to make of all this? @steve.dower [suggested](https://github.com/python/cpython/issues/73991#issuecomment-2113228933) that the copy functions might be best placed in the `os` module. @storchaka [pushed back](https://github.com/python/cpython/pull/119079#issuecomment-2114341003) on this. I feel ambivalent - I agree with Steve that the copy functions feel more at home in `os`, but they don’t seem obviously out-of-place in `shutil` either, and I’d rather not move ~1000 lines of code unless I have plenty of buy-in! @thesamesam [noted](https://github.com/python/cpython/pull/119079#issuecomment-2114001056) an [issue](https://github.com/python/cpython/issues/81338) and [PR](https://github.com/python/cpython/pull/93152) about using `copy_file_range()` on Linux to speed up copying.

A shiny penny for anyone’s thoughts! Should the copy functions remain in `shutil`? If so, is it (un)reasonable to import and use them from `pathlib`?

---

_[View the full topic](https://discuss.python.org/t/incrementally-move-high-level-path-operations-from-shutil-to-pathlib/19208)._
