You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
caplog.get_records and caplog.clear conflict #9877
caplog.get_records() gets decoupled from actual caplog records when caplog.clear() is called. As a result, after caplog.clear() is called, caplog.get_records() is frozen: it does not get cleared, nor does it get new records.
It seems that when setup/call/teardown stage begin, will init a stage log records stash, which used in LogCaptureFixture.get_records,
but after LogCaptureFixture.clear, the stage records in stash not be reset
I tried to fix with the following changed
# _pytest/logging.pydef_runtest_for(self, item: nodes.Item, when: str) ->Generator[None, None, None]:
"""Implement the internals of the pytest_runtest_xxx() hooks."""withcatching_logs(
self.caplog_handler,
level=self.log_level,
) ascaplog_handler, catching_logs(
self.report_handler,
level=self.log_level,
) asreport_handler:
caplog_handler.reset()
caplog_handler.set_when(when) # Add "when" property to LogCaptureHandler, set stage in runtestreport_handler.reset()
item.stash[caplog_records_key][when] =caplog_handler.recordsitem.stash[caplog_handler_key] =caplog_handleryieldlog=report_handler.stream.getvalue().strip()
item.add_report_section(when, "log", log)
# _pytest/logging.pydefclear(self) ->None:
"""Reset the list of log records and the captured log text."""self.handler.reset()
self._item.stash[caplog_records_key][self.handler.when] =self.records# consistent with records after clear
It's not really clear to me why you added the set_when line, but that's probably just my inexperience with this codebase. The other line you added seems to address the issue I raised, though I am wondering if it might not be simpler to just add a layer of indirection: instead of storing List[logging.LogRecord], store LogCaptureHandler, then dynamically fetch the records when requested. It would have the advantage that the state is always consistent, and nothing needs to be rebound on clear. Again, I'm really not familiar with this code base so I might be missing something.
My understanding is StashKey[Dict[str, List[logging.LogRecord]]]() is used to storage caplog record in different stage(setup/call/teardown), but when caplog.clear() in stage, LogCaptureFixture can't know which stage caplog to clear. So I added set_when to fix it.
Can you share more details about the suggestion "instead of storing List[logging.LogRecord], store LogCaptureHandler "?
I see, thanks for the explanation, that makes sense.
While typing out a clarification of what I meant with my suggestion I realized I was missing something and it makes little sense. You can safely ignore that part.
caplog_handler.reset() set LogCaptureHandler.records a new list object, which lost bind to item.stash
As each running stage use one caplog_handler object and it's records object reference in item.stash item.stash[caplog_records_key][when] = caplog_handler.records. So after clear, any log records can not be captured to item.stash
Use self.records.clear() instead of self.records = [] when caplog.clear() to fix it
Activity
Fix stage caplog records not clear
EmptyRabbit commentedon Jun 15, 2022
I would like to fix this issue
It seems that when setup/call/teardown stage begin, will init a stage log records stash, which used in
LogCaptureFixture.get_records,but after
LogCaptureFixture.clear, the stage records in stash not be resetI tried to fix with the following changed
Fix stage caplog records not clear
Fix stage caplog records not clear
Fix stage caplog records not clear
Fix stage caplog records not clear
sanderr commentedon Jun 17, 2022
It's not really clear to me why you added the
set_whenline, but that's probably just my inexperience with this codebase. The other line you added seems to address the issue I raised, though I am wondering if it might not be simpler to just add a layer of indirection: instead of storingList[logging.LogRecord], storeLogCaptureHandler, then dynamically fetch the records when requested. It would have the advantage that the state is always consistent, and nothing needs to be rebound on clear. Again, I'm really not familiar with this code base so I might be missing something.EmptyRabbit commentedon Jun 20, 2022
My understanding is
StashKey[Dict[str, List[logging.LogRecord]]]()is used to storage caplog record in different stage(setup/call/teardown), but whencaplog.clear()in stage,LogCaptureFixturecan't know which stage caplog to clear. So I addedset_whento fix it.Can you share more details about the suggestion "instead of storing
List[logging.LogRecord], storeLogCaptureHandler"?sanderr commentedon Jun 20, 2022
I see, thanks for the explanation, that makes sense.
While typing out a clarification of what I meant with my suggestion I realized I was missing something and it makes little sense. You can safely ignore that part.
Fix stage caplog records not clear
EmptyRabbit commentedon Jul 5, 2022
Update root cause and fix
caplog_handler.reset()set LogCaptureHandler.records a new list object, which lost bind to item.stashAs each running stage use one caplog_handler object and it's records object reference in item.stash
item.stash[caplog_records_key][when] = caplog_handler.records. So after clear, any log records can not be captured to item.stashUse
self.records.clear()instead ofself.records = []whencaplog.clear()to fix itchore(deps): update dependency pytest to v7 (#3)
Fix stage caplog records not clear
Fix stage caplog records not clear