Coverage for python/lsst/resources/_resourceHandles/_fileResourceHandle.py: 86%

56 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-09-19 01:59 -0700

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 

12 

13__all__ = ("FileResourceHandle",) 

14 

15import logging 

16from collections.abc import Iterable 

17from io import SEEK_SET 

18from typing import IO, TYPE_CHECKING, AnyStr, TypeVar 

19 

20from ._baseResourceHandle import BaseResourceHandle 

21 

22if TYPE_CHECKING: 

23 from .._resourcePath import ResourcePath 

24 

25U = TypeVar("U", str, bytes) 

26 

27 

28class FileResourceHandle(BaseResourceHandle[U]): 

29 """File based specialization of `.BaseResourceHandle`. 

30 

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. 

47 

48 Notes 

49 ----- 

50 Documentation on the methods of this class line should refer to the 

51 corresponding methods in the `io` module. 

52 """ 

53 

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 ) 

68 

69 @property 

70 def name(self) -> str: 

71 # More consistent to return the path without the file://. 

72 return self._uri.ospath 

73 

74 @property 

75 def mode(self) -> str: 

76 return self._mode 

77 

78 def close(self) -> None: 

79 self._fileHandle.close() 

80 

81 @property 

82 def closed(self) -> bool: 

83 return self._fileHandle.closed 

84 

85 def fileno(self) -> int: 

86 return self._fileHandle.fileno() 

87 

88 def flush(self) -> None: 

89 self._fileHandle.flush() 

90 

91 @property 

92 def isatty(self) -> bool: 

93 return self._fileHandle.isatty() 

94 

95 def readable(self) -> bool: 

96 return self._fileHandle.readable() 

97 

98 def readline(self, size: int = -1) -> U: 

99 return self._fileHandle.readline(size) 

100 ... 

101 

102 def readlines(self, hint: int = -1) -> Iterable[U]: 

103 return self._fileHandle.readlines(hint) 

104 

105 def seek(self, offset: int, whence: int = SEEK_SET) -> int: 

106 return self._fileHandle.seek(offset, whence) 

107 

108 def seekable(self) -> bool: 

109 return self._fileHandle.seekable() 

110 

111 def tell(self) -> int: 

112 return self._fileHandle.tell() 

113 

114 def truncate(self, size: int | None = None) -> int: 

115 return self._fileHandle.truncate(size) 

116 

117 def writable(self) -> bool: 

118 return self._fileHandle.writable() 

119 

120 def writelines(self, lines: Iterable[AnyStr]) -> None: 

121 self._fileHandle.writelines(lines) 

122 

123 def read(self, size: int = -1) -> U: 

124 return self._fileHandle.read(size) 

125 

126 def write(self, b: U) -> int: 

127 return self._fileHandle.write(b)