1
1
from contextlib import contextmanager
2
2
from contextvars import ContextVar
3
+ import logging
3
4
from typing import Any , Iterator , Optional , Protocol , runtime_checkable
4
5
5
6
__all__ = ("OutputStream" , "InputStream" , "IOStream" )
6
7
8
+ logger = logging .getLogger (__name__ )
9
+
7
10
8
11
@runtime_checkable
9
12
class OutputStream (Protocol ):
@@ -39,6 +42,31 @@ def input(self, prompt: str = "", *, password: bool = False) -> str:
39
42
class IOStream (InputStream , OutputStream , Protocol ):
40
43
"""A protocol for input/output streams."""
41
44
45
+ # ContextVar must be used in multithreaded or async environments
46
+ _default_io_stream : ContextVar [Optional ["IOStream" ]] = ContextVar ("default_iostream" , default = None )
47
+ _default_io_stream .set (None )
48
+ _global_default : Optional ["IOStream" ] = None
49
+
50
+ @staticmethod
51
+ def set_global_default (stream : "IOStream" ) -> None :
52
+ """Set the default input/output stream.
53
+
54
+ Args:
55
+ stream (IOStream): The input/output stream to set as the default.
56
+ """
57
+ IOStream ._global_default = stream
58
+
59
+ @staticmethod
60
+ def get_global_default () -> "IOStream" :
61
+ """Get the default input/output stream.
62
+
63
+ Returns:
64
+ IOStream: The default input/output stream.
65
+ """
66
+ if IOStream ._global_default is None :
67
+ raise RuntimeError ("No global default IOStream has been set" )
68
+ return IOStream ._global_default
69
+
42
70
@staticmethod
43
71
def get_default () -> "IOStream" :
44
72
"""Get the default input/output stream.
@@ -48,13 +76,10 @@ def get_default() -> "IOStream":
48
76
"""
49
77
iostream = IOStream ._default_io_stream .get ()
50
78
if iostream is None :
51
- raise RuntimeError ("No default IOStream has been set" )
79
+ logger .warning ("No default IOStream has been set, defaulting to IOConsole." )
80
+ return IOStream .get_global_default ()
52
81
return iostream
53
82
54
- # ContextVar must be used in multithreaded or async environments
55
- _default_io_stream : ContextVar [Optional ["IOStream" ]] = ContextVar ("default_iostream" )
56
- _default_io_stream .set (None )
57
-
58
83
@staticmethod
59
84
@contextmanager
60
85
def set_default (stream : Optional ["IOStream" ]) -> Iterator [None ]:
0 commit comments