1#
2# Copyright (C) 2020 Radim Rehurek <me@radimrehurek.com>
3#
4# This code is distributed under the terms and conditions
5# from the MIT License (MIT).
6#
7"""Implements the transport for the file:// schema."""
8
9from __future__ import annotations
10
11import builtins
12import io
13import os.path
14from typing import IO, TYPE_CHECKING, Any, TypedDict
15
16if TYPE_CHECKING:
17 from smart_open._typing import TransportParams
18
19SCHEME = "file"
20
21URI_EXAMPLES = (
22 "./local/path/file",
23 "~/local/path/file",
24 "local/path/file",
25 "./local/path/file.gz",
26 "file:///home/user/file",
27 "file:///home/user/file.bz2",
28)
29
30
31class _LocalUri(TypedDict):
32 scheme: str
33 uri_path: str
34
35
36open = io.open
37
38
39def parse_uri(uri_as_string: str) -> _LocalUri:
40 """Parse a ``file://`` URI (or bare local path) into its path component."""
41 local_path = extract_local_path(uri_as_string)
42 return {"scheme": SCHEME, "uri_path": local_path}
43
44
45def open_uri(uri_as_string: str, mode: str, transport_params: TransportParams) -> IO[Any]: # noqa: ARG001 # interface conformance
46 """Open a local file URI using the given mode."""
47 parsed_uri = parse_uri(uri_as_string)
48 return builtins.open(parsed_uri["uri_path"], mode) # noqa: PTH123 # mirrors builtins.open signature exactly
49
50
51def extract_local_path(uri_as_string: str) -> str:
52 """Return the user-expanded local filesystem path from `uri_as_string`."""
53 if uri_as_string.startswith("file://"):
54 local_path = uri_as_string.replace("file://", "", 1)
55 else:
56 local_path = uri_as_string
57 return os.path.expanduser(local_path) # noqa: PTH111 # pathlib collapses leading double slashes; preserve os.path semantics