1111from io import StringIO
1212from logging import LogRecord
1313from pathlib import Path
14+ from types import TracebackType
1415from typing import AbstractSet
1516from typing import Dict
1617from typing import final
1718from typing import Generator
19+ from typing import Generic
1820from typing import List
1921from typing import Literal
2022from typing import Mapping
2123from typing import Optional
2224from typing import Tuple
25+ from typing import Type
2326from typing import TYPE_CHECKING
2427from typing import TypeVar
2528from typing import Union
@@ -62,7 +65,7 @@ class DatetimeFormatter(logging.Formatter):
6265 :func:`time.strftime` in case of microseconds in format string.
6366 """
6467
65- def formatTime (self , record : LogRecord , datefmt = None ) -> str :
68+ def formatTime (self , record : LogRecord , datefmt : Optional [ str ] = None ) -> str :
6669 if datefmt and "%f" in datefmt :
6770 ct = self .converter (record .created )
6871 tz = timezone (timedelta (seconds = ct .tm_gmtoff ), ct .tm_zone )
@@ -331,7 +334,7 @@ def add_option_ini(option, dest, default=None, type=None, **kwargs):
331334
332335
333336# Not using @contextmanager for performance reasons.
334- class catching_logs :
337+ class catching_logs ( Generic [ _HandlerType ]) :
335338 """Context manager that prepares the whole logging machinery properly."""
336339
337340 __slots__ = ("handler" , "level" , "orig_level" )
@@ -340,7 +343,7 @@ def __init__(self, handler: _HandlerType, level: Optional[int] = None) -> None:
340343 self .handler = handler
341344 self .level = level
342345
343- def __enter__ (self ):
346+ def __enter__ (self ) -> _HandlerType :
344347 root_logger = logging .getLogger ()
345348 if self .level is not None :
346349 self .handler .setLevel (self .level )
@@ -350,7 +353,12 @@ def __enter__(self):
350353 root_logger .setLevel (min (self .orig_level , self .level ))
351354 return self .handler
352355
353- def __exit__ (self , type , value , traceback ):
356+ def __exit__ (
357+ self ,
358+ exc_type : Optional [Type [BaseException ]],
359+ exc_val : Optional [BaseException ],
360+ exc_tb : Optional [TracebackType ],
361+ ) -> None :
354362 root_logger = logging .getLogger ()
355363 if self .level is not None :
356364 root_logger .setLevel (self .orig_level )
@@ -421,7 +429,7 @@ def handler(self) -> LogCaptureHandler:
421429 return self ._item .stash [caplog_handler_key ]
422430
423431 def get_records (
424- self , when : " Literal[' setup', ' call', ' teardown']"
432+ self , when : Literal [" setup" , " call" , " teardown" ]
425433 ) -> List [logging .LogRecord ]:
426434 """Get the logging records for one of the possible test phases.
427435
@@ -742,7 +750,7 @@ def set_log_path(self, fname: str) -> None:
742750 if old_stream :
743751 old_stream .close ()
744752
745- def _log_cli_enabled (self ):
753+ def _log_cli_enabled (self ) -> bool :
746754 """Return whether live logging is enabled."""
747755 enabled = self ._config .getoption (
748756 "--log-cli-level"
0 commit comments