@@ -1410,101 +1410,3 @@ def filter_params(params, **kwargs):
14101410 params [new_param ] = params .pop (old_param )
14111411
14121412 return params
1413-
1414-
1415- def is_docker () -> bool :
1416- path = '/proc/self/cgroup'
1417- return os .path .exists ('/.dockerenv' ) or (os .path .isfile (path ) and any ('docker' in line for line in open (path )))
1418-
1419-
1420- def stream_supports_colour (stream : Any ) -> bool :
1421- is_a_tty = hasattr (stream , 'isatty' ) and stream .isatty ()
1422-
1423- # Pycharm and Vscode support colour in their inbuilt editors
1424- if 'PYCHARM_HOSTED' in os .environ or os .environ .get ('TERM_PROGRAM' ) == 'vscode' :
1425- return is_a_tty
1426-
1427- if sys .platform != 'win32' :
1428- # Docker does not consistently have a tty attached to it
1429- return is_a_tty or is_docker ()
1430-
1431- # ANSICON checks for things like ConEmu
1432- # WT_SESSION checks if this is Windows Terminal
1433- return is_a_tty and ('ANSICON' in os .environ or 'WT_SESSION' in os .environ )
1434-
1435-
1436- class _ColourFormatter (logging .Formatter ):
1437- # ANSI codes are a bit weird to decipher if you're unfamiliar with them, so here's a refresher
1438- # It starts off with a format like \x1b[XXXm where XXX is a semicolon separated list of commands
1439- # The important ones here relate to colour.
1440- # 30-37 are black, red, green, yellow, blue, magenta, cyan and white in that order
1441- # 40-47 are the same except for the background
1442- # 90-97 are the same but "bright" foreground
1443- # 100-107 are the same as the bright ones but for the background.
1444- # 1 means bold, 2 means dim, 0 means reset, and 4 means underline.
1445-
1446- LEVEL_COLOURS = [
1447- (logging .DEBUG , '\x1b [40;1m' ),
1448- (logging .INFO , '\x1b [34;1m' ),
1449- (logging .WARNING , '\x1b [33;1m' ),
1450- (logging .ERROR , '\x1b [31m' ),
1451- (logging .CRITICAL , '\x1b [41m' ),
1452- ]
1453-
1454- FORMATS = {
1455- level : logging .Formatter (
1456- f'\x1b [30;1m%(asctime)s\x1b [0m { colour } %(levelname)-8s\x1b [0m \x1b [35m%(name)s\x1b [0m %(message)s' ,
1457- '%Y-%m-%d %H:%M:%S' ,
1458- )
1459- for level , colour in LEVEL_COLOURS
1460- }
1461-
1462- def format (self , record ):
1463- formatter = self .FORMATS .get (record .levelno )
1464- if formatter is None :
1465- formatter = self .FORMATS [logging .DEBUG ]
1466-
1467- # Override the traceback to always print in red
1468- if record .exc_info :
1469- text = formatter .formatException (record .exc_info )
1470- record .exc_text = f'\x1b [31m{ text } \x1b [0m'
1471-
1472- output = formatter .format (record )
1473-
1474- # Remove the cache layer
1475- record .exc_text = None
1476- return output
1477-
1478-
1479- def setup_logging (
1480- * ,
1481- handler : logging .Handler = MISSING ,
1482- formatter : logging .Formatter = MISSING ,
1483- level : int = MISSING ,
1484- root : bool = True ,
1485- ) -> None :
1486- """A helper method to automatically setup the library's default logging.
1487- """
1488-
1489- if level is MISSING :
1490- level = logging .INFO
1491-
1492- if handler is MISSING :
1493- handler = logging .StreamHandler ()
1494-
1495- if formatter is MISSING :
1496- if isinstance (handler , logging .StreamHandler ) and stream_supports_colour (handler .stream ):
1497- formatter = _ColourFormatter ()
1498- else :
1499- dt_fmt = '%Y-%m-%d %H:%M:%S'
1500- formatter = logging .Formatter ('[{asctime}] [{levelname:<8}] {name}: {message}' , dt_fmt , style = '{' )
1501-
1502- if root :
1503- logger = logging .getLogger ()
1504- else :
1505- lib , _ , _ = __name__ .partition ('.' )
1506- logger = logging .getLogger (lib )
1507-
1508- handler .setFormatter (formatter )
1509- logger .setLevel (level )
1510- logger .addHandler (handler )
0 commit comments