8
8
from dataclasses import dataclass
9
9
from io import TextIOWrapper
10
10
from logging import Filter
11
- from typing import Any , ClassVar , Generator , List , Optional , TextIO , Type
11
+ from typing import Any , ClassVar , Generator , List , Optional , Type
12
12
13
13
from pip ._vendor .rich .console import (
14
14
Console ,
29
29
from pip ._internal .utils .misc import ensure_dir
30
30
31
31
_log_state = threading .local ()
32
+ _stdout_console = None
33
+ _stderr_console = None
32
34
subprocess_logger = getLogger ("pip.subprocessor" )
33
35
34
36
@@ -144,12 +146,21 @@ def on_broken_pipe(self) -> None:
144
146
raise BrokenPipeError () from None
145
147
146
148
149
+ def get_console (* , stderr : bool = False ) -> Console :
150
+ if stderr :
151
+ assert _stderr_console is not None , "stderr rich console is missing!"
152
+ return _stderr_console
153
+ else :
154
+ assert _stdout_console is not None , "stdout rich console is missing!"
155
+ return _stdout_console
156
+
157
+
147
158
class RichPipStreamHandler (RichHandler ):
148
159
KEYWORDS : ClassVar [Optional [List [str ]]] = []
149
160
150
- def __init__ (self , stream : Optional [ TextIO ], no_color : bool ) -> None :
161
+ def __init__ (self , console : Console ) -> None :
151
162
super ().__init__ (
152
- console = PipConsole ( file = stream , no_color = no_color , soft_wrap = True ) ,
163
+ console = console ,
153
164
show_time = False ,
154
165
show_level = False ,
155
166
show_path = False ,
@@ -266,17 +277,16 @@ def setup_logging(verbosity: int, no_color: bool, user_log_file: Optional[str])
266
277
vendored_log_level = "WARNING" if level in ["INFO" , "ERROR" ] else "DEBUG"
267
278
268
279
# Shorthands for clarity
269
- log_streams = {
270
- "stdout" : "ext://sys.stdout" ,
271
- "stderr" : "ext://sys.stderr" ,
272
- }
273
280
handler_classes = {
274
281
"stream" : "pip._internal.utils.logging.RichPipStreamHandler" ,
275
282
"file" : "pip._internal.utils.logging.BetterRotatingFileHandler" ,
276
283
}
277
284
handlers = ["console" , "console_errors" , "console_subprocess" ] + (
278
285
["user_log" ] if include_user_log else []
279
286
)
287
+ global _stdout_console , stderr_console
288
+ _stdout_console = PipConsole (file = sys .stdout , no_color = no_color , soft_wrap = True )
289
+ _stderr_console = PipConsole (file = sys .stderr , no_color = no_color , soft_wrap = True )
280
290
281
291
logging .config .dictConfig (
282
292
{
@@ -311,16 +321,14 @@ def setup_logging(verbosity: int, no_color: bool, user_log_file: Optional[str])
311
321
"console" : {
312
322
"level" : level ,
313
323
"class" : handler_classes ["stream" ],
314
- "no_color" : no_color ,
315
- "stream" : log_streams ["stdout" ],
324
+ "console" : _stdout_console ,
316
325
"filters" : ["exclude_subprocess" , "exclude_warnings" ],
317
326
"formatter" : "indent" ,
318
327
},
319
328
"console_errors" : {
320
329
"level" : "WARNING" ,
321
330
"class" : handler_classes ["stream" ],
322
- "no_color" : no_color ,
323
- "stream" : log_streams ["stderr" ],
331
+ "console" : _stderr_console ,
324
332
"filters" : ["exclude_subprocess" ],
325
333
"formatter" : "indent" ,
326
334
},
@@ -329,8 +337,7 @@ def setup_logging(verbosity: int, no_color: bool, user_log_file: Optional[str])
329
337
"console_subprocess" : {
330
338
"level" : level ,
331
339
"class" : handler_classes ["stream" ],
332
- "stream" : log_streams ["stderr" ],
333
- "no_color" : no_color ,
340
+ "console" : _stderr_console ,
334
341
"filters" : ["restrict_to_subprocess" ],
335
342
"formatter" : "indent" ,
336
343
},
0 commit comments