diff --git a/.flake8 b/.flake8 index 7364f2cd..b4fa48c5 100644 --- a/.flake8 +++ b/.flake8 @@ -14,6 +14,9 @@ per-file-ignores = tests/*:S101 # I900: Requirements for examples shouldn't be included examples/*:I900 + # I900: flake8-requirements doesn't see aioredis in the requirements file cause it is extra dependency + aiohttp_session/redis_storage.py:I900 + build/*:I900 # flake8-import-order import-order-style = pycharm diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 46da005e..7deff070 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -37,11 +37,11 @@ jobs: # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. - + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality - + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild @@ -50,7 +50,7 @@ jobs: # ℹī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - # If the Autobuild fails above, remove it and uncomment the following three lines. + # If the Autobuild fails above, remove it and uncomment the following three lines. # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. # - run: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f801b014..64ce69c7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,85 +1,85 @@ repos: -- repo: local - hooks: - - id: changelogs-rst - name: changelog filenames - language: fail - entry: >- - Changelog files must be named - ####.(bugfix|feature|removal|doc|misc)(.#)?(.rst)? - exclude: >- - ^CHANGES/(\.TEMPLATE\.rst|\.gitignore|\d+\.(bugfix|feature|removal|doc|misc)(\.\d+)?(\.rst)?|README\.rst)$ - files: ^CHANGES/ - - id: changelogs-user-role - name: Changelog files should use a non-broken :user:`name` role - language: pygrep - entry: :user:([^`]+`?|`[^`]+[\s,]) - pass_filenames: true - types: [file, rst] -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.3.0' - hooks: - - id: check-merge-conflict -- repo: https://github.com/asottile/yesqa - rev: v1.4.0 - hooks: - - id: yesqa -- repo: https://github.com/PyCQA/isort - rev: '5.10.1' - hooks: - - id: isort -- repo: https://github.com/psf/black - rev: '22.10.0' - hooks: - - id: black - language_version: python3 -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.3.0' - hooks: - - id: end-of-file-fixer - exclude: >- - ^docs/[^/]*\.svg$ - - id: requirements-txt-fixer - exclude: >- - ^requirements/constraints[.]txt$ - - id: trailing-whitespace - - id: file-contents-sorter - files: | - CONTRIBUTORS.txt| - docs/spelling_wordlist.txt| - .gitignore| - .gitattributes - - id: check-case-conflict - - id: check-json - - id: check-xml - - id: check-executables-have-shebangs - - id: check-toml - - id: check-yaml - - id: debug-statements - - id: check-added-large-files - - id: check-symlinks - - id: fix-byte-order-marker - - id: fix-encoding-pragma - args: ['--remove'] - - id: detect-aws-credentials - args: ['--allow-missing-credentials'] - - id: detect-private-key - exclude: ^examples/ -- repo: https://github.com/asottile/pyupgrade - rev: 'v3.1.0' - hooks: - - id: pyupgrade - args: ['--py38-plus'] -- repo: https://github.com/PyCQA/flake8 - rev: '5.0.4' - hooks: - - id: flake8 - exclude: "^docs/" -- repo: https://github.com/Lucas-C/pre-commit-hooks-markup - rev: v1.0.1 - hooks: - - id: rst-linter - files: >- - ^[^/]+[.]rst$ - exclude: >- - ^CHANGES\.rst$ + - repo: local + hooks: + - id: changelogs-rst + name: changelog filenames + language: fail + entry: >- + Changelog files must be named + ####.(bugfix|feature|removal|doc|misc)(.#)?(.rst)? + exclude: >- + ^CHANGES/(\.TEMPLATE\.rst|\.gitignore|\d+\.(bugfix|feature|removal|doc|misc)(\.\d+)?(\.rst)?|README\.rst)$ + files: ^CHANGES/ + - id: changelogs-user-role + name: Changelog files should use a non-broken :user:`name` role + language: pygrep + entry: :user:([^`]+`?|`[^`]+[\s,]) + pass_filenames: true + types: [file, rst] + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: "v4.3.0" + hooks: + - id: check-merge-conflict + - repo: https://github.com/asottile/yesqa + rev: v1.4.0 + hooks: + - id: yesqa + - repo: https://github.com/PyCQA/isort + rev: "5.13.2" + hooks: + - id: isort + - repo: https://github.com/psf/black + rev: "22.10.0" + hooks: + - id: black + language_version: python3 + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: "v4.3.0" + hooks: + - id: end-of-file-fixer + exclude: >- + ^docs/[^/]*\.svg$ + - id: requirements-txt-fixer + exclude: >- + ^requirements/constraints[.]txt$ + - id: trailing-whitespace + - id: file-contents-sorter + files: | + CONTRIBUTORS.txt| + docs/spelling_wordlist.txt| + .gitignore| + .gitattributes + - id: check-case-conflict + - id: check-json + - id: check-xml + - id: check-executables-have-shebangs + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: check-added-large-files + - id: check-symlinks + - id: fix-byte-order-marker + - id: fix-encoding-pragma + args: ["--remove"] + - id: detect-aws-credentials + args: ["--allow-missing-credentials"] + - id: detect-private-key + exclude: ^examples/ + - repo: https://github.com/asottile/pyupgrade + rev: "v3.1.0" + hooks: + - id: pyupgrade + args: ["--py38-plus"] + - repo: https://github.com/PyCQA/flake8 + rev: "7.1.1" + hooks: + - id: flake8 + exclude: "^docs/" + - repo: https://github.com/Lucas-C/pre-commit-hooks-markup + rev: v1.0.1 + hooks: + - id: rst-linter + files: >- + ^[^/]+[.]rst$ + exclude: >- + ^CHANGES\.rst$ diff --git a/aiohttp_session/redis_storage.py b/aiohttp_session/redis_storage.py index b48455c7..dd8758fe 100644 --- a/aiohttp_session/redis_storage.py +++ b/aiohttp_session/redis_storage.py @@ -10,13 +10,17 @@ from redis import VERSION as REDIS_VERSION, asyncio as aioredis except ImportError: # pragma: no cover try: - import aioredis # type: ignore[import-not-found, no-redef] # noqa: I900 + import aioredis # type: ignore[import-not-found, no-redef] except ImportError: aioredis = None # type: ignore[assignment] else: import warnings - warnings.warn("aioredis library is deprecated, please replace with redis.", - DeprecationWarning, stacklevel=1) + + warnings.warn( + "aioredis library is deprecated, please replace with redis.", + DeprecationWarning, + stacklevel=1, + ) REDIS_VERSION = (4, 3) diff --git a/demo/flash_messages_example.py b/demo/flash_messages_example.py index 199a1d55..e5efde08 100644 --- a/demo/flash_messages_example.py +++ b/demo/flash_messages_example.py @@ -1,5 +1,5 @@ import base64 -from typing import Awaitable, Callable, List, NoReturn, cast +from typing import List, NoReturn, cast from aiohttp import web from aiohttp.typedefs import Handler @@ -18,7 +18,9 @@ def get_messages(request: web.Request) -> List[str]: @web.middleware -async def flash_middleware(request: web.Request, handler: Handler) -> web.StreamResponse: +async def flash_middleware( + request: web.Request, handler: Handler +) -> web.StreamResponse: session = await get_session(request) request["flash_incoming"] = session.pop("flash", []) try: diff --git a/demo/login_required_example.py b/demo/login_required_example.py index b9eeb226..a8afdce6 100644 --- a/demo/login_required_example.py +++ b/demo/login_required_example.py @@ -15,6 +15,7 @@ user_key = web.AppKey("user", str) + def login_required(fn: _Handler) -> _Handler: async def wrapped( request: web.Request, *args: Any, **kwargs: Any diff --git a/demo/redis_storage.py b/demo/redis_storage.py index ef7d5ae6..07da0429 100644 --- a/demo/redis_storage.py +++ b/demo/redis_storage.py @@ -18,7 +18,9 @@ async def handler(request: web.Request) -> web.Response: async def redis_pool(app: web.Application) -> AsyncIterator[None]: redis_address = "redis://127.0.0.1:6379" - async with aioredis.from_url(redis_address) as redis: # type: ignore[no-untyped-call] + async with aioredis.from_url( + redis_address, + ) as redis: # type: ignore[no-untyped-call] storage = RedisStorage(redis) setup(app, storage) yield diff --git a/tests/conftest.py b/tests/conftest.py index 30f22542..4f651129 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,5 @@ from __future__ import annotations -import asyncio -import gc import socket import sys import time @@ -83,7 +81,9 @@ async def redis_server( # type: ignore[misc] # No docker types. delay = 0.1 for _i in range(20): # pragma: no cover try: - conn = aioredis.from_url(f"redis://{host}:{port}") # type: ignore[no-untyped-call] + conn = aioredis.from_url( + f"redis://{host}:{port}", + ) # type: ignore[no-untyped-call] await conn.set("foo", "bar") break except aioredis.ConnectionError: @@ -179,7 +179,9 @@ def memcached_params( # type: ignore[misc] @pytest.fixture -async def memcached(memcached_params: _MemcachedParams) -> AsyncIterator[aiomcache.Client]: +async def memcached( + memcached_params: _MemcachedParams, +) -> AsyncIterator[aiomcache.Client]: conn = aiomcache.Client(**memcached_params) yield conn await conn.close() diff --git a/tests/test_encrypted_cookie_storage.py b/tests/test_encrypted_cookie_storage.py index 31471afe..bd7d5f5c 100644 --- a/tests/test_encrypted_cookie_storage.py +++ b/tests/test_encrypted_cookie_storage.py @@ -10,12 +10,7 @@ from aiohttp.typedefs import Handler from cryptography.fernet import Fernet -from aiohttp_session import ( - Session, - get_session, - new_session, - session_middleware, -) +from aiohttp_session import Session, get_session, new_session, session_middleware from aiohttp_session.cookie_storage import EncryptedCookieStorage from .typedefs import AiohttpClient @@ -42,7 +37,7 @@ def create_app( def decrypt(fernet: Fernet, cookie_value: str) -> Dict[str, Any]: - assert type(cookie_value) == str + assert type(cookie_value) == str # noqa: E721 cookie_value = fernet.decrypt(cookie_value.encode("utf-8")).decode("utf-8") return cast(Dict[str, Any], json.loads(cookie_value)) diff --git a/tests/test_get_session.py b/tests/test_get_session.py index fa0a5e15..dc8507fc 100644 --- a/tests/test_get_session.py +++ b/tests/test_get_session.py @@ -46,7 +46,7 @@ async def test_get_new_session() -> None: session = Session("identity", data=None, new=False) class Storage(AbstractStorage): - async def load_session(self, request: web.Request) -> Session: # type: ignore[empty-body] + async def load_session(self, request: web.Request) -> Session: # type: ignore[empty-body] # noqa: E501 """Dummy""" async def save_session( @@ -77,7 +77,7 @@ class Storage(AbstractStorage): async def new_session(self) -> Session: return "" # type: ignore[return-value] - async def load_session(self, request: web.Request) -> Session: # type: ignore[empty-body] + async def load_session(self, request: web.Request) -> Session: # type: ignore[empty-body] # noqa: E501 """Dummy""" async def save_session( diff --git a/tests/test_http_exception.py b/tests/test_http_exception.py index 7d2e473e..01bf0a85 100644 --- a/tests/test_http_exception.py +++ b/tests/test_http_exception.py @@ -3,11 +3,7 @@ from aiohttp import web from aiohttp.typedefs import Handler -from aiohttp_session import ( - SimpleCookieStorage, - get_session, - session_middleware, -) +from aiohttp_session import SimpleCookieStorage, get_session, session_middleware from .typedefs import AiohttpClient diff --git a/tests/test_nacl_storage.py b/tests/test_nacl_storage.py index baa47d12..61e941d8 100644 --- a/tests/test_nacl_storage.py +++ b/tests/test_nacl_storage.py @@ -11,12 +11,7 @@ from aiohttp.typedefs import Handler from nacl.encoding import Base64Encoder -from aiohttp_session import ( - Session, - get_session, - new_session, - session_middleware, -) +from aiohttp_session import Session, get_session, new_session, session_middleware from aiohttp_session.nacl_storage import NaClCookieStorage from .typedefs import AiohttpClient @@ -49,7 +44,7 @@ def create_app( def decrypt(secretbox: nacl.secret.SecretBox, cookie_value: str) -> Any: - assert type(cookie_value) == str + assert type(cookie_value) == str # noqa: E721 return json.loads( secretbox.decrypt(cookie_value.encode("utf-8"), encoder=Base64Encoder).decode( "utf-8" diff --git a/tests/test_redis_storage.py b/tests/test_redis_storage.py index 4c72b59b..9a2f133b 100644 --- a/tests/test_redis_storage.py +++ b/tests/test_redis_storage.py @@ -4,7 +4,7 @@ import json import time import uuid -from typing import Any, Callable, Dict, MutableMapping, Optional, cast +from typing import Any, Callable, MutableMapping, cast import pytest from aiohttp import web @@ -22,7 +22,7 @@ def create_app( handler: Handler, redis: aioredis.Redis, - max_age: Optional[int] = None, + max_age: int | None = None, key_factory: Callable[[], str] = lambda: uuid.uuid4().hex, ) -> web.Application: middleware = session_middleware( @@ -34,7 +34,7 @@ def create_app( async def make_cookie( - client: TestClient, redis: aioredis.Redis, data: Dict[Any, Any] + client: TestClient, redis: aioredis.Redis, data: dict[Any, Any] ) -> None: session_data = {"session": data, "created": int(time.time())} value = json.dumps(session_data)