Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type annotations: pathlib.Path vs importlib.resources.abc.Traversable

When loading file resources that are bundled inside my distribution package, I use importlib.resources.files. When loading files from disk, I use pathlib.Path.

Sometimes I want to write a function that will take either:

from importlib.resources.abc import Traversable
from pathlib import Path

def process_file(file_to_process: Traversable | Path) -> None: ...

It feels cumbersome to annotate all file-processing functions with Traversable | Path. I could define and use my own union type, but that feels like something that Python might already have built-in that I'm missing. I only require the basic subset of both types: open / close / read / write, etc, and nothing like touching permissions or using OS-specific details.

What is the correct type to use for a file resource that can be loaded from a distribution package via importlib or from a drive via pathlib?

I'm currently using Python 3.11 but will upgrade over time, so all 3.11+ answers are welcome.

like image 328
Charles Nicholson Avatar asked Sep 01 '25 23:09

Charles Nicholson


1 Answers

I believe you can just use Traversable in all cases. It looks like Traversable is a protocol, and since pathlib.Path implements the necessary methods, objects of type pathlib.Path should also be Traversable. And in fact:

>>> from pathlib import Path
>>> from importlib.resources.abc import Traversable
>>> p = Path('.')
>>> isinstance(p, Path)
True
>>> isinstance(p, Traversable)
True

So you should be able to write:

def process_file(file_to_process: Traversable) -> None: ...

I've checked, and mypy seems happy with the above annotation when calling process_file(Path('example.txt')).

like image 199
larsks Avatar answered Sep 03 '25 19:09

larsks