-
Notifications
You must be signed in to change notification settings - Fork 49
Closed
Labels
compatibility 🤝Compatibility with stdlib pathlibCompatibility with stdlib pathlib
Description
Currently opening a UPath via open fails with a FileNotFoundError because the URI returned via __fspath__() is just interpreted as a string path.
>>> import upath
>>> pth = upath.UPath("memory:///abc.txt")
>>> pth.write_text("hello world")
11
>>> with open(pth, "rt") as f:
... print(f.read())
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'memory:/abc.txt'There's two possible ways of improving this error:
- We raise an exception in non-local UPath subclasses in
__fspath__. - Or we could keep the basic functionality that fspath returns a string and raise an exception if we detect that the result was used in
openimport os import sys from textwrap import dedent from typing import Self class _upath_str(str): """helper str subclass for better error messages This helper class allows us to catch when a user tries to provide a UPath instance of a non-local filesystem to Python's `open()` function. """ def __str__(self) -> Self: return self def _upath_audit_hook(name: str, args: tuple) -> None: """audit hook matching the `open` event Raises a better error message if we detect that a user tries to use UPath instances with `open()`. """ if name == "open" and isinstance(args[0], _upath_str): msg = dedent( f"""\ builtins.open does not support non-local UPath instances. Use the pathlib interface instead: >>> pth = UPath({args[0]!r}) >>> with pth.open() as f: >>> ... """ ) raise OSError(msg) sys.addaudithook(_upath_audit_hook) class A: def __fspath__(self): return _upath_str("abc") def __str__(self): return _upath_str("abc") a = A() b = _upath_str("b") print(type(b)) c = str(a) print(type(c)) print(type(str(c))) os.fspath(a) with open(a) as f: pass
(1) would be preferable, but (2) might be useful, since there's some code out there that uses __fspath__ to convert os.PathLike to strings.
Need to do a survey of code on github, and if we choose (1) there needs to be a deprecation period.
Metadata
Metadata
Assignees
Labels
compatibility 🤝Compatibility with stdlib pathlibCompatibility with stdlib pathlib