TLDR;
Is there a something like numpy’s asarray for pathlib.Path
that just returns the object without conversion/copy in case it’s already a path (as opposed to a str | bytes | os.PathLike
or anything else the constructor supports).
Background
To accept objects that represent a path the abstract interface os.PathLike
can be used and conveniently enables a function to get a string/bytes representation using os.fspath
regardless of the passed in object.
I often however find myself wanting to work with pathlib.Path
objects while still allowing paths passed as str | bytes
without explicitly first checking for the types (as all I really care about is the resulting type). This can of course be done by always constructing a Path
object from the argument but that always results in a copy even if the argument already is a Path
which would also be the most common case for functions calling eachother.
Of course the idiom path = path if isinstance(path, pathlib.Path) else pathlib.Path(path)
works but the pattern and need feels common enough that I feel that there is a reasonable chance it’s already thought of and I’m just missing it, especially since the path objects are mostly immutable and returns copies on all modifications anyway.
It could of course be that the thought is that the copy for every level in pathlib.Path.__new__
(though the call to _from_parts
) is performant enough that the pattern with copy is the intended way.
Edit: Added current example as clarification that I have no problem solving it with a function and the question is more about if the use-case was already catered for in a builtin way and I’m failing to find it.
Current solutions to clarify that it’s not about how to solve the problem
def ensure_path(path: os.PathLike | str | bytes) -> pathlib.Path:
return path if isinstance(path, pathlib.Path) else pathlib.Path(path)
# This isn't that onerous of course but it feels common enough that I
# expected it may have some existing solution.
def accept_path_argument(path: path: os.PathLike | str | bytes):
path_ = ensure_path(path)
# This is of course also fine with only drawback needless garbage creation
def accept_path_argument(path: path: os.PathLike | str | bytes):
path_ = pathlib.Path(path)