Skip to content

Commit 8770f3f

Browse files
committed
add file.open_file() function
1 parent d28e39a commit 8770f3f

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-4
lines changed

pkg/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ namespaces = true
1515

1616
# ----------------------------------------- Project Metadata -------------------------------------
1717
[project]
18-
version = "0.2.2"
18+
version = "0.2.3"
1919
name = "FileEx"
2020
requires-python = ">=3.10"

pkg/src/fileex/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
"""FileEx"""
22

3-
from fileex import exception, directory, search, path
3+
from fileex import directory, exception, file, path, search
44

55
__all__ = [
6-
"exception",
76
"directory",
8-
"search",
7+
"exception",
8+
"file",
99
"path",
10+
"search",
1011
]

pkg/src/fileex/file.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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

Comments
 (0)