Coverage for python/lsst/resources/_resourceHandles/_baseResourceHandle.py: 74%
76 statements
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-13 09:59 +0000
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-13 09:59 +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
13from types import TracebackType
15__all__ = ("BaseResourceHandle", "CloseStatus", "ResourceHandleProtocol")
17from abc import ABC, abstractmethod, abstractproperty
18from collections.abc import Callable, Iterable
19from enum import Enum, auto
20from io import SEEK_SET
21from logging import Logger
22from typing import AnyStr, Generic, Protocol, TypeVar
24S = TypeVar("S", bound="ResourceHandleProtocol")
25T = TypeVar("T", bound="BaseResourceHandle")
26U = TypeVar("U", str, bytes)
29class CloseStatus(Enum):
30 """Enumerated closed/open status of a file handle, implementation detail
31 that may be used by BaseResourceHandle children.
32 """
34 OPEN = auto()
35 CLOSING = auto()
36 CLOSED = auto()
39class ResourceHandleProtocol(Protocol, Generic[U]):
40 """Defines the interface protocol that is compatible with children of
41 `.BaseResourceHandle`.
43 Any class that satisfies this protocol can be used in any context where a
44 `.BaseResourceHandle` is expected.
45 """
47 @abstractproperty
48 def mode(self) -> str: ... 48 ↛ exitline 48 didn't return from function 'mode'
50 @abstractmethod
51 def close(self) -> None: ... 51 ↛ exitline 51 didn't return from function 'close'
53 @abstractproperty
54 def closed(self) -> bool: ... 54 ↛ exitline 54 didn't return from function 'closed'
56 @abstractmethod
57 def fileno(self) -> int: ... 57 ↛ exitline 57 didn't return from function 'fileno'
59 @abstractmethod
60 def flush(self) -> None: ... 60 ↛ exitline 60 didn't return from function 'flush'
62 @abstractproperty
63 def isatty(self) -> bool | Callable[[], bool]: ... 63 ↛ exitline 63 didn't return from function 'isatty'
65 @abstractmethod
66 def readable(self) -> bool: ... 66 ↛ exitline 66 didn't return from function 'readable'
68 @abstractmethod
69 def readline(self, size: int = -1) -> U: ... 69 ↛ exitline 69 didn't return from function 'readline'
71 @abstractmethod
72 def readlines(self, hint: int = -1) -> Iterable[U]: ... 72 ↛ exitline 72 didn't return from function 'readlines'
74 @abstractmethod
75 def seek(self, offset: int, whence: int = SEEK_SET, /) -> int:
76 pass
78 @abstractmethod
79 def seekable(self) -> bool: ... 79 ↛ exitline 79 didn't return from function 'seekable'
81 @abstractmethod
82 def tell(self) -> int: ... 82 ↛ exitline 82 didn't return from function 'tell'
84 @abstractmethod
85 def truncate(self, size: int | None = None) -> int: ... 85 ↛ exitline 85 didn't return from function 'truncate'
87 @abstractmethod
88 def writable(self) -> bool: ... 88 ↛ exitline 88 didn't return from function 'writable'
90 @abstractmethod
91 def writelines(self, lines: Iterable[U], /) -> None: ... 91 ↛ exitline 91 didn't return from function 'writelines'
93 @abstractmethod
94 def read(self, size: int = -1) -> U: ... 94 ↛ exitline 94 didn't return from function 'read'
96 @abstractmethod
97 def write(self, b: U, /) -> int: ... 97 ↛ exitline 97 didn't return from function 'write'
99 def __enter__(self: S) -> S: ... 99 ↛ exitline 99 didn't return from function '__enter__'
101 def __exit__( 101 ↛ exitline 101 didn't jump to the function exit
102 self,
103 exc_type: type[BaseException] | None,
104 exc_val: BaseException | None,
105 exc_tb: TracebackType | None,
106 /,
107 ) -> bool | None: ...
110class BaseResourceHandle(ABC, ResourceHandleProtocol[U]):
111 """Base class interface for the handle like interface of
112 `~lsst.resources.ResourcePath` subclasses.
114 Parameters
115 ----------
116 mode : `str`
117 Handle modes as described in the python `io` module.
118 log : `~logging.Logger`
119 Logger to used when writing messages.
120 newline : `str`
121 When doing multiline operations, break the stream on given character
122 Defaults to newline.
124 Notes
125 -----
126 Documentation on the methods of this class line should refer to the
127 corresponding methods in the `io` module.
128 """
130 _closed: CloseStatus
131 _mode: str
132 _log: Logger
133 _newline: U
135 def __init__(self, mode: str, log: Logger, *, newline: AnyStr | None = None) -> None:
136 if newline is None:
137 if "b" in mode:
138 self._newline = b"\n" # type: ignore
139 else:
140 self._newline = "\n" # type: ignore
141 else:
142 self._newline = newline # type: ignore
143 self._mode = mode
144 self._log = log
146 @property
147 def mode(self) -> str:
148 return self._mode
150 def __enter__(self: T) -> T:
151 self._closed = CloseStatus.OPEN
152 return self
154 def __exit__(
155 self,
156 exc_type: type[BaseException] | None,
157 exc_bal: BaseException | None,
158 exc_tb: TracebackType | None,
159 ) -> bool | None:
160 self.close()
161 return None