Skip to content

Commit 682639f

Browse files
committed
Provide logger class patching as a context manager
1 parent e502dc5 commit 682639f

File tree

2 files changed

+50
-52
lines changed

2 files changed

+50
-52
lines changed

pytest_reportportal/listener.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# This try/except can go away once we support pytest >= 3.3
99
import _pytest.logging
1010
PYTEST_HAS_LOGGING_PLUGIN = True
11-
from .rp_logging import RPLogHandler, patch_logger_class, unpatch_logger_class
11+
from .rp_logging import RPLogHandler, patching_logger_class
1212
except ImportError:
1313
PYTEST_HAS_LOGGING_PLUGIN = False
1414

@@ -17,6 +17,7 @@ class RPReportListener(object):
1717
def __init__(self, log_level=logging.NOTSET):
1818
# Test Item result
1919
self.result = None
20+
self._log_level = log_level
2021
if PYTEST_HAS_LOGGING_PLUGIN:
2122
self._log_handler = RPLogHandler(log_level, filter_reportportal_client_logs=True)
2223

@@ -25,13 +26,10 @@ def pytest_runtest_protocol(self, item):
2526
PyTestService.start_pytest_item(item)
2627
if PYTEST_HAS_LOGGING_PLUGIN:
2728
# This check can go away once we support pytest >= 3.3
28-
try:
29-
patch_logger_class()
29+
with patching_logger_class():
3030
with _pytest.logging.catching_logs(self._log_handler,
3131
level=self._log_level):
3232
yield
33-
finally:
34-
unpatch_logger_class()
3533
else:
3634
yield
3735
PyTestService.finish_pytest_item(self.result or 'SKIPPED')

pytest_reportportal/rp_logging.py

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sys
22
import logging
3+
from contextlib import contextmanager
34
from functools import wraps
45

56
from .service import PyTestService
@@ -84,51 +85,50 @@ def emit(self, record):
8485
)
8586

8687

87-
def patch_logger_class():
88+
@contextmanager
89+
def patching_logger_class():
8890
logger_class = logging.getLoggerClass()
89-
90-
def wrap_log(original_func):
91-
@wraps(original_func)
92-
def _log(self, *args, **kwargs):
93-
attachment = kwargs.pop('attachment', None)
94-
if attachment is not None:
95-
kwargs.setdefault('extra', {}).update({'attachment': attachment})
96-
return original_func(self, *args, **kwargs)
97-
return _log
98-
99-
def wrap_makeRecord(original_func):
100-
@wraps(original_func)
101-
def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
102-
func=None, extra=None, sinfo=None):
103-
if extra is not None:
104-
attachment = extra.pop('attachment', None)
105-
else:
106-
attachment = None
107-
try:
108-
# Python 3.5
109-
record = original_func(self, name, level, fn, lno, msg, args,
110-
exc_info, func=func, extra=extra,
111-
sinfo=sinfo)
112-
except TypeError:
113-
# Python 2.7
114-
record = original_func(self, name, level, fn, lno, msg, args,
115-
exc_info, func=func, extra=extra)
116-
record.attachment = attachment
117-
return record
118-
return makeRecord
119-
120-
# Store references to the original methods to allow unpatching
121-
setattr(logger_class, '_original__log', logger_class._log)
122-
logger_class._log = wrap_log(logger_class._log)
123-
setattr(logger_class, '_original_makeRecord', logger_class.makeRecord)
124-
logger_class.makeRecord = wrap_makeRecord(logger_class.makeRecord)
125-
126-
127-
def unpatch_logger_class():
128-
logger_class = logging.getLoggerClass()
129-
if hasattr(logger_class, '_original__log'):
130-
logger_class._log = logger_class._original__log
131-
delattr(logger_class, '_original__log')
132-
if hasattr(logger_class, '_original_makeRecord'):
133-
logger_class.makeRecord = logger_class._original_makeRecord
134-
delattr(logger_class, '_original_makeRecord')
91+
original_log = logger_class._log
92+
original_makeRecord = logger_class.makeRecord
93+
94+
try:
95+
def wrap_log(original_func):
96+
@wraps(original_func)
97+
def _log(self, *args, **kwargs):
98+
attachment = kwargs.pop('attachment', None)
99+
if attachment is not None:
100+
kwargs.setdefault('extra', {}).update(
101+
{'attachment': attachment})
102+
return original_func(self, *args, **kwargs)
103+
return _log
104+
105+
def wrap_makeRecord(original_func):
106+
@wraps(original_func)
107+
def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
108+
func=None, extra=None, sinfo=None):
109+
if extra is not None:
110+
attachment = extra.pop('attachment', None)
111+
else:
112+
attachment = None
113+
try:
114+
# Python 3.5
115+
record = original_func(self, name, level, fn, lno, msg,
116+
args, exc_info, func=func,
117+
extra=extra, sinfo=sinfo)
118+
except TypeError:
119+
# Python 2.7
120+
record = original_func(self, name, level, fn, lno, msg,
121+
args, exc_info, func=func,
122+
extra=extra)
123+
record.attachment = attachment
124+
return record
125+
return makeRecord
126+
127+
logger_class._log = wrap_log(logger_class._log)
128+
logger_class.makeRecord = wrap_makeRecord(logger_class.makeRecord)
129+
130+
yield
131+
132+
finally:
133+
logger_class._log = original_log
134+
logger_class.makeRecord = original_makeRecord

0 commit comments

Comments
 (0)