docstr: Handle a setup/call/teardown report, generating the appropriate
  XML tags as necessary.
  
  Note: due to plugins like xdist, this hook may be called in interlaced
  order with reports from other nodes. For example:
  
  Usual call order:
      -> setup node1
      -> call node1
      -> teardown node1
      -> setup node2
      -> call node2
      -> teardown node2
  
  Possible call order in xdist:
      -> setup node1
      -> call node1
      -> setup node2
      -> call node2
      -> teardown node2
      -> teardown node1
docstr_tok: ["Handle","a","setup\/call\/teardown","report",",","generating","the","appropriate","XML","tags","as","necessary",".","Note",":","due","to","plugins","like","xdist",",","this","hook","may","be","called","in","interlaced","order","with","reports","from","other","nodes",".","For","example",":","Usual","call","order",":","-",">","setup","node1","-",">","call","node1","-",">","teardown","node1","-",">","setup","node2","-",">","call","node2","-",">","teardown","node2","Possible","call","order","in","xdist",":","-",">","setup","node1","-",">","call","node1","-",">","setup","node2","-",">","call","node2","-",">","teardown","node2","-",">","teardown","node1"]
code: def pytest_runtest_logreport(self, report: TestReport) -> None:
      """Handle a setup/call/teardown report, generating the appropriate
      XML tags as necessary.
  
      Note: due to plugins like xdist, this hook may be called in interlaced
      order with reports from other nodes. For example:
  
      Usual call order:
          -> setup node1
          -> call node1
          -> teardown node1
          -> setup node2
          -> call node2
          -> teardown node2
  
      Possible call order in xdist:
          -> setup node1
          -> call node1
          -> setup node2
          -> call node2
          -> teardown node2
          -> teardown node1
      """
      close_report = None
      if report.passed:
          if report.when == "call":  # ignore setup/teardown
              reporter = self._opentestcase(report)
              reporter.append_pass(report)
      elif report.failed:
          if report.when == "teardown":
              # The following vars are needed when xdist plugin is used.
              report_wid = getattr(report, "worker_id", None)
              report_ii = getattr(report, "item_index", None)
              close_report = next(
                  (
                      rep
                      for rep in self.open_reports
                      if (
                          rep.nodeid == report.nodeid
                          and getattr(rep, "item_index", None)
                          == report_ii
                          and getattr(rep, "worker_id", None)
                          == report_wid
                      )
                  ),
                  None,
              )
              if close_report:
                  # We need to open new testcase in case we have failure in
                  # call and error in teardown in order to follow junit
                  # schema.
                  self.finalize(close_report)
                  self.cnt_double_fail_tests += 1
          reporter = self._opentestcase(report)
          if report.when == "call":
              reporter.append_failure(report)
              self.open_reports.append(report)
              if not self.log_passing_tests:
                  reporter.write_captured_output(report)
          else:
              reporter.append_error(report)
      elif report.skipped:
          reporter = self._opentestcase(report)
          reporter.append_skipped(report)
      self.update_testcase_duration(report)
      if report.when == "teardown":
          reporter = self._opentestcase(report)
          reporter.write_captured_output(report)
  
          self.finalize(report)
          report_wid = getattr(report, "worker_id", None)
          report_ii = getattr(report, "item_index", None)
          close_report = next(
              (
                  rep
                  for rep in self.open_reports
                  if (
                      rep.nodeid == report.nodeid
                      and getattr(rep, "item_index", None) == report_ii
                      and getattr(rep, "worker_id", None) == report_wid
                  )
              ),
              None,
          )
          if close_report:
              self.open_reports.remove(close_report)
  
imports: import functools
  import os
  import platform
  import re
  import xml.etree.ElementTree
  from datetime import datetime
  from typing import Callable
  from typing import Dict
  from typing import List
  from typing import Match
  from typing import Optional
  from typing import Tuple
  from typing import Union
  import pytest
  from _pytest import nodes
  from _pytest import timing
  from _pytest._code.code import ExceptionRepr
  from _pytest._code.code import ReprFileLocation
  from _pytest.config import Config
  from _pytest.config import filename_arg
  from _pytest.config.argparsing import Parser
  from _pytest.fixtures import FixtureRequest
  from _pytest.reports import TestReport
  from _pytest.stash import StashKey
  from _pytest.terminal import TerminalReporter
label_desc: Use image node_id 6 for calling the LogXML obj's underlying member method code with example usage: obj.pytest_runtest_logreport(report) without return types