From 1c79904bcd29db43bc8cde1b624a60433494c0d0 Mon Sep 17 00:00:00 2001 From: Taybin Rutkin Date: Wed, 13 Oct 2021 09:22:32 -0400 Subject: [PATCH 1/9] test on python 3.10 --- .travis.yml | 5 +++++ tox.ini | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7377e46f..e9aaa09c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -147,6 +147,11 @@ matrix: os: linux dist: xenial stage: test + - python: 3.10.0 + env: TOXENV=3.10 IDENT="3.10.0" RUN_SUITE=y + os: linux + dist: xenial + stage: test before_install: install: diff --git a/tox.ini b/tox.ini index 097c91b8..35e47994 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = 3.9,3.8,3.7,3.6,flake8,apicheck,typecheck,docstyle,bandit +envlist = 3.10,3.9,3.8,3.7,3.6,flake8,apicheck,typecheck,docstyle,bandit [testenv] deps= @@ -14,6 +14,7 @@ sitepackages = False recreate = False commands = py.test --random-order --open-files -xvv --cov=mode --cov-branch basepython = + 3.10,typecheck,apicheck,linkcheck: python3.10 3.9: python3.9 3.8,flake8,typecheck,apicheck,linkcheck,docstyle,bandit: python3.8 3.7: python3.7 From 3be51effe112cd63ed36d77d9cf9e1b67107c450 Mon Sep 17 00:00:00 2001 From: Taybin Rutkin Date: Wed, 13 Oct 2021 10:24:43 -0400 Subject: [PATCH 2/9] Removes use of deprecated and removed loop arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note that this doesn’t change the parameters of functions. They still accept loop arguments, even if they are unused. Changing the API to account for unused variables will come in a later commit. --- mode/services.py | 5 ----- mode/supervisors.py | 1 - mode/threads.py | 6 ++---- mode/utils/times.py | 2 +- mode/worker.py | 2 +- t/unit/test_services.py | 4 +--- t/unit/test_threads.py | 16 +++++++--------- t/unit/test_worker.py | 2 +- 8 files changed, 13 insertions(+), 25 deletions(-) diff --git a/mode/services.py b/mode/services.py index f075e080..06131980 100644 --- a/mode/services.py +++ b/mode/services.py @@ -692,7 +692,6 @@ async def sleep( await asyncio.wait_for( self._stopped.wait(), timeout=want_seconds(n), - loop=loop or self.loop, ) except asyncio.TimeoutError: pass @@ -716,7 +715,6 @@ async def wait_many( cast(Iterable[Awaitable[Any]], coros), return_when=asyncio.ALL_COMPLETED, timeout=want_seconds(timeout), - loop=self.loop, ) return await self._wait_one(coro, timeout=timeout) @@ -747,7 +745,6 @@ async def wait_first( futures.values(), return_when=asyncio.FIRST_COMPLETED, timeout=timeout, - loop=self.loop, ) for f in done: if f.done() and f.exception() is not None: @@ -784,7 +781,6 @@ async def _wait_stopped(self, timeout: Seconds = None) -> None: [stopped, crashed], return_when=asyncio.FIRST_COMPLETED, timeout=timeout, - loop=self.loop, ) for fut in done: fut.result() # propagate exceptions @@ -971,7 +967,6 @@ async def _wait_for_futures(self, *, timeout: float = None) -> None: await asyncio.wait( self._futures, return_when=asyncio.ALL_COMPLETED, - loop=self.loop, timeout=timeout, ) diff --git a/mode/supervisors.py b/mode/supervisors.py index 0c6c8ad5..98ebd4ac 100644 --- a/mode/supervisors.py +++ b/mode/supervisors.py @@ -168,7 +168,6 @@ async def stop_services(self, services: List[ServiceT]) -> None: # Stop them all simultaneously. await asyncio.gather( *[service.stop() for service in services], - loop=self.loop, ) async def restart_service(self, service: ServiceT) -> None: diff --git a/mode/threads.py b/mode/threads.py index 80e9c5f2..2d59e689 100644 --- a/mode/threads.py +++ b/mode/threads.py @@ -320,11 +320,9 @@ class MethodQueue(Service): mundane_level = "debug" - def __init__( - self, loop: asyncio.AbstractEventLoop, num_workers: int = 2, **kwargs: Any - ) -> None: + def __init__(self, num_workers: int = 2, **kwargs: Any) -> None: super().__init__(**kwargs) - self._queue = asyncio.Queue(loop=self.loop) + self._queue = asyncio.Queue() self._queue_ready = Event(loop=self.loop) self.num_workers = num_workers self._workers = [] diff --git a/mode/utils/times.py b/mode/utils/times.py index 05723f78..87e113bb 100644 --- a/mode/utils/times.py +++ b/mode/utils/times.py @@ -148,7 +148,7 @@ async def __aenter__(self) -> "Bucket": if self.raises: raise self.raises() expected_time = self.expected_time() - await asyncio.sleep(expected_time, loop=self.loop) + await asyncio.sleep(expected_time) return self async def __aexit__( diff --git a/mode/worker.py b/mode/worker.py index 367c3da7..1d98ab6c 100644 --- a/mode/worker.py +++ b/mode/worker.py @@ -331,7 +331,7 @@ def _shutdown_loop(self) -> None: raise self.crash_reason from self.crash_reason async def _sentinel_task(self) -> None: - await asyncio.sleep(1.0, loop=self.loop) + await asyncio.sleep(1.0) def _gather_all(self) -> None: # sleeps for at most 10 * 0.1s diff --git a/t/unit/test_services.py b/t/unit/test_services.py index 72c4baea..cca479ff 100644 --- a/t/unit/test_services.py +++ b/t/unit/test_services.py @@ -123,7 +123,7 @@ class ATaskService(Service): values = [] def __post_init__(self): - self.event = asyncio.Event(loop=self.loop) + self.event = asyncio.Event() @Service.task async def _background_task(self): @@ -343,7 +343,6 @@ async def test__wait_stopped(self, *, service): ], return_when=asyncio.FIRST_COMPLETED, timeout=1.0, - loop=service.loop, ) for fut in done: @@ -553,7 +552,6 @@ async def test_wait_many(self, *, service): [m1, m2], return_when=asyncio.ALL_COMPLETED, timeout=3.34, - loop=service.loop, ) service._wait_one.assert_called_once_with(ANY, timeout=3.34) diff --git a/t/unit/test_threads.py b/t/unit/test_threads.py index 4f7c337e..dccc1f72 100644 --- a/t/unit/test_threads.py +++ b/t/unit/test_threads.py @@ -260,7 +260,7 @@ class test_MethodQueue: @pytest.mark.asyncio async def test_call(self): loop = asyncio.get_event_loop() - queue = MethodQueue(num_workers=2, loop=loop) + queue = MethodQueue(num_workers=2) async with queue: @@ -279,8 +279,8 @@ async def myfun(x, y): @pytest.mark.asyncio async def test_call_raising(self): loop = asyncio.get_event_loop() - queue = MethodQueue(num_workers=2, loop=loop) - all_done = asyncio.Event(loop=loop) + queue = MethodQueue(num_workers=2) + all_done = asyncio.Event() calls = 0 async with queue: @@ -310,11 +310,10 @@ async def myfun(x, y): @pytest.mark.asyncio async def test_cast(self): - loop = asyncio.get_event_loop() - queue = MethodQueue(num_workers=2, loop=loop) + queue = MethodQueue(num_workers=2) calls = 0 - all_done = asyncio.Event(loop=loop) + all_done = asyncio.Event() async with queue: @@ -330,11 +329,10 @@ async def myfun(x, y): @pytest.mark.asyncio async def test_flush(self): - loop = asyncio.get_event_loop() - queue = MethodQueue(num_workers=2, loop=loop) + queue = MethodQueue(num_workers=2) calls = 0 - all_done = asyncio.Event(loop=loop) + all_done = asyncio.Event() async def myfun(x, y): nonlocal calls diff --git a/t/unit/test_worker.py b/t/unit/test_worker.py index 9a2315ed..4bee6b33 100644 --- a/t/unit/test_worker.py +++ b/t/unit/test_worker.py @@ -355,7 +355,7 @@ def patch_shutdown_loop(self, worker, is_running=False): async def test__sentinel_task(self, worker): with patch("asyncio.sleep", AsyncMock()) as sleep: await worker._sentinel_task() - sleep.coro.assert_called_once_with(1.0, loop=worker.loop) + sleep.coro.assert_called_once_with(1.0) def test__gather_all(self, worker): with patch("mode.worker.all_tasks") as all_tasks: From 8524be6127626509e078e5304fec8654b893903a Mon Sep 17 00:00:00 2001 From: Taybin Rutkin Date: Wed, 13 Oct 2021 10:56:23 -0400 Subject: [PATCH 3/9] use bionic for testing python 3.10 with travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e9aaa09c..ed6bb153 100644 --- a/.travis.yml +++ b/.travis.yml @@ -150,7 +150,7 @@ matrix: - python: 3.10.0 env: TOXENV=3.10 IDENT="3.10.0" RUN_SUITE=y os: linux - dist: xenial + dist: bionic stage: test before_install: From eb5aad0c7e63305c85efa503fcd2cd44fa417b63 Mon Sep 17 00:00:00 2001 From: Taybin Rutkin Date: Wed, 13 Oct 2021 10:58:48 -0400 Subject: [PATCH 4/9] just run linters on python 3.8 (for now) --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 35e47994..e277ac51 100644 --- a/tox.ini +++ b/tox.ini @@ -14,7 +14,7 @@ sitepackages = False recreate = False commands = py.test --random-order --open-files -xvv --cov=mode --cov-branch basepython = - 3.10,typecheck,apicheck,linkcheck: python3.10 + 3.10: python3.10 3.9: python3.9 3.8,flake8,typecheck,apicheck,linkcheck,docstyle,bandit: python3.8 3.7: python3.7 From cbe20e2f89a2a32551aaaf4c8db7223e76d9b43c Mon Sep 17 00:00:00 2001 From: Taybin Rutkin Date: Wed, 13 Oct 2021 11:07:54 -0400 Subject: [PATCH 5/9] run linters on bionic VM --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed6bb153..9ba40d70 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,27 +15,27 @@ matrix: - python: 3.8.6 env: TOXENV=flake8 os: linux - dist: focal + dist: bionic stage: lint - python: 3.8.6 env: TOXENV=typecheck os: linux - dist: focal + dist: bionic stage: lint - python: 3.8.6 env: TOXENV=apicheck os: linux - dist: focal + dist: bionic stage: lint - python: 3.8.6 env: TOXENV=docstyle os: linux - dist: focal + dist: bionic stage: lint - python: 3.8.6 env: TOXENV=bandit os: linux - dist: focal + dist: bionic stage: lint - python: 3.6.3 env: TOXENV=3.6 RUN_SUITE=y From b404ecaf32ef51e0b19959b499bc0ba72a261a36 Mon Sep 17 00:00:00 2001 From: Taybin Rutkin Date: Wed, 13 Oct 2021 11:19:41 -0400 Subject: [PATCH 6/9] some workarounds for flake8-isort --- requirements/flakes.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements/flakes.txt b/requirements/flakes.txt index ef1a03a5..d05b20e8 100644 --- a/requirements/flakes.txt +++ b/requirements/flakes.txt @@ -1,4 +1,4 @@ -flake8>=2.5.4 +flake8>=3.8.3,<4.0 # flake8-isort doesn't work with flake8-4.0 flake8-bandit flake8-bugbear flake8-builtins-unleashed @@ -10,3 +10,4 @@ flake8-mock flake8-pep3101 flake8-pyi flake8-tuple +isort<5.0.0 # flake8-isort doesn't work with isort-5 From d70ec60fb9e2aa98b90a8343542743a6f9188b00 Mon Sep 17 00:00:00 2001 From: Taybin Rutkin Date: Wed, 13 Oct 2021 12:06:57 -0400 Subject: [PATCH 7/9] use pre-commit to enforce formatting --- .bumpversion.cfg | 1 - .github/ISSUE_TEMPLATE.md | 1 - .pre-commit-config.yaml | 30 +++++++++++++++++++++++++++ .travis.yml | 5 +++++ CODE_OF_CONDUCT.rst | 1 - README.rst | 1 - docs/index.rst | 1 - docs/reference/mode.loop.eventlet.rst | 1 - docs/reference/mode.loop.gevent.rst | 1 - docs/reference/mode.loop.uvloop.rst | 1 - extra/bandit/baseline.json | 2 +- extra/bandit/config.yml | 1 - mode/__init__.py | 8 +++---- mode/loop/eventlet.py | 2 +- mode/loop/gevent.py | 4 ++-- requirements/flakes.txt | 4 +--- setup.cfg | 4 ++++ setup.py | 4 ++-- t/functional/utils/test_queues.py | 2 +- t/unit/test_services.py | 1 - 20 files changed, 51 insertions(+), 24 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.bumpversion.cfg b/.bumpversion.cfg index d6aa7c29..df600288 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -12,4 +12,3 @@ serialize = [bumpversion:file:docs/includes/introduction.txt] [bumpversion:file:README.rst] - diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 54f27622..aca083c3 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -26,4 +26,3 @@ Paste the full traceback (if there is any) * Python version * Mode version * Operating system - diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..25e434e3 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,30 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.0.1 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + + - repo: https://github.com/ambv/black + rev: 21.9b0 + hooks: + - id: black + + - repo: https://github.com/pycqa/isort + rev: 5.9.3 + hooks: + - id: isort + name: isort (python) + + - repo: local + hooks: + - id: flake8 + name: flake8 + stages: [commit] + language: python + entry: flake8 + types: [python] diff --git a/.travis.yml b/.travis.yml index 9ba40d70..d29d0c4b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -147,6 +147,11 @@ matrix: os: linux dist: xenial stage: test + - python: 3.9.6 + env: TOXENV=3.9 IDENT="3.9.6" RUN_SUITE=y + os: linux + dist: bionic + stage: test - python: 3.10.0 env: TOXENV=3.10 IDENT="3.10.0" RUN_SUITE=y os: linux diff --git a/CODE_OF_CONDUCT.rst b/CODE_OF_CONDUCT.rst index d59514a5..7141c712 100644 --- a/CODE_OF_CONDUCT.rst +++ b/CODE_OF_CONDUCT.rst @@ -41,4 +41,3 @@ reported by opening an issue or contacting one or more of the project maintainer This Code of Conduct is adapted from the Contributor Covenant, version 1.2.0 available at http://contributor-covenant.org/version/1/2/0/. - diff --git a/README.rst b/README.rst index dfcf4e03..f12a9d30 100644 --- a/README.rst +++ b/README.rst @@ -484,4 +484,3 @@ version 1.2.0 available at http://contributor-covenant.org/version/1/2/0/. .. |pyimp| image:: https://img.shields.io/pypi/implementation/mode-streaming.svg :alt: Supported Python implementations. :target: http://pypi.org/project/mode-streaming/ - diff --git a/docs/index.rst b/docs/index.rst index ded15b38..156eb339 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -30,4 +30,3 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` * :ref:`search` - diff --git a/docs/reference/mode.loop.eventlet.rst b/docs/reference/mode.loop.eventlet.rst index 5c8eaccc..e2cac7f0 100644 --- a/docs/reference/mode.loop.eventlet.rst +++ b/docs/reference/mode.loop.eventlet.rst @@ -10,4 +10,3 @@ Importing this module directly will set the global event loop. See :mod:`faust.loop` for more information. - diff --git a/docs/reference/mode.loop.gevent.rst b/docs/reference/mode.loop.gevent.rst index d86d01ad..6f50695f 100644 --- a/docs/reference/mode.loop.gevent.rst +++ b/docs/reference/mode.loop.gevent.rst @@ -10,4 +10,3 @@ Importing this module directly will set the global event loop. See :mod:`faust.loop` for more information. - diff --git a/docs/reference/mode.loop.uvloop.rst b/docs/reference/mode.loop.uvloop.rst index 181a1ede..72fe42a5 100644 --- a/docs/reference/mode.loop.uvloop.rst +++ b/docs/reference/mode.loop.uvloop.rst @@ -10,4 +10,3 @@ Importing this module directly will set the global event loop. See :mod:`faust.loop` for more information. - diff --git a/extra/bandit/baseline.json b/extra/bandit/baseline.json index 68afae14..f05fb96b 100644 --- a/extra/bandit/baseline.json +++ b/extra/bandit/baseline.json @@ -537,4 +537,4 @@ "test_name": "try_except_pass" } ] -} \ No newline at end of file +} diff --git a/extra/bandit/config.yml b/extra/bandit/config.yml index ee7ec19c..38fba5ae 100644 --- a/extra/bandit/config.yml +++ b/extra/bandit/config.yml @@ -395,4 +395,3 @@ weak_cryptographic_key: weak_key_size_ec_medium: 224 weak_key_size_rsa_high: 1024 weak_key_size_rsa_medium: 2048 - diff --git a/mode/__init__.py b/mode/__init__.py index 7cd7a335..0fa7dda8 100644 --- a/mode/__init__.py +++ b/mode/__init__.py @@ -6,6 +6,10 @@ import re import sys import typing + +# Lazy loading. +# - See werkzeug/__init__.py for the rationale behind this. +from types import ModuleType # noqa from typing import Any, Mapping, NamedTuple, Sequence __version__ = "0.1.0" @@ -89,10 +93,6 @@ class version_info_t(NamedTuple): ] -# Lazy loading. -# - See werkzeug/__init__.py for the rationale behind this. -from types import ModuleType # noqa - all_by_module: Mapping[str, Sequence[str]] = { "mode.services": ["Service", "task", "timer"], "mode.signals": ["BaseSignal", "Signal", "SyncSignal"], diff --git a/mode/loop/eventlet.py b/mode/loop/eventlet.py index 2a66e68a..1f77a24a 100644 --- a/mode/loop/eventlet.py +++ b/mode/loop/eventlet.py @@ -1,4 +1,5 @@ """Enable :pypi:`eventlet` support for :mod:`asyncio`.""" +import asyncio # noqa: E402,I100,I202 import os os.environ["GEVENT_LOOP"] = "mode.loop._gevent_loop.Loop" @@ -18,7 +19,6 @@ "Eventlet loop requires the aioeventlet library: " "pip install aioeventlet" ) from None -import asyncio # noqa: E402,I100,I202 if asyncio._get_running_loop() is not None: raise RuntimeError("Event loop created before importing eventlet loop!") diff --git a/mode/loop/gevent.py b/mode/loop/gevent.py index 835696a6..14d28fa7 100644 --- a/mode/loop/gevent.py +++ b/mode/loop/gevent.py @@ -1,6 +1,8 @@ """Enable :pypi:`gevent` support for :mod:`asyncio`.""" +import asyncio # noqa: E402,I100,I202 import os import warnings +from typing import Optional, cast # noqa: F401,E402 os.environ["GEVENT_LOOP"] = "mode.loop._gevent_loop.Loop" try: @@ -11,7 +13,6 @@ "Gevent loop requires the gevent library: " "pip install gevent" ) from None gevent.monkey.patch_all() -from typing import Optional, cast # noqa: F401,E402 try: import psycopg2 # noqa: F401 @@ -33,7 +34,6 @@ "Gevent loop requires the aiogevent library: " "pip install aiogevent" ) from None -import asyncio # noqa: E402,I100,I202 if asyncio._get_running_loop() is not None: raise RuntimeError("Event loop created before importing gevent loop!") diff --git a/requirements/flakes.txt b/requirements/flakes.txt index d05b20e8..1063c4f5 100644 --- a/requirements/flakes.txt +++ b/requirements/flakes.txt @@ -1,13 +1,11 @@ -flake8>=3.8.3,<4.0 # flake8-isort doesn't work with flake8-4.0 +flake8>=4.0.0 flake8-bandit flake8-bugbear flake8-builtins-unleashed flake8-comprehensions flake8-debugger -flake8-isort flake8-logging-format flake8-mock flake8-pep3101 flake8-pyi flake8-tuple -isort<5.0.0 # flake8-isort doesn't work with isort-5 diff --git a/setup.cfg b/setup.cfg index 09b47f9f..47caec6e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -41,6 +41,9 @@ universal = 1 ignore = N806, N802, N801, N803, I100, I201, I202, B008, W504, G200, S101, E203, E266, E501, W503 enable-extensions = G max-line-length = 88 +per-file-ignores = + t/*: S301,S403 + #[pep257] #ignore = D102,D104,D203,D105,D213 @@ -82,3 +85,4 @@ warn_unused_ignores = True [isort] profile=black +known_first_party=mode diff --git a/setup.py b/setup.py index ed70fc21..1281296b 100644 --- a/setup.py +++ b/setup.py @@ -18,11 +18,11 @@ def _pyimp(): NAME = "mode-streaming" EXTENSIONS = {"eventlet", "gevent", "uvloop"} -E_UNSUPPORTED_PYTHON = "%s 1.0 requires %%s %%s or later!" % (NAME,) +E_UNSUPPORTED_PYTHON = "%s 1.0 requires %%s %%s or later!" % (NAME,) # noqa: S001 PYIMP = _pyimp() if sys.version_info < (3, 6): - raise Exception(E_UNSUPPORTED_PYTHON % (PYIMP, "3.6")) + raise Exception(E_UNSUPPORTED_PYTHON % (PYIMP, "3.6")) # noqa: S001 from pathlib import Path # noqa diff --git a/t/functional/utils/test_queues.py b/t/functional/utils/test_queues.py index 2a172508..d44d8282 100644 --- a/t/functional/utils/test_queues.py +++ b/t/functional/utils/test_queues.py @@ -51,7 +51,7 @@ async def test_suspend_resume__clear_on_resume(self): time_now = monotonic() await queue.put(2) assert monotonic() - time_now > 0.1 - await queue.get() == 2 + assert await queue.get() == 2 @pytest.mark.asyncio async def test_suspend_resume__initially_suspended(self): diff --git a/t/unit/test_services.py b/t/unit/test_services.py index cca479ff..ce23ee9d 100644 --- a/t/unit/test_services.py +++ b/t/unit/test_services.py @@ -1,5 +1,4 @@ import asyncio -from time import sleep from typing import ContextManager import pytest From 5b98293c5a74068dedab26bf6614dd6f9b5f2847 Mon Sep 17 00:00:00 2001 From: Taybin Rutkin Date: Wed, 13 Oct 2021 12:57:27 -0400 Subject: [PATCH 8/9] fix typecheck linter --- mode/utils/logging.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mode/utils/logging.py b/mode/utils/logging.py index 1863f46c..96519f08 100644 --- a/mode/utils/logging.py +++ b/mode/utils/logging.py @@ -319,7 +319,7 @@ def format(self, record: logging.LogRecord) -> str: return super().format(record) -class ExtensionFormatter(colorlog.TTYColoredFormatter): # type: ignore +class ExtensionFormatter(colorlog.TTYColoredFormatter): """Formatter that can register callbacks to format args. Extends :pypi:`colorlog`. @@ -331,7 +331,7 @@ def __init__(self, stream: IO = None, **kwargs: Any) -> None: def format(self, record: logging.LogRecord) -> str: self._format_args(record) record.extra = _format_extra(record) # type: ignore - return cast(str, super().format(record)) + return cast(str, super().format(record)) # type: ignore def _format_args(self, record: logging.LogRecord) -> None: format_arg = self.format_arg From 79dd6305e0aedb258d40e5429c9934e50709a805 Mon Sep 17 00:00:00 2001 From: Taybin Rutkin Date: Wed, 13 Oct 2021 13:12:00 -0400 Subject: [PATCH 9/9] test 3.9.6 on focal and ignore 3.9.1 --- .travis.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index d29d0c4b..2563f7ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -142,18 +142,15 @@ matrix: os: linux dist: focal stage: test - - python: 3.9.1 - env: TOXENV=3.9 IDENT="3.9.1" RUN_SUITE=y - os: linux - dist: xenial - stage: test - - python: 3.9.6 - env: TOXENV=3.9 IDENT="3.9.6" RUN_SUITE=y + - name: Latest python-3.9 + python: 3.9 + env: TOXENV=3.9 IDENT="3.9" RUN_SUITE=y os: linux dist: bionic stage: test - - python: 3.10.0 - env: TOXENV=3.10 IDENT="3.10.0" RUN_SUITE=y + - name: Latest python-3.10 + python: 3.10.0 + env: TOXENV=3.10 IDENT="3.10" RUN_SUITE=y os: linux dist: bionic stage: test