Skip to content

shutil: Inconsistent return types when using pathlib #132322

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
srittau opened this issue Apr 9, 2025 · 3 comments
Open

shutil: Inconsistent return types when using pathlib #132322

srittau opened this issue Apr 9, 2025 · 3 comments
Labels
stdlib Python modules in the Lib dir topic-pathlib type-bug An unexpected behavior, bug, or error

Comments

@srittau
Copy link
Contributor

srittau commented Apr 9, 2025

Bug report

Bug description:

Using pathlib with shutil usually works, but there are some quirks when it comes to return types. As an example, see the copy function (but other functions are affected as well):

cpython/Lib/shutil.py

Lines 468 to 484 in 67ded6a

def copy(src, dst, *, follow_symlinks=True):
"""Copy data and mode bits ("cp src dst"). Return the file's destination.
The destination may be a directory.
If follow_symlinks is false, symlinks won't be followed. This
resembles GNU's "cp -P src dst".
If source and destination are the same file, a SameFileError will be
raised.
"""
if os.path.isdir(dst):
dst = os.path.join(dst, os.path.basename(src))
copyfile(src, dst, follow_symlinks=follow_symlinks)
copymode(src, dst, follow_symlinks=follow_symlinks)
return dst

In this case, if a Path object gets passed in as dst, it will be returned unchanged if it is not a directory, but a str will be returned if it is a directory. That's unexpected, the return type should be consistent, probably by always returning a str.

I assume that pathlib support is mostly incidental in shutil, considering that the latter predates the former. shutil should probably be reviewed for proper pathlib support at some point. (See also a few other pathlib/shutil related issues reported here.)

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Linked PRs

@kinow
Copy link
Contributor

kinow commented Apr 9, 2025

probably by always returning a str.

Maybe that's the best option, since it look like shutil doesn't use pathlib directly.

@picnixz picnixz added the stdlib Python modules in the Lib dir label Apr 11, 2025
rpxchoudhury added a commit to rpxchoudhury/cpython that referenced this issue Apr 23, 2025
Fixes issue python#132322 by normalizing return types in shutil.copy, copy2, copyfile, copytree, and move using os.fspath(), so that they consistently return str even when pathlib.Path is passed.

All relevant tests pass locally
@gpshead
Copy link
Member

gpshead commented Apr 27, 2025

There may be code already depending on the existing behavior. ie: type checkers already presume it can return both per https://github.com/python/typeshed/blob/main/stdlib/shutil.pyi#L54

@srittau
Copy link
Contributor Author

srittau commented Apr 28, 2025

Changing this to return a consistent return type seems safe if code is already required to handle both types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir topic-pathlib type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

5 participants