Coverage for python/lsst/resources/_resourceHandles/_fileResourceHandle.py: 86%
56 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 09:30 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 09:30 +0000
1# This file is part of lsst-resources.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# Use of this source code is governed by a 3-clause BSD-style
10# license that can be found in the LICENSE file.
11from __future__ import annotations
13__all__ = ("FileResourceHandle",)
15import logging
16from collections.abc import Iterable
17from io import SEEK_SET
18from typing import IO, TYPE_CHECKING, AnyStr, TypeVar
20from ._baseResourceHandle import BaseResourceHandle
22if TYPE_CHECKING:
23 from .._resourcePath import ResourcePath
25U = TypeVar("U", str, bytes)
28class FileResourceHandle(BaseResourceHandle[U]):
29 """File based specialization of `.BaseResourceHandle`.
31 Parameters
32 ----------
33 mode : `str`
34 Handle modes as described in the python `io` module.
35 log : `~logging.Logger`
36 Logger to used when writing messages.
37 uri : `lsst.resources.ResourcePath`
38 URI of the file on the filesystem to use.
39 encoding : `str` or None
40 Optionally supply the encoding of the file. If a file is opened in
41 binary mode, this argument is not used.
42 newline : `str`
43 When doing multiline operations, break the stream on given character.
44 Defaults to newline. If a file is opened in binary mode, this argument
45 is not used, as binary files will only split lines on the binary
46 newline representation.
48 Notes
49 -----
50 Documentation on the methods of this class line should refer to the
51 corresponding methods in the `io` module.
52 """
54 def __init__(
55 self, mode: str, log: logging.Logger, uri: ResourcePath, *, encoding: str | None, newline: str = "\n"
56 ):
57 super().__init__(mode, log, uri, newline=newline)
58 self._filename = uri.ospath
59 # Opening a file in binary mode supports neither a newline nor an
60 # encoding argument. ResourcePath.open documents encoding as being
61 # ignored for binary IO, so drop it rather than letting open() raise.
62 binary = "b" in mode
63 newline_arg = None if binary else newline
64 encoding_arg = None if binary else encoding
65 self._fileHandle: IO = open(
66 file=uri.ospath, mode=self._mode, newline=newline_arg, encoding=encoding_arg
67 )
69 @property
70 def name(self) -> str:
71 # More consistent to return the path without the file://.
72 return self._uri.ospath
74 @property
75 def mode(self) -> str:
76 return self._mode
78 def close(self) -> None:
79 self._fileHandle.close()
81 @property
82 def closed(self) -> bool:
83 return self._fileHandle.closed
85 def fileno(self) -> int:
86 return self._fileHandle.fileno()
88 def flush(self) -> None:
89 self._fileHandle.flush()
91 @property
92 def isatty(self) -> bool:
93 return self._fileHandle.isatty()
95 def readable(self) -> bool:
96 return self._fileHandle.readable()
98 def readline(self, size: int = -1) -> U:
99 return self._fileHandle.readline(size)
100 ...
102 def readlines(self, hint: int = -1) -> Iterable[U]:
103 return self._fileHandle.readlines(hint)
105 def seek(self, offset: int, whence: int = SEEK_SET) -> int:
106 return self._fileHandle.seek(offset, whence)
108 def seekable(self) -> bool:
109 return self._fileHandle.seekable()
111 def tell(self) -> int:
112 return self._fileHandle.tell()
114 def truncate(self, size: int | None = None) -> int:
115 return self._fileHandle.truncate(size)
117 def writable(self) -> bool:
118 return self._fileHandle.writable()
120 def writelines(self, lines: Iterable[AnyStr]) -> None:
121 self._fileHandle.writelines(lines)
123 def read(self, size: int = -1) -> U:
124 return self._fileHandle.read(size)
126 def write(self, b: U) -> int:
127 return self._fileHandle.write(b)