mirror of https://github.com/streamlink/streamlink
logger: remove deprecated compat logger
- remove old Logger and LoggerModule classes - remove old {,Compat}LogRecord classes - remove deprecated and unneeded methods from StreamlinkLogger - remove usage of old Logger from Session - remove session reference from ConsoleOutput
This commit is contained in:
parent
b4c89f57c2
commit
9ac40cb075
|
@ -1,6 +1,4 @@
|
|||
import logging
|
||||
import sys
|
||||
import warnings
|
||||
from logging import NOTSET, ERROR, WARN, INFO, DEBUG, CRITICAL
|
||||
from threading import Lock
|
||||
|
||||
|
@ -17,72 +15,11 @@ levels = [name for _, name in _levelToName.items()]
|
|||
_config_lock = Lock()
|
||||
|
||||
|
||||
class _CompatLogRecord(logging.LogRecord):
|
||||
"""
|
||||
LogRecord wrapper to include sinfo for Python 3 by not Python 2
|
||||
"""
|
||||
|
||||
def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None, **kwargs):
|
||||
super(_CompatLogRecord, self).__init__(name, level, pathname, lineno, msg, args, exc_info, func=func,
|
||||
sinfo=sinfo, **kwargs)
|
||||
|
||||
|
||||
class _LogRecord(_CompatLogRecord):
|
||||
def getMessage(self):
|
||||
"""
|
||||
Return the message for this LogRecord.
|
||||
|
||||
Return the message for this LogRecord after merging any user-supplied
|
||||
arguments with the message.
|
||||
"""
|
||||
msg = self.msg
|
||||
if self.args:
|
||||
msg = msg.format(*self.args)
|
||||
return msg
|
||||
|
||||
|
||||
class StreamlinkLogger(logging.getLoggerClass(), object):
|
||||
def __init__(self, name, level=logging.NOTSET):
|
||||
super(StreamlinkLogger, self).__init__(name, level)
|
||||
|
||||
class StreamlinkLogger(logging.getLoggerClass()):
|
||||
def trace(self, message, *args, **kws):
|
||||
if self.isEnabledFor(TRACE):
|
||||
self._log(TRACE, message, args, **kws)
|
||||
|
||||
def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
|
||||
func=None, extra=None, sinfo=None):
|
||||
"""
|
||||
A factory method which can be overridden in subclasses to create
|
||||
specialized LogRecords.
|
||||
"""
|
||||
if name.startswith("streamlink"):
|
||||
rv = _LogRecord(name, level, fn, lno, msg, args, exc_info, func, sinfo)
|
||||
else:
|
||||
rv = _CompatLogRecord(name, level, fn, lno, msg, args, exc_info, func, sinfo)
|
||||
if extra is not None:
|
||||
for key in extra:
|
||||
if (key in ["message", "asctime"]) or (key in rv.__dict__):
|
||||
raise KeyError("Attempt to overwrite %r in LogRecord" % key)
|
||||
rv.__dict__[key] = extra[key]
|
||||
return rv
|
||||
|
||||
def set_level(self, level):
|
||||
self.setLevel(level)
|
||||
|
||||
@staticmethod
|
||||
def new_module(name):
|
||||
warnings.warn("Logger.new_module has been deprecated, use the standard logging.getLogger method",
|
||||
category=DeprecationWarning, stacklevel=2)
|
||||
return logging.getLogger("streamlink.{0}".format(name))
|
||||
|
||||
@staticmethod
|
||||
def set_output(output):
|
||||
"""
|
||||
No-op, must be set in the log handler
|
||||
"""
|
||||
warnings.warn("Logger.set_output has been deprecated, use the standard logging module",
|
||||
category=DeprecationWarning, stacklevel=2)
|
||||
|
||||
|
||||
logging.setLoggerClass(StreamlinkLogger)
|
||||
root = logging.getLogger("streamlink")
|
||||
|
@ -130,59 +67,6 @@ class StringFormatter(logging.Formatter):
|
|||
return s
|
||||
|
||||
|
||||
class Logger(object):
|
||||
Levels = levels
|
||||
Format = "[{name}][{levelname}] {message}"
|
||||
root_name = "streamlink_old"
|
||||
|
||||
def __init__(self):
|
||||
warnings.warn("Logger class has been deprecated, use the standard logging module",
|
||||
category=DeprecationWarning, stacklevel=2)
|
||||
self.root = logging.getLogger(self.root_name)
|
||||
root.propagate = False
|
||||
self.handler = logging.StreamHandler(sys.stdout)
|
||||
self.handler.setFormatter(StringFormatter(self.Format, style="{", remove_base=[self.root_name]))
|
||||
self.root.addHandler(self.handler)
|
||||
self.set_level("info")
|
||||
|
||||
@classmethod
|
||||
def get_logger(cls, name):
|
||||
return logging.getLogger("{0}.{1}".format(cls.root_name, name))
|
||||
|
||||
def new_module(self, module):
|
||||
return LoggerModule(self, module)
|
||||
|
||||
def set_level(self, level):
|
||||
self.root.setLevel(level)
|
||||
|
||||
def set_output(self, output):
|
||||
self.handler.stream = output
|
||||
|
||||
def msg(self, module, level, msg, *args, **kwargs):
|
||||
log = self.get_logger(module)
|
||||
log.log(level, msg, *args)
|
||||
|
||||
|
||||
class LoggerModule(object):
|
||||
def __init__(self, manager, module):
|
||||
warnings.warn("LoggerModule class has been deprecated, use the standard logging module",
|
||||
category=DeprecationWarning, stacklevel=2)
|
||||
self.manager = manager
|
||||
self.module = module
|
||||
|
||||
def error(self, msg, *args, **kwargs):
|
||||
self.manager.msg(self.module, ERROR, msg, *args, **kwargs)
|
||||
|
||||
def warning(self, msg, *args, **kwargs):
|
||||
self.manager.msg(self.module, WARN, msg, *args, **kwargs)
|
||||
|
||||
def info(self, msg, *args, **kwargs):
|
||||
self.manager.msg(self.module, INFO, msg, *args, **kwargs)
|
||||
|
||||
def debug(self, msg, *args, **kwargs):
|
||||
self.manager.msg(self.module, DEBUG, msg, *args, **kwargs)
|
||||
|
||||
|
||||
BASIC_FORMAT = "[{name}][{levelname}] {message}"
|
||||
FORMAT_STYLE = "{"
|
||||
REMOVE_BASE = ["streamlink", "streamlink_cli"]
|
||||
|
@ -211,4 +95,4 @@ def basicConfig(**kwargs):
|
|||
root.setLevel(level)
|
||||
|
||||
|
||||
__all__ = ["StreamlinkLogger", "Logger", "basicConfig", "root", "levels"]
|
||||
__all__ = ["StreamlinkLogger", "basicConfig", "root", "levels"]
|
||||
|
|
|
@ -8,7 +8,7 @@ import requests
|
|||
|
||||
from collections import OrderedDict
|
||||
|
||||
from streamlink.logger import StreamlinkLogger, Logger
|
||||
from streamlink.logger import StreamlinkLogger
|
||||
from streamlink.utils import update_scheme, memoize
|
||||
from streamlink.utils.l10n import Localization
|
||||
from . import plugins, __version__
|
||||
|
@ -89,17 +89,6 @@ class Streamlink(object):
|
|||
self.options.update(options)
|
||||
self.plugins = OrderedDict({})
|
||||
self.load_builtin_plugins()
|
||||
self._logger = None
|
||||
|
||||
@property
|
||||
def logger(self):
|
||||
"""
|
||||
Backwards compatible logger property
|
||||
:return: Logger instance
|
||||
"""
|
||||
if not self._logger:
|
||||
self._logger = Logger()
|
||||
return self._logger
|
||||
|
||||
def set_option(self, key, value):
|
||||
"""Sets general options used by plugins and streams originating
|
||||
|
@ -367,25 +356,6 @@ class Streamlink(object):
|
|||
plugin = self.plugins[plugin]
|
||||
return plugin.get_option(key)
|
||||
|
||||
def set_loglevel(self, level):
|
||||
"""Sets the log level used by this session.
|
||||
|
||||
Valid levels are: "none", "error", "warning", "info"
|
||||
and "debug".
|
||||
|
||||
:param level: level of logging to output
|
||||
|
||||
"""
|
||||
self.logger.set_level(level)
|
||||
|
||||
def set_logoutput(self, output):
|
||||
"""Sets the log output used by this session.
|
||||
|
||||
:param output: a file-like object with a write method
|
||||
|
||||
"""
|
||||
self.logger.set_output(output)
|
||||
|
||||
@memoize
|
||||
def resolve_url(self, url, follow_redirect=True):
|
||||
"""Attempts to find a plugin that can use this URL.
|
||||
|
|
|
@ -30,15 +30,10 @@ class ConsoleUserInputRequester(UserInputRequester):
|
|||
|
||||
|
||||
class ConsoleOutput(object):
|
||||
def __init__(self, output, streamlink, json=False):
|
||||
self.streamlink = streamlink
|
||||
|
||||
def __init__(self, output, json=False):
|
||||
self.json = json
|
||||
self.output = output
|
||||
|
||||
def set_level(self, level):
|
||||
self.streamlink.set_loglevel(level)
|
||||
|
||||
def set_output(self, output):
|
||||
self.output = output
|
||||
|
||||
|
|
|
@ -691,8 +691,7 @@ def setup_console(output):
|
|||
global console
|
||||
|
||||
# All console related operations is handled via the ConsoleOutput class
|
||||
console = ConsoleOutput(output, streamlink)
|
||||
console.json = args.json
|
||||
console = ConsoleOutput(output, args.json)
|
||||
|
||||
# Handle SIGTERM just like SIGINT
|
||||
signal.signal(signal.SIGTERM, signal.default_int_handler)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from io import StringIO
|
||||
import unittest
|
||||
from unittest.mock import Mock, patch
|
||||
from unittest.mock import patch
|
||||
|
||||
from streamlink_cli.console import ConsoleOutput
|
||||
|
||||
|
@ -13,41 +13,41 @@ class _TestObj(object):
|
|||
class TestConsole(unittest.TestCase):
|
||||
def test_msg_format(self):
|
||||
output = StringIO()
|
||||
console = ConsoleOutput(output, Mock())
|
||||
console = ConsoleOutput(output)
|
||||
console.msg("{0} - {1}", 1, 2)
|
||||
|
||||
self.assertEqual("1 - 2\n", output.getvalue())
|
||||
|
||||
def test_msg_format_kw(self):
|
||||
output = StringIO()
|
||||
console = ConsoleOutput(output, Mock())
|
||||
console = ConsoleOutput(output)
|
||||
console.msg("{test} - {what}", test=1, what=2)
|
||||
|
||||
self.assertEqual("1 - 2\n", output.getvalue())
|
||||
|
||||
def test_msg_json_not_set(self):
|
||||
output = StringIO()
|
||||
console = ConsoleOutput(output, Mock())
|
||||
console = ConsoleOutput(output)
|
||||
self.assertEqual(None, console.msg_json({"test": 1}))
|
||||
self.assertEqual("", output.getvalue())
|
||||
|
||||
def test_msg_json(self):
|
||||
output = StringIO()
|
||||
console = ConsoleOutput(output, Mock(), json=True)
|
||||
console = ConsoleOutput(output, json=True)
|
||||
console.msg_json({"test": 1})
|
||||
self.assertEqual('''{\n "test": 1\n}\n''', output.getvalue())
|
||||
|
||||
def test_msg_json_object(self):
|
||||
output = StringIO()
|
||||
test_obj = _TestObj()
|
||||
console = ConsoleOutput(output, Mock(), json=True)
|
||||
console = ConsoleOutput(output, json=True)
|
||||
console.msg_json(test_obj)
|
||||
self.assertEqual('''{\n "test": 1\n}\n''', output.getvalue())
|
||||
|
||||
@patch('streamlink_cli.console.sys.exit')
|
||||
def test_msg_json_error(self, mock_exit):
|
||||
output = StringIO()
|
||||
console = ConsoleOutput(output, Mock(), json=True)
|
||||
console = ConsoleOutput(output, json=True)
|
||||
console.msg_json({"error": "bad"})
|
||||
self.assertEqual('''{\n "error": "bad"\n}\n''', output.getvalue())
|
||||
mock_exit.assert_called_with(1)
|
||||
|
@ -55,7 +55,7 @@ class TestConsole(unittest.TestCase):
|
|||
@patch('streamlink_cli.console.sys.exit')
|
||||
def test_exit(self, mock_exit):
|
||||
output = StringIO()
|
||||
console = ConsoleOutput(output, Mock())
|
||||
console = ConsoleOutput(output)
|
||||
console.exit("error")
|
||||
self.assertEqual("error: error\n", output.getvalue())
|
||||
mock_exit.assert_called_with(1)
|
||||
|
@ -63,17 +63,11 @@ class TestConsole(unittest.TestCase):
|
|||
@patch('streamlink_cli.console.sys.exit')
|
||||
def test_exit_json(self, mock_exit):
|
||||
output = StringIO()
|
||||
console = ConsoleOutput(output, Mock(), json=True)
|
||||
console = ConsoleOutput(output, json=True)
|
||||
console.exit("error")
|
||||
self.assertEqual('''{\n "error": "error"\n}\n''', output.getvalue())
|
||||
mock_exit.assert_called_with(1)
|
||||
|
||||
def test_set_level(self):
|
||||
session = Mock()
|
||||
console = ConsoleOutput(Mock(), session)
|
||||
console.set_level("debug")
|
||||
session.set_loglevel.assert_called_with("debug")
|
||||
|
||||
@patch('streamlink_cli.console.sys.stderr')
|
||||
@patch('streamlink_cli.console.input')
|
||||
@patch('streamlink_cli.console.sys.stdin.isatty')
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
from io import StringIO
|
||||
import logging
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
from streamlink import logger, Streamlink
|
||||
from tests import catch_warnings
|
||||
from streamlink import logger
|
||||
|
||||
|
||||
class TestLogging(unittest.TestCase):
|
||||
|
@ -53,54 +51,3 @@ class TestLogging(unittest.TestCase):
|
|||
logger.root.setLevel("info")
|
||||
log.info(u"Special Character: Ѩ")
|
||||
self.assertEqual(output.getvalue(), u"[test][info] Special Character: Ѩ\n")
|
||||
|
||||
|
||||
class TestDeprecatedLogger(unittest.TestCase):
|
||||
def setUp(self):
|
||||
warnings.resetwarnings()
|
||||
warnings.simplefilter('always', DeprecationWarning) # turn off filter
|
||||
|
||||
def tearDown(self):
|
||||
warnings.simplefilter('default', DeprecationWarning) # restore filter
|
||||
|
||||
def _new_logger(self):
|
||||
output = StringIO()
|
||||
manager = logger.Logger()
|
||||
manager.set_output(output)
|
||||
return manager, output
|
||||
|
||||
@catch_warnings()
|
||||
def test_deprecated_level(self):
|
||||
manager, output = self._new_logger()
|
||||
|
||||
with warnings.catch_warnings(record=True):
|
||||
log = manager.new_module("test_level")
|
||||
log.debug("test")
|
||||
self.assertEqual(output.tell(), 0)
|
||||
manager.set_level("debug")
|
||||
log.debug("test")
|
||||
self.assertNotEqual(output.tell(), 0)
|
||||
|
||||
@catch_warnings()
|
||||
def test_deprecated_output(self):
|
||||
manager, output = self._new_logger()
|
||||
|
||||
log = manager.new_module("test_output")
|
||||
manager.set_level("debug")
|
||||
log.debug("test")
|
||||
self.assertEqual(output.getvalue(), "[test_output][debug] test\n")
|
||||
|
||||
@catch_warnings()
|
||||
def test_deprecated_session_logger(self):
|
||||
session = Streamlink()
|
||||
output = StringIO()
|
||||
|
||||
new_log = session.logger.new_module("test")
|
||||
session.set_logoutput(output)
|
||||
session.set_loglevel("info")
|
||||
|
||||
new_log.info("test1")
|
||||
|
||||
# regular python loggers shouldn't log here
|
||||
logging.getLogger("streamlink.test").critical("should not log")
|
||||
self.assertEqual(output.getvalue(), "[test][info] test1\n")
|
||||
|
|
Loading…
Reference in New Issue