diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fa3a945..01ad56a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,11 +27,11 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: "actions/checkout@v4" - - uses: "actions/setup-python@v4" + - uses: "actions/setup-python@v5" with: python-version: "${{ matrix.python-version }}" cache: pip @@ -54,7 +54,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] arch: ["x86", "x64"] env: @@ -62,7 +62,7 @@ jobs: steps: - uses: "actions/checkout@v4" - - uses: "actions/setup-python@v4" + - uses: "actions/setup-python@v5" with: python-version: "${{ matrix.python-version }}" architecture: "${{ matrix.arch }}" @@ -84,11 +84,11 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: "actions/checkout@v4" - - uses: "actions/setup-python@v4" + - uses: "actions/setup-python@v5" with: python-version: "${{ matrix.python-version }}" architecture: "${{ matrix.arch }}" @@ -109,5 +109,5 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 - - uses: pre-commit/action@v3.0.0 + - uses: actions/setup-python@v5 + - uses: pre-commit/action@v3.0.1 diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 68f567c..820163e 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -29,7 +29,7 @@ jobs: id-token: write steps: - name: Download artifacts - uses: dawidd6/action-download-artifact@268677152d06ba59fcec7a7f0b5d961b6ccd7e1e # v2.28.0 + uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 # v6 with: path: artifacts/ run_id: ${{ github.event.inputs.run_id || github.event.workflow_run.id }} @@ -39,16 +39,16 @@ jobs: ls -lR artifacts/ mkdir dist mv artifacts/sdist/*.tar.gz dist/ - mv artifacts/wheels/*.whl dist/ + mv artifacts/wheels-*/*.whl dist/ - name: Publish to pypi.org - uses: pypa/gh-action-pypi-publish@b7f401de30cb6434a1e19f805ff006643653240e # v1.8.10 + uses: pypa/gh-action-pypi-publish@f7600683efdcb7656dec5b29656edb7bc586e597 # v1.10.3 if: github.event_name == 'workflow_run' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'pypi') with: packages-dir: dist/ - name: Publish to test.pypi.org - uses: pypa/gh-action-pypi-publish@b7f401de30cb6434a1e19f805ff006643653240e # v1.8.10 + uses: pypa/gh-action-pypi-publish@f7600683efdcb7656dec5b29656edb7bc586e597 # v1.10.3 if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'testpypi' with: repository-url: https://test.pypi.org/legacy/ diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml index 8e445b7..bc6b833 100644 --- a/.github/workflows/wheel-builder.yml +++ b/.github/workflows/wheel-builder.yml @@ -36,7 +36,7 @@ jobs: run: .venv/bin/pip install -U pip build - name: Make sdist run: .venv/bin/python -m build --sdist - - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: sdist path: dist/*.tar.gz @@ -47,7 +47,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04, windows-2019, macos-11] + os: [ubuntu-20.04, windows-2019, macos-12] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 @@ -57,9 +57,9 @@ jobs: persist-credentials: false - name: Build wheels - uses: pypa/cibuildwheel@fff9ec32ed25a9c576750c91e06b410ed0c15db7 # v2.16.2 + uses: pypa/cibuildwheel@7940a4c0e76eb2030e473a5f864f291f63ee879b # v2.21.3 - - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: - name: wheels + name: wheels-${{ matrix.os }} path: ./wheelhouse/*.whl diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9354901..46e87b6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v5.0.0 hooks: - id: check-toml - id: check-yaml @@ -9,21 +9,21 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace args: [--markdown-linebreak-ext=md] - - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.7.1 + - repo: https://github.com/rbubley/mirrors-prettier + rev: v3.3.3 hooks: - id: prettier exclude: docs/sheet/.*\.html$ - repo: https://github.com/asottile/pyupgrade - rev: v3.7.0 + rev: v3.18.0 hooks: - id: pyupgrade - args: [--py38-plus] + args: [--py39-plus] - repo: https://github.com/timothycrosley/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 24.10.0 hooks: - id: black diff --git a/CHANGES b/CHANGES index d91b0f3..84a9668 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,13 @@ Logbook Changelog ================= +Version 1.8.0 +------------- + +- Python 3.13 support +- Fixed deprecation warnings on Python 3.12 +- Dropped support for Python 3.8 + Version 1.7.0.post0 ------------------- diff --git a/benchmark/bench_disabled_introspection.py b/benchmark/bench_disabled_introspection.py index 87d4fe8..606c1ab 100644 --- a/benchmark/bench_disabled_introspection.py +++ b/benchmark/bench_disabled_introspection.py @@ -1,4 +1,5 @@ """Tests with frame introspection disabled""" + from logbook import Flags, Logger, NullHandler log = Logger("Test logger") diff --git a/benchmark/bench_disabled_logger.py b/benchmark/bench_disabled_logger.py index 3572da6..56097f2 100644 --- a/benchmark/bench_disabled_logger.py +++ b/benchmark/bench_disabled_logger.py @@ -1,4 +1,5 @@ """Tests with the whole logger disabled""" + from logbook import Logger log = Logger("Test logger") diff --git a/benchmark/bench_enabled_introspection.py b/benchmark/bench_enabled_introspection.py index 11013bf..8289a60 100644 --- a/benchmark/bench_enabled_introspection.py +++ b/benchmark/bench_enabled_introspection.py @@ -1,4 +1,5 @@ """Tests with stack frame introspection enabled""" + from logbook import Flags, Logger, NullHandler log = Logger("Test logger") diff --git a/benchmark/bench_file_handler.py b/benchmark/bench_file_handler.py index 6b2c0cf..738e426 100644 --- a/benchmark/bench_file_handler.py +++ b/benchmark/bench_file_handler.py @@ -1,4 +1,5 @@ """Benchmarks the file handler""" + from tempfile import NamedTemporaryFile from logbook import FileHandler, Logger diff --git a/benchmark/bench_file_handler_unicode.py b/benchmark/bench_file_handler_unicode.py index 10059df..27a3574 100644 --- a/benchmark/bench_file_handler_unicode.py +++ b/benchmark/bench_file_handler_unicode.py @@ -1,4 +1,5 @@ """Benchmarks the file handler with unicode""" + from tempfile import NamedTemporaryFile from logbook import FileHandler, Logger diff --git a/benchmark/bench_logger_creation.py b/benchmark/bench_logger_creation.py index 0019084..ef11231 100644 --- a/benchmark/bench_logger_creation.py +++ b/benchmark/bench_logger_creation.py @@ -1,4 +1,5 @@ """Test with no handler active""" + from logbook import Logger diff --git a/benchmark/bench_logger_level_low.py b/benchmark/bench_logger_level_low.py index 1ec47b4..b28fa5d 100644 --- a/benchmark/bench_logger_level_low.py +++ b/benchmark/bench_logger_level_low.py @@ -1,4 +1,5 @@ """Benchmarks too low logger levels""" + from io import StringIO from logbook import ERROR, Logger, StreamHandler diff --git a/benchmark/bench_logging_file_handler.py b/benchmark/bench_logging_file_handler.py index 37be718..dc236c5 100644 --- a/benchmark/bench_logging_file_handler.py +++ b/benchmark/bench_logging_file_handler.py @@ -1,4 +1,5 @@ """Tests logging file handler in comparison""" + from logging import FileHandler, getLogger from tempfile import NamedTemporaryFile diff --git a/benchmark/bench_logging_file_handler_unicode.py b/benchmark/bench_logging_file_handler_unicode.py index 7ff319f..c937449 100644 --- a/benchmark/bench_logging_file_handler_unicode.py +++ b/benchmark/bench_logging_file_handler_unicode.py @@ -1,4 +1,5 @@ """Tests logging file handler in comparison""" + from logging import FileHandler, getLogger from tempfile import NamedTemporaryFile diff --git a/benchmark/bench_logging_logger_creation.py b/benchmark/bench_logging_logger_creation.py index 3004f29..830f765 100644 --- a/benchmark/bench_logging_logger_creation.py +++ b/benchmark/bench_logging_logger_creation.py @@ -1,4 +1,5 @@ """Test with no handler active""" + from logging import getLogger root_logger = getLogger() diff --git a/benchmark/bench_logging_logger_level_low.py b/benchmark/bench_logging_logger_level_low.py index 4e018ad..2185ded 100644 --- a/benchmark/bench_logging_logger_level_low.py +++ b/benchmark/bench_logging_logger_level_low.py @@ -1,4 +1,5 @@ """Tests with a logging handler becoming a noop for comparison""" + from io import StringIO from logging import ERROR, StreamHandler, getLogger diff --git a/benchmark/bench_logging_noop.py b/benchmark/bench_logging_noop.py index ad942e1..81319c6 100644 --- a/benchmark/bench_logging_noop.py +++ b/benchmark/bench_logging_noop.py @@ -1,4 +1,5 @@ """Tests with a logging handler becoming a noop for comparison""" + from io import StringIO from logging import ERROR, StreamHandler, getLogger diff --git a/benchmark/bench_logging_noop_filter.py b/benchmark/bench_logging_noop_filter.py index 13a6de5..7035084 100644 --- a/benchmark/bench_logging_noop_filter.py +++ b/benchmark/bench_logging_noop_filter.py @@ -1,4 +1,5 @@ """Tests with a filter disabling a handler for comparsion in logging""" + from io import StringIO from logging import Filter, StreamHandler, getLogger diff --git a/benchmark/bench_logging_stream_handler.py b/benchmark/bench_logging_stream_handler.py index 7935b80..09512a8 100644 --- a/benchmark/bench_logging_stream_handler.py +++ b/benchmark/bench_logging_stream_handler.py @@ -1,4 +1,5 @@ """Tests the stream handler in logging""" + from io import StringIO from logging import Logger, StreamHandler diff --git a/benchmark/bench_noop.py b/benchmark/bench_noop.py index 3b9f6ba..bdf7b97 100644 --- a/benchmark/bench_noop.py +++ b/benchmark/bench_noop.py @@ -1,4 +1,5 @@ """Test with no handler active""" + from io import StringIO from logbook import ERROR, Logger, NullHandler, StreamHandler diff --git a/benchmark/bench_noop_filter_on_handler.py b/benchmark/bench_noop_filter_on_handler.py index 255a42c..392b153 100644 --- a/benchmark/bench_noop_filter_on_handler.py +++ b/benchmark/bench_noop_filter_on_handler.py @@ -1,4 +1,5 @@ """Like the filter test, but with the should_handle implemented""" + from io import StringIO from logbook import Logger, NullHandler, StreamHandler diff --git a/benchmark/bench_redirect_from_logging.py b/benchmark/bench_redirect_from_logging.py index 1b4ab14..f0a0df9 100644 --- a/benchmark/bench_redirect_from_logging.py +++ b/benchmark/bench_redirect_from_logging.py @@ -1,4 +1,5 @@ """Tests redirects from logging to logbook""" + from io import StringIO from logging import getLogger diff --git a/benchmark/bench_redirect_to_logging.py b/benchmark/bench_redirect_to_logging.py index b19a296..dcf2a1d 100644 --- a/benchmark/bench_redirect_to_logging.py +++ b/benchmark/bench_redirect_to_logging.py @@ -1,4 +1,5 @@ """Tests redirects from logging to logbook""" + from io import StringIO from logging import StreamHandler, getLogger diff --git a/benchmark/bench_stack_manipulation.py b/benchmark/bench_stack_manipulation.py index 671262a..d3bece2 100644 --- a/benchmark/bench_stack_manipulation.py +++ b/benchmark/bench_stack_manipulation.py @@ -1,4 +1,5 @@ """Tests basic stack manipulation performance""" + from io import StringIO from tempfile import NamedTemporaryFile diff --git a/benchmark/bench_stream_handler.py b/benchmark/bench_stream_handler.py index f3ae875..b3cfda1 100644 --- a/benchmark/bench_stream_handler.py +++ b/benchmark/bench_stream_handler.py @@ -1,4 +1,5 @@ """Tests the stream handler""" + from io import StringIO from logbook import Logger, StreamHandler diff --git a/benchmark/bench_test_handler.py b/benchmark/bench_test_handler.py index aa17dc2..818e3a0 100644 --- a/benchmark/bench_test_handler.py +++ b/benchmark/bench_test_handler.py @@ -1,4 +1,5 @@ """Tests the test handler""" + from logbook import Logger, TestHandler log = Logger("Test logger") diff --git a/pyproject.toml b/pyproject.toml index 49bb0ad..01ffea0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,13 +16,13 @@ maintainers = [ ] classifiers = [ "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] -requires-python = ">=3.8" +requires-python = ">=3.9" dynamic = ["version"] [project.urls] diff --git a/src/logbook/__version__.py b/src/logbook/__version__.py index 365ce3d..29654ee 100644 --- a/src/logbook/__version__.py +++ b/src/logbook/__version__.py @@ -1 +1 @@ -__version__ = "1.7.0.post0" +__version__ = "1.8.0" diff --git a/src/logbook/_fallback.py b/src/logbook/_fallback.py index c011f2b..e314ee4 100644 --- a/src/logbook/_fallback.py +++ b/src/logbook/_fallback.py @@ -7,6 +7,7 @@ :copyright: (c) 2010 by Armin Ronacher, Georg Brandl. :license: BSD, see LICENSE for more details. """ + from itertools import count from logbook.concurrency import ( diff --git a/src/logbook/base.py b/src/logbook/base.py index 470577a..4ae5a2c 100644 --- a/src/logbook/base.py +++ b/src/logbook/base.py @@ -7,6 +7,7 @@ :copyright: (c) 2010 by Armin Ronacher, Georg Brandl. :license: BSD, see LICENSE for more details. """ + import os import sys import traceback diff --git a/src/logbook/compat.py b/src/logbook/compat.py index c79fef1..a2d0073 100644 --- a/src/logbook/compat.py +++ b/src/logbook/compat.py @@ -8,14 +8,17 @@ :copyright: (c) 2010 by Armin Ronacher, Georg Brandl. :license: BSD, see LICENSE for more details. """ + import logging import sys import warnings from collections.abc import Mapping -from datetime import date, datetime, timezone +from datetime import timezone import logbook +from .helpers import datetime_utcfromtimestamp + def redirect_logging(set_root_logger_level=True): """Permanently redirects logging to the stdlib. This also @@ -140,7 +143,7 @@ def convert_time(self, timestamp): """Converts the UNIX timestamp of the old record into a datetime object as used by logbook. """ - return datetime.utcfromtimestamp(timestamp) + return datetime_utcfromtimestamp(timestamp) def convert_record(self, old_record): """Converts an old logging record into a logbook log record.""" diff --git a/src/logbook/handlers.py b/src/logbook/handlers.py index 287e3fc..f718a8c 100644 --- a/src/logbook/handlers.py +++ b/src/logbook/handlers.py @@ -7,6 +7,7 @@ :copyright: (c) 2010 by Armin Ronacher, Georg Brandl. :license: BSD, see LICENSE for more details. """ + import errno import gzip import math diff --git a/src/logbook/helpers.py b/src/logbook/helpers.py index eb58304..603df98 100644 --- a/src/logbook/helpers.py +++ b/src/logbook/helpers.py @@ -7,6 +7,7 @@ :copyright: (c) 2010 by Armin Ronacher, Georg Brandl. :license: BSD, see LICENSE for more details. """ + import errno import os import random @@ -136,8 +137,6 @@ def _convert(obj): for key, value in obj.items(): if not isinstance(key, str): key = str(key) - if not isinstance(key, str): - key = key rv[key] = _convert(value) return rv @@ -153,8 +152,16 @@ def datetime_utcnow(): """ return datetime.now(timezone.utc).replace(tzinfo=None) + def datetime_utcfromtimestamp(timestamp): + """datetime.utcfromtimesetamp() but doesn't emit a deprecation warning. + + Will be fixed by https://github.com/getlogbook/logbook/issues/353 + """ + return datetime.fromtimestamp(timestamp, timezone.utc).replace(tzinfo=None) + else: datetime_utcnow = datetime.utcnow + datetime_utcfromtimestamp = datetime.utcfromtimestamp def format_iso8601(d=None): diff --git a/src/logbook/more.py b/src/logbook/more.py index d9bb8d2..64ab4a7 100644 --- a/src/logbook/more.py +++ b/src/logbook/more.py @@ -7,6 +7,7 @@ :copyright: (c) 2010 by Armin Ronacher, Georg Brandl. :license: BSD, see LICENSE for more details. """ + import os import platform import re @@ -232,7 +233,6 @@ def emit(self, record): class SlackHandler(Handler, StringFormatterHandlerMixin): - """A handler that logs to slack. Requires that you sign up an application on slack and request an api token. Furthermore the slacker library has to be installed. @@ -520,7 +520,6 @@ def flush(self): class RiemannHandler(Handler): - """ A handler that sends logs as events to Riemann. """ diff --git a/src/logbook/notifiers.py b/src/logbook/notifiers.py index 4199adc..1f391c1 100644 --- a/src/logbook/notifiers.py +++ b/src/logbook/notifiers.py @@ -7,6 +7,7 @@ :copyright: (c) 2010 by Armin Ronacher, Christopher Grebs. :license: BSD, see LICENSE for more details. """ + import base64 import os import sys diff --git a/src/logbook/queues.py b/src/logbook/queues.py index 9d9454f..d0c0795 100644 --- a/src/logbook/queues.py +++ b/src/logbook/queues.py @@ -7,6 +7,7 @@ :copyright: (c) 2010 by Armin Ronacher, Georg Brandl. :license: BSD, see LICENSE for more details. """ + import json import platform import threading diff --git a/src/logbook/ticketing.py b/src/logbook/ticketing.py index e463693..84d820c 100644 --- a/src/logbook/ticketing.py +++ b/src/logbook/ticketing.py @@ -8,6 +8,7 @@ :copyright: (c) 2010 by Armin Ronacher, Georg Brandl. :license: BSD, see LICENSE for more details. """ + import json from time import time diff --git a/tests/test_logging_times.py b/tests/test_logging_times.py index a27bf06..46da2c9 100644 --- a/tests/test_logging_times.py +++ b/tests/test_logging_times.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta, tzinfo +from datetime import datetime, timedelta, timezone, tzinfo import pytest @@ -25,7 +25,7 @@ def test_timedate_format(activation_strategy, logger): # get the expected difference between local and utc time t1 = datetime.now() - t2 = datetime.utcnow() + t2 = datetime.now(timezone.utc).replace(tzinfo=None) tz_minutes_diff = (t1 - t2).total_seconds() / 60.0 diff --git a/tests/utils.py b/tests/utils.py index 277d9be..3eb5908 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -5,6 +5,7 @@ :copyright: (c) 2010 by Armin Ronacher, Georg Brandl. :license: BSD, see LICENSE for more details. """ + import functools import importlib import sys diff --git a/tox.ini b/tox.ini index 499ed52..c55559b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{38,39,310,311,312}{,-nospeedups},pypy,docs +envlist = py{39,310,311,312,313}{,-nospeedups},pypy,docs [testenv] extras = @@ -27,8 +27,8 @@ commands = [gh-actions] python = - 3.8: py38 3.9: py39 3.10: py310 3.11: py311, docs 3.12: py312 + 3.13: py313