diff --git a/stdlib/logging/__init__.pyi b/stdlib/logging/__init__.pyi index 8ed2f0b62417..6a8f66871a67 100644 --- a/stdlib/logging/__init__.pyi +++ b/stdlib/logging/__init__.pyi @@ -413,6 +413,8 @@ class LogRecord: sinfo: str | None = ..., ) -> None: ... def getMessage(self) -> str: ... + # Allows setting contextual information on LogRecord objects as per the docs, see #7833 + def __setattr__(self, __name: str, __value: Any) -> None: ... _L = TypeVar("_L", bound=Logger | LoggerAdapter[Any]) diff --git a/test_cases/stdlib/test_logging.py b/test_cases/stdlib/test_logging.py new file mode 100644 index 000000000000..dd572538fd4e --- /dev/null +++ b/test_cases/stdlib/test_logging.py @@ -0,0 +1,16 @@ +import logging +from typing import Any + +# This pattern comes from the logging docs, and should therefore pass a type checker +# See https://docs.python.org/3/library/logging.html#logrecord-objects + +old_factory = logging.getLogRecordFactory() + + +def record_factory(*args: Any, **kwargs: Any) -> logging.LogRecord: + record = old_factory(*args, **kwargs) + record.custom_attribute = 0xDECAFBAD + return record + + +logging.setLogRecordFactory(record_factory)