Skip to content

Commit 77028d9

Browse files
xcp/accessor.py: openText(): Context manager to read text from addr
Add `Accessor.openText()` as context manager to wrap openAddress() with `io.TextIOWrapper` (if needed). It yields IO[str] or False, closing the created TextIOWrapper and the underlying file on leaving the context. It is intented for use in xcp.repository and any other user requiring text as string without having to call .decode() on the returned file object. It also closes the underlying file object on leaving the context. Signed-off-by: Bernhard Kaindl <bernhard.kaindl@cloud.com>
1 parent 6e930d1 commit 77028d9

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

xcp/accessor.py

Lines changed: 21 additions & 0 deletions
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -25,17 +25,22 @@
25

25

26
"""accessor - provide common interface to access methods"""
26
"""accessor - provide common interface to access methods"""
27

27

28+
# pyre-ignore-all-errors[6,16]
28
import ftplib
29
import ftplib
30+
import io
29
import os
31
import os
32+
import sys
30
import tempfile
33
import tempfile
31
import errno
34
import errno
35+
from contextlib import contextmanager
32
from typing import cast, TYPE_CHECKING
36
from typing import cast, TYPE_CHECKING
33

37

34
from six.moves import urllib # pyright: ignore
38
from six.moves import urllib # pyright: ignore
35

39

36
from xcp import logger, mount
40
from xcp import logger, mount
37

41

38
if TYPE_CHECKING:
42
if TYPE_CHECKING:
43+
from collections.abc import Generator
39
from typing import IO
44
from typing import IO
40
from typing_extensions import Literal
45
from typing_extensions import Literal
41

46

@@ -70,6 +75,22 @@ def access(self, name):
70

75

71
return True
76
return True
72

77

78+
@contextmanager
79+
def openText(self, address):
80+
# type:(str) -> Generator[IO[str] | Literal[False], None, None]
81+
"""Context manager to read text from address using 'with'. Yields IO[str] or False"""
82+
readbuffer = self.openAddress(address)
83+
84+
if readbuffer and sys.version_info >= (3, 0):
85+
textiowrapper = io.TextIOWrapper(readbuffer, encoding="utf-8")
86+
yield textiowrapper
87+
textiowrapper.close()
88+
else:
89+
yield cast(io.TextIOWrapper, readbuffer)
90+
91+
if readbuffer:
92+
readbuffer.close()
93+
73
def openAddress(self, address):
94
def openAddress(self, address):
74
# type:(str) -> IO[bytes] | Literal[False]
95
# type:(str) -> IO[bytes] | Literal[False]
75
"""must be overloaded"""
96
"""must be overloaded"""

0 commit comments

Comments
 (0)