https://docs.python.org/3/library/logging.html#logrecord-objects gives the following pattern for adding contextual information to LogRecord objects which can then be used in log formats:
old_factory=logging.getLogRecordFactory()
defrecord_factory(*args, **kwargs):
record=old_factory(*args, **kwargs)
record.custom_attribute=0xdecafbadreturnrecordlogging.setLogRecordFactory(record_factory)
However, if you use this pattern and run mypy, you'll get an error like error: "LogRecord" has no attribute "custom_attribute". You can get around this error by using setattr(record, "custom_attribute", 0xdecafbad) instead of record.custom_attribute = 0xdecafbad.
Should the stub for the LogRecord class define a __setattr__ method because this sort of usage of assigning to arbitrary attributes is expected for the LogRecord class? Would that have undesirable side effects?
Here is a complete example:
importloggingcustom_contextual_data="XYZ"defmain() ->None:
logging.basicConfig(
format="[%(asctime)s] [%(custom_contextual_data)s] [%(name)s] %(levelname)s: %(message)s", level=logging.DEBUG
)
old_factory=logging.getLogRecordFactory()
defrecord_factory(*args: object, **kwargs: object) ->logging.LogRecord:
globalcustom_contextual_datarecord=old_factory(*args, **kwargs)
# mypy: error: "LogRecord" has no attribute "custom_contextual_data"record.custom_contextual_data=custom_contextual_data# mypy: no error# setattr(record, "custom_contextual_data", custom_contextual_data)returnrecordlogging.setLogRecordFactory(record_factory)
logger=logging.getLogger(__name__)
logger.info("Hello XYZ world!")
globalcustom_contextual_datacustom_contextual_data="ABC"logger.info("Hello ABC world!")
if__name__=="__main__":
main()mypy.ini:
[mypy]
files = mypy_log_record_repro/
strict_equality = True
disallow_untyped_defs = True
disallow_untyped_calls = True
disallow_untyped_decorators = True
no_implicit_optional = True
strict_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_no_return = True
warn_return_any = True
warn_unreachable = True
https://docs.python.org/3/library/logging.html#logrecord-objects gives the following pattern for adding contextual information to LogRecord objects which can then be used in log formats:
However, if you use this pattern and run mypy, you'll get an error like
error: "LogRecord" has no attribute "custom_attribute". You can get around this error by usingsetattr(record, "custom_attribute", 0xdecafbad)instead ofrecord.custom_attribute = 0xdecafbad.Should the stub for the
LogRecordclass define a__setattr__method because this sort of usage of assigning to arbitrary attributes is expected for theLogRecordclass? Would that have undesirable side effects?Here is a complete example:
mypy.ini: