|
| 1 | +from pathlib import Path |
| 2 | +from typing import IO |
| 3 | +import io |
| 4 | + |
| 5 | +from fileex.file import is_path |
| 6 | + |
| 7 | + |
| 8 | +def open_file( |
| 9 | + source: str | bytes | Path, |
| 10 | + mode: str = 'r', |
| 11 | + encoding: str | None = None |
| 12 | +) -> IO[str] | IO[bytes]: |
| 13 | + """Create an open file-like object from content or filepath. |
| 14 | +
|
| 15 | + If `source` is a `str` or `bytes`, returns an in-memory |
| 16 | + file-like object containing that content. If `source` is a |
| 17 | + `pathlib.Path`, opens the file at that path with the |
| 18 | + specified mode. |
| 19 | +
|
| 20 | + Parameters |
| 21 | + ---------- |
| 22 | + source |
| 23 | + File content (as string or bytes) |
| 24 | + or path (as string or pathlib.Path). |
| 25 | + If a string is provided, it is first checked |
| 26 | + if it is a valid existing file path. |
| 27 | + If so, the string is treated as a path, |
| 28 | + otherwise as file content. |
| 29 | + Bytes are always treated as content, |
| 30 | + and a `pathlib.Path` is always treated as a file path. |
| 31 | + mode |
| 32 | + Mode (e.g., 'r', 'w', 'rb') to open the file when `source` is a path. |
| 33 | + Ignored when `source` is content. |
| 34 | + encoding |
| 35 | + Encoding to use when opening a text file from a path. |
| 36 | + Ignored when `source` is content or in binary mode. |
| 37 | +
|
| 38 | + Returns |
| 39 | + ------- |
| 40 | + A file-like object. For content sources, this will be an |
| 41 | + `io.StringIO` or `io.BytesIO`. For file paths, this returns |
| 42 | + the standard file object. |
| 43 | + You can close the returned object by calling its `close()` method |
| 44 | + when done to release resources. |
| 45 | + """ |
| 46 | + if isinstance(source, str): |
| 47 | + if is_path(source): |
| 48 | + return Path(source).open(mode=mode, encoding=encoding) |
| 49 | + return io.StringIO(source) |
| 50 | + if isinstance(source, bytes): |
| 51 | + return io.BytesIO(source) |
| 52 | + if isinstance(source, Path): |
| 53 | + return source.open(mode=mode, encoding=encoding) |
| 54 | + raise TypeError( |
| 55 | + f"Expected str, bytes, or pathlib.Path, got {type(source).__name__}" |
| 56 | + ) |
0 commit comments