88from dataclasses import dataclass
99from io import TextIOWrapper
1010from logging import Filter
11- from typing import Any , ClassVar , Generator , List , Optional , TextIO , Type
11+ from typing import Any , ClassVar , Generator , List , Optional , Type
1212
1313from pip ._vendor .rich .console import (
1414 Console ,
2929from pip ._internal .utils .misc import ensure_dir
3030
3131_log_state = threading .local ()
32+ _stdout_console = None
33+ _stderr_console = None
3234subprocess_logger = getLogger ("pip.subprocessor" )
3335
3436
@@ -144,12 +146,21 @@ def on_broken_pipe(self) -> None:
144146 raise BrokenPipeError () from None
145147
146148
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+
147158class RichPipStreamHandler (RichHandler ):
148159 KEYWORDS : ClassVar [Optional [List [str ]]] = []
149160
150- def __init__ (self , stream : Optional [ TextIO ], no_color : bool ) -> None :
161+ def __init__ (self , console : Console ) -> None :
151162 super ().__init__ (
152- console = PipConsole ( file = stream , no_color = no_color , soft_wrap = True ) ,
163+ console = console ,
153164 show_time = False ,
154165 show_level = False ,
155166 show_path = False ,
@@ -266,17 +277,16 @@ def setup_logging(verbosity: int, no_color: bool, user_log_file: Optional[str])
266277 vendored_log_level = "WARNING" if level in ["INFO" , "ERROR" ] else "DEBUG"
267278
268279 # Shorthands for clarity
269- log_streams = {
270- "stdout" : "ext://sys.stdout" ,
271- "stderr" : "ext://sys.stderr" ,
272- }
273280 handler_classes = {
274281 "stream" : "pip._internal.utils.logging.RichPipStreamHandler" ,
275282 "file" : "pip._internal.utils.logging.BetterRotatingFileHandler" ,
276283 }
277284 handlers = ["console" , "console_errors" , "console_subprocess" ] + (
278285 ["user_log" ] if include_user_log else []
279286 )
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 )
280290
281291 logging .config .dictConfig (
282292 {
@@ -311,16 +321,14 @@ def setup_logging(verbosity: int, no_color: bool, user_log_file: Optional[str])
311321 "console" : {
312322 "level" : level ,
313323 "class" : handler_classes ["stream" ],
314- "no_color" : no_color ,
315- "stream" : log_streams ["stdout" ],
324+ "console" : _stdout_console ,
316325 "filters" : ["exclude_subprocess" , "exclude_warnings" ],
317326 "formatter" : "indent" ,
318327 },
319328 "console_errors" : {
320329 "level" : "WARNING" ,
321330 "class" : handler_classes ["stream" ],
322- "no_color" : no_color ,
323- "stream" : log_streams ["stderr" ],
331+ "console" : _stderr_console ,
324332 "filters" : ["exclude_subprocess" ],
325333 "formatter" : "indent" ,
326334 },
@@ -329,8 +337,7 @@ def setup_logging(verbosity: int, no_color: bool, user_log_file: Optional[str])
329337 "console_subprocess" : {
330338 "level" : level ,
331339 "class" : handler_classes ["stream" ],
332- "stream" : log_streams ["stderr" ],
333- "no_color" : no_color ,
340+ "console" : _stderr_console ,
334341 "filters" : ["restrict_to_subprocess" ],
335342 "formatter" : "indent" ,
336343 },
0 commit comments