@@ -227,15 +227,21 @@ with fs.open(path_str, 'rb') as f:
227227
228228### How do I create a custom UPath for a new filesystem?
229229
230- Subclass ` UPath ` and register it:
230+ Let's say you have an fsspec filesystem with protocol ` myproto ` and the default
231+ implementation does not correctly work for ` .is_dir() ` . You can then subclass
232+ ` UPath ` and register your implementation:
231233
232234``` python
233235from upath import UPath
234236from upath.registry import register_implementation
235237
236238class MyCustomPath (UPath ):
237- def custom_method (self ):
238- return f " Custom behavior for { self } "
239+
240+ # fix specific methods if the filesystem is a bit non-standard
241+ def is_dir (self , * , follow_symlinks = True ):
242+ # some special way to check if it's a dir
243+ is_dir = ...
244+ return is_dir
239245
240246# Register for your protocol
241247register_implementation(" myproto" , MyCustomPath)
@@ -244,6 +250,52 @@ register_implementation("myproto", MyCustomPath)
244250my_path = UPath(" myproto://server/path" )
245251```
246252
253+ !!! note "don't extend the API in your subclass"
254+
255+ You should not extend the API in your UPath subclass.
256+ If you want to add new methods please use `upath.extensions.ProxyUPath` as a base class
257+
258+ ### How do I add custom methods to UPath?
259+
260+ If you need to add domain-specific methods (like ` .download() ` or ` .upload() ` ), use ` ProxyUPath ` instead of subclassing ` UPath ` directly:
261+
262+ ``` python
263+ from upath import UPath
264+ from upath.extensions import ProxyUPath
265+
266+ class MyCustomPath (ProxyUPath ):
267+ """ A path with extra convenience methods."""
268+
269+ def download (self , local_path ):
270+ """ Download this remote file to a local path."""
271+ local = UPath(local_path)
272+ local.write_bytes(self .read_bytes())
273+ return local
274+
275+ def get_metadata (self ):
276+ """ Get custom metadata for this file."""
277+ stat = self .stat()
278+ return {
279+ ' size' : stat.st_size,
280+ ' modified' : stat.st_mtime,
281+ ' name' : self .name,
282+ }
283+
284+ # Use it like a regular UPath
285+ path = MyCustomPath(" s3://my-bucket/data.csv" , anon = True )
286+
287+ # Access standard UPath methods
288+ print (path.exists())
289+ print (path.name)
290+
291+ # Use your custom methods
292+ metadata = path.get_metadata()
293+ path.download(" /tmp/data.csv" )
294+ ```
295+
296+ The key difference: ` ProxyUPath ` wraps a ` UPath ` instance and delegates to it, while keeping your custom methods separate from the core pathlib API.
297+
298+
247299---
248300
249301## Supported Filesystems
0 commit comments