From c37995de875d6b60c0140890f02df07090f161ba Mon Sep 17 00:00:00 2001 From: Frazer McLean Date: Sun, 30 Jul 2023 21:31:46 +0200 Subject: [PATCH 1/6] Resolve TODO about dropping Python 2 --- src/logbook/base.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/logbook/base.py b/src/logbook/base.py index 998f1dc..f9fb425 100644 --- a/src/logbook/base.py +++ b/src/logbook/base.py @@ -450,8 +450,7 @@ def __init__( #: where custom log processors can attach custom context sensitive #: data. - # TODO: Replace the lambda with str when we remove support for python 2 - self.extra = defaultdict(lambda: "", extra or ()) + self.extra = defaultdict(str, extra or ()) #: If available, optionally the interpreter frame that pulled the #: heavy init. This usually points to somewhere in the dispatcher. #: Might not be available for all calls and is removed when the log @@ -559,8 +558,7 @@ def update_from_dict(self, d): if isinstance(self.time, str): self.time = parse_iso8601(self.time) - # TODO: Replace the lambda with str when we remove support for python 2` - self.extra = defaultdict(lambda: "", self.extra) + self.extra = defaultdict(str, self.extra) return self def _format_message(self, msg, *args, **kwargs): From 19d57f820bdc95202dc3f1177cb7c04c76d8cdba Mon Sep 17 00:00:00 2001 From: Frazer McLean Date: Sun, 30 Jul 2023 21:35:19 +0200 Subject: [PATCH 2/6] Use datetime.timestamp I note that LoggingHandler has a bug if set_datetime_format("local") is used. Maybe in Logbook 2 we can get ride of the naive-means-UTC default we currently have. --- src/logbook/compat.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/logbook/compat.py b/src/logbook/compat.py index f3fc2a8..c79fef1 100644 --- a/src/logbook/compat.py +++ b/src/logbook/compat.py @@ -12,12 +12,10 @@ import sys import warnings from collections.abc import Mapping -from datetime import date, datetime +from datetime import date, datetime, timezone import logbook -_epoch_ord = date(1970, 1, 1).toordinal() - def redirect_logging(set_root_logger_level=True): """Permanently redirects logging to the stdlib. This also @@ -213,12 +211,10 @@ def convert_level(self, level): def convert_time(self, dt): """Converts a datetime object into a timestamp.""" - year, month, day, hour, minute, second = dt.utctimetuple()[:6] - days = date(year, month, 1).toordinal() - _epoch_ord + day - 1 - hours = days * 24 + hour - minutes = hours * 60 + minute - seconds = minutes * 60 + second - return seconds + if dt.tzinfo is None: + # Logbook uses naive datetimes to represent UTC (utcnow) + return dt.replace(tzinfo=timezone.utc).timestamp() + return dt.timestamp() def convert_record(self, old_record): """Converts a record from logbook to logging.""" From 085a5eddc555f555113303894b527c459788ea79 Mon Sep 17 00:00:00 2001 From: Frazer McLean Date: Sun, 30 Jul 2023 21:35:59 +0200 Subject: [PATCH 3/6] Use importlib --- tests/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/utils.py b/tests/utils.py index f7c9443..bde3b96 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -6,6 +6,7 @@ :license: BSD, see LICENSE for more details. """ import functools +import importlib import os import sys from contextlib import contextmanager @@ -40,7 +41,7 @@ def get_total_delta_seconds(delta): def require_module(module_name): found = True try: - __import__(module_name) + importlib.import_module(module_name) except ImportError: found = False From 7e90e9c593edc6a327595d46c699fa240f2b375d Mon Sep 17 00:00:00 2001 From: Frazer McLean Date: Sun, 30 Jul 2023 21:37:29 +0200 Subject: [PATCH 4/6] Use timedelta.total_seconds() --- tests/test_logging_times.py | 6 ++---- tests/utils.py | 10 ---------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/tests/test_logging_times.py b/tests/test_logging_times.py index 006572b..a27bf06 100644 --- a/tests/test_logging_times.py +++ b/tests/test_logging_times.py @@ -4,8 +4,6 @@ import logbook -from .utils import get_total_delta_seconds - def test_timedate_format(activation_strategy, logger): """ @@ -29,7 +27,7 @@ def test_timedate_format(activation_strategy, logger): t1 = datetime.now() t2 = datetime.utcnow() - tz_minutes_diff = get_total_delta_seconds(t1 - t2) / 60.0 + tz_minutes_diff = (t1 - t2).total_seconds() / 60.0 if abs(tz_minutes_diff) < 1: pytest.skip( @@ -38,7 +36,7 @@ def test_timedate_format(activation_strategy, logger): ) # get the difference between LogRecord local and utc times - logbook_minutes_diff = get_total_delta_seconds(time_local - time_utc) / 60.0 + logbook_minutes_diff = (time_local - time_utc).total_seconds() / 60.0 assert abs(logbook_minutes_diff) > 1, ( "Localtime does not differ from UTC by more than 1 " "minute (Local: %s, UTC: %s)" % (time_local, time_utc) diff --git a/tests/utils.py b/tests/utils.py index bde3b96..7411fc4 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -21,16 +21,6 @@ LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -def get_total_delta_seconds(delta): - """ - Replacement for datetime.timedelta.total_seconds() for Python 2.5, 2.6 - and 3.1 - """ - return ( - delta.microseconds + (delta.seconds + delta.days * 24 * 3600) * 10**6 - ) / 10**6 - - appveyor = pytest.mark.skipif( os.environ.get("APPVEYOR") != "True", reason="AppVeyor CI test" ) From d755c7383cdbe5eb7951dd455a86f79cdc3092a1 Mon Sep 17 00:00:00 2001 From: Frazer McLean Date: Sun, 30 Jul 2023 21:37:41 +0200 Subject: [PATCH 5/6] Remove unused pytest markers --- tests/utils.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index 7411fc4..277d9be 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -7,7 +7,6 @@ """ import functools import importlib -import os import sys from contextlib import contextmanager from io import StringIO @@ -21,13 +20,6 @@ LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -appveyor = pytest.mark.skipif( - os.environ.get("APPVEYOR") != "True", reason="AppVeyor CI test" -) - -travis = pytest.mark.skipif(os.environ.get("TRAVIS") != "true", reason="Travis CI test") - - def require_module(module_name): found = True try: From 6c54e0fb69e1b268b077862cb7c59a9ab49b3c0a Mon Sep 17 00:00:00 2001 From: Frazer McLean Date: Sun, 30 Jul 2023 21:37:59 +0200 Subject: [PATCH 6/6] Fix implicit concatenation on same line after black reformat --- tests/test_unicode.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_unicode.py b/tests/test_unicode.py index 487d405..3a503c7 100644 --- a/tests/test_unicode.py +++ b/tests/test_unicode.py @@ -26,7 +26,7 @@ def test_default_format_bad_encoding(logger): def test_custom_unicode_format_unicode(logger): - format_string = "[{record.level_name}] " "{record.channel}: {record.message}" + format_string = "[{record.level_name}] {record.channel}: {record.message}" with capturing_stderr_context() as stream: with logbook.StderrHandler(format_string=format_string): logger.warn("\u2603") @@ -34,7 +34,7 @@ def test_custom_unicode_format_unicode(logger): def test_custom_string_format_unicode(logger): - format_string = "[{record.level_name}] " "{record.channel}: {record.message}" + format_string = "[{record.level_name}] {record.channel}: {record.message}" with capturing_stderr_context() as stream: with logbook.StderrHandler(format_string=format_string): logger.warn("\u2603")