]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
tooling: pyright strict checking, black reconfiguration for longer lines, automatic...
authorVasek Sraier <git@vakabus.cz>
Fri, 26 Mar 2021 22:38:51 +0000 (23:38 +0100)
committerAleš Mrázek <ales.mrazek@nic.cz>
Fri, 8 Apr 2022 14:17:52 +0000 (16:17 +0200)
44 files changed:
manager/.gitignore
manager/integration/runner.py
manager/integration/tests/basic_startup/send_request.py
manager/integration/tests/worker_count/run_test.py
manager/knot_resolver_manager/__main__.py
manager/knot_resolver_manager/compat/__init__.py
manager/knot_resolver_manager/compat/asyncio.py
manager/knot_resolver_manager/compat/dataclasses.py
manager/knot_resolver_manager/configuration.py
manager/knot_resolver_manager/kres_manager.py
manager/knot_resolver_manager/systemd.py
manager/knot_resolver_manager/utils/__init__.py
manager/knot_resolver_manager/utils/dataclasses_yaml.py
manager/knot_resolver_manager/utils/types.py [new file with mode: 0644]
manager/poetry.lock
manager/pyproject.toml
manager/pyrightconfig.json
manager/scripts/container-run.py
manager/tests/utils/test_dataclasses_yaml.py
manager/tests/utils/test_dataclasses_yaml_inheritance.py
manager/typings/READMEmd [new file with mode: 0644]
manager/typings/jinja2/__init__.pyi [new file with mode: 0644]
manager/typings/jinja2/_compat.pyi [new file with mode: 0644]
manager/typings/jinja2/_stringdefs.pyi [new file with mode: 0644]
manager/typings/jinja2/bccache.pyi [new file with mode: 0644]
manager/typings/jinja2/compiler.pyi [new file with mode: 0644]
manager/typings/jinja2/constants.pyi [new file with mode: 0644]
manager/typings/jinja2/debug.pyi [new file with mode: 0644]
manager/typings/jinja2/defaults.pyi [new file with mode: 0644]
manager/typings/jinja2/environment.pyi [new file with mode: 0644]
manager/typings/jinja2/exceptions.pyi [new file with mode: 0644]
manager/typings/jinja2/ext.pyi [new file with mode: 0644]
manager/typings/jinja2/filters.pyi [new file with mode: 0644]
manager/typings/jinja2/lexer.pyi [new file with mode: 0644]
manager/typings/jinja2/loaders.pyi [new file with mode: 0644]
manager/typings/jinja2/meta.pyi [new file with mode: 0644]
manager/typings/jinja2/nodes.pyi [new file with mode: 0644]
manager/typings/jinja2/optimizer.pyi [new file with mode: 0644]
manager/typings/jinja2/parser.pyi [new file with mode: 0644]
manager/typings/jinja2/runtime.pyi [new file with mode: 0644]
manager/typings/jinja2/sandbox.pyi [new file with mode: 0644]
manager/typings/jinja2/tests.pyi [new file with mode: 0644]
manager/typings/jinja2/utils.pyi [new file with mode: 0644]
manager/typings/jinja2/visitor.pyi [new file with mode: 0644]

index ff1cdbf6e481ba178209a9668e64e4da8d043e62..8cce37b0f072124a8090f7e23f80fb707ca274de 100644 (file)
@@ -7,4 +7,5 @@ yarn.lock
 package-lock.json
 .pytype
 dist/
-.tox/
\ No newline at end of file
+.tox/
+.vscode/
\ No newline at end of file
index 6955e2bd8e174b082ba75255467fc6428de6c030..bd9c7517fabe6e8a02e8200c6226e8f5f5f03ef4 100644 (file)
@@ -1,21 +1,20 @@
-import subprocess
-import signal
-import uuid
-from typing import Optional, List, BinaryIO, Dict
+import hashlib
+import json
+import os
 import shutil
+import signal
+import subprocess
+import sys
 import tarfile
-import os
 import time
-import sys
-import requests
-import hashlib
-import click
-import json
-import toml
-
+import uuid
 from _hashlib import HASH as Hash
 from pathlib import Path, PurePath
-from typing import Union
+from typing import BinaryIO, Dict, List, Optional, Union
+
+import click
+import requests
+import toml
 
 
 class DirectoryHash:
index eb9b318587bc1f10807bc225f19d094c74d54b47..5c9d8142f4fe94c36e02d5ede84e46b2edad9b6e 100644 (file)
@@ -40,4 +40,4 @@ lua_config: |
 
 # send the config
 r = requests.post('http+unix://%2Ftmp%2Fmanager.sock/config', data=PAYLOAD)
-r.raise_for_status()
\ No newline at end of file
+r.raise_for_status()
index 40fd7b4bca6cb414a92c8e54ea341d09491ebe1f..12eac1d8e00b45bcad2a378fd5919e48a0d523e0 100644 (file)
@@ -1,11 +1,12 @@
 
 
 
-import requests
-import requests_unixsocket
 import subprocess
 import time
 
+import requests
+import requests_unixsocket
+
 # patch requests library so that it supports unix socket
 requests_unixsocket.monkeypatch()
 
@@ -65,4 +66,4 @@ print("Decreasing worker count to 4")
 set_workers(4)
 time.sleep(2)
 count = count_running()
-assert count == 4, f"Unexpected number of kresd instances is running - {count}"
\ No newline at end of file
+assert count == 4, f"Unexpected number of kresd instances is running - {count}"
index 14e5c66b4ea72c9c178f4779740a89b286eb7a7b..8e5691f886d8180b8a41fc8e5793f78b17319374 100644 (file)
@@ -1,13 +1,13 @@
-from typing import Optional
-from pathlib import Path
 import sys
+from pathlib import Path
+from typing import Optional
 
-from aiohttp import web
 import click
+from aiohttp import web
 
 from .kres_manager import KresManager
-from .utils import ignore_exceptions
 from . import configuration
+from .utils import ignore_exceptions
 
 # when changing this, change the help message in main()
 _SOCKET_PATH = "/tmp/manager.sock"
@@ -38,7 +38,7 @@ def main(listen: Optional[str]):
     manager = KresManager()
     app["kres_manager"] = manager
 
-    async def init_manager(app):
+    async def init_manager(app: web.Application):
         await app["kres_manager"].load_system_state()
 
     app.on_startup.append(init_manager)
index efb04f4633841c047f85b684eb8632e7cbda26d5..410074cda76e5903d76f577733427bf0c0e6a113 100644 (file)
@@ -1,5 +1,3 @@
-from . import asyncio
-from . import dataclasses
-
+from . import asyncio, dataclasses
 
 __all__ = ["asyncio", "dataclasses"]
index 331e180ba3f877242f5436f813f18826fceb8c10..e35ed233091b09b989e84c1b7b2635f86024d34e 100644 (file)
@@ -1,13 +1,25 @@
-# pylint: disable=E1101
+# We disable pylint checks, because it can't find methods in newer Python versions.
+#
+# pylint: disable=no-member
+
+# We disable pyright checks because it can't find method that don't exist in this Python version
+# so the reported error is correct, but due to the version checking conditions, it never happens
+#
+# pyright: reportUnknownMemberType=false
+# pyright: reportUnknownVariableType=false
+# pyright: reportGeneralTypeIssues=false
 
-from asyncio.futures import Future
-import sys
 import asyncio
 import functools
-from typing import Awaitable, Coroutine
+import sys
+from typing import Any, Awaitable, Callable, Coroutine, Optional, TypeVar
+
+from knot_resolver_manager.utils.types import NoneType
+
+T = TypeVar("T")
 
 
-def to_thread(func, *args, **kwargs) -> Awaitable:
+def to_thread(func: Callable[..., T], *args: Any, **kwargs: Any) -> Awaitable[T]:
     # version 3.9 and higher, call directly
     if sys.version_info.major >= 3 and sys.version_info.minor >= 9:
         return asyncio.to_thread(func, *args, **kwargs)
@@ -19,7 +31,7 @@ def to_thread(func, *args, **kwargs) -> Awaitable:
         return loop.run_in_executor(None, pfunc)
 
 
-def create_task(coro: Coroutine, name=None) -> Future:
+def create_task(coro: Coroutine[Any, T, NoneType], name: Optional[str] = None) -> Awaitable[T]:
     # version 3.8 and higher, call directly
     if sys.version_info.major >= 3 and sys.version_info.minor >= 8:
         return asyncio.create_task(coro, name=name)
@@ -33,7 +45,7 @@ def create_task(coro: Coroutine, name=None) -> Future:
         return asyncio.ensure_future(coro)
 
 
-def run(coro: Coroutine, debug=None) -> Awaitable:
+def run(coro: Coroutine[Any, T, NoneType], debug: Optional[bool] = None) -> Awaitable[T]:
     # ideally copy-paste of this:
     # https://github.com/python/cpython/blob/3.9/Lib/asyncio/runners.py#L8
 
index 403141d036cd96c0a0fb73cbe55624667f2443ba..09c41110b4b026c216f2f80c6fa14cc6c0a4e6d8 100644 (file)
@@ -9,5 +9,4 @@ the option to do it transparently, without changing anything else.
 
 from dataclasses import dataclass
 
-
 __all__ = ["dataclass"]
index 897859d7f94652adf61bd1130775971c50bb2dd8..3e325d5e3fdfac7b4f0620f04db0ebf3b268f017 100644 (file)
@@ -1,5 +1,6 @@
 from typing import Text
-from jinja2 import Environment
+
+from jinja2 import Environment, Template
 
 from .datamodel import ConfData
 
@@ -10,7 +11,7 @@ _LUA_TEMPLATE_STR = """
 """
 
 _ENV = Environment(enable_async=True)
-_LUA_TEMPLATE = _ENV.from_string(_LUA_TEMPLATE_STR)
+_LUA_TEMPLATE: Template = _ENV.from_string(_LUA_TEMPLATE_STR)
 
 
 async def render_lua(config: ConfData) -> Text:
index 828d62a4ddc3df9c842b0ac220e4cbed86dac2bb..a107ab43377e241e88500c35c1ce9fa92ae6abd4 100644 (file)
@@ -1,10 +1,8 @@
 import asyncio
-from uuid import uuid4
 from typing import List, Optional
+from uuid import uuid4
 
-from . import compat
-from . import systemd
-from . import configuration
+from . import compat, configuration, systemd
 from .datamodel import ConfData
 
 
@@ -26,9 +24,7 @@ class Kresd:
         await compat.asyncio.to_thread(systemd.stop_unit, f"kresd@{self._id}.service")
 
     async def restart(self):
-        await compat.asyncio.to_thread(
-            systemd.restart_unit, f"kresd@{self._id}.service"
-        )
+        await compat.asyncio.to_thread(systemd.restart_unit, f"kresd@{self._id}.service")
 
     def mark_for_restart(self):
         self._needs_restart = True
index e526f1444f95e997ea34fc4fbd2c7dc062f48433..30707ecbf0b5e0e0a55436b3d50440bb4d5612d4 100644 (file)
@@ -1,9 +1,12 @@
+# pyright: reportUnknownMemberType=false
+# pyright: reportMissingTypeStubs=false
+
 from threading import Thread
-from typing import List, Union
-from typing_extensions import Literal
+from typing import Any, List, Union
 
-from pydbus import SystemBus
 from gi.repository import GLib
+from pydbus import SystemBus
+from typing_extensions import Literal
 
 # ugly global result variable, but this module will be used once in a every
 # process, so we should get away with it
@@ -16,33 +19,31 @@ class SystemdException(Exception):
     pass
 
 
-def _create_manager_interface():
-    bus = SystemBus()
+def _create_manager_interface() -> Any:
+    bus: Any = SystemBus()
     systemd = bus.get(".systemd1")
     return systemd
 
 
-def _wait_for_job_completion(systemd, job):
+def _wait_for_job_completion(systemd: Any, job: Any):
     def event_loop_isolation_thread():
         global result_state
 
-        loop = GLib.MainLoop()
+        loop: Any = GLib.MainLoop()
         systemd.JobRemoved.connect(_wait_for_job_completion_handler(loop, job))
         result_state = None
         loop.run()
 
         if result_state != "done":
-            raise SystemdException(
-                f"Job completed with state '{result_state}' instead of expected 'done'"
-            )
+            raise SystemdException(f"Job completed with state '{result_state}' instead of expected 'done'")
 
     thread = Thread(target=event_loop_isolation_thread)
     thread.start()
     thread.join()
 
 
-def _wait_for_job_completion_handler(loop, job_path):
-    def event_hander(_job_id, path, _unit, state):
+def _wait_for_job_completion_handler(loop: Any, job_path: Any) -> Any:
+    def event_hander(_job_id: Any, path: Any, _unit: Any, state: Any):
         global result_state
 
         # if the job is no longer queued, stop the loop
index de056390cdf8b0e0ba72518ca2472377fabf6ed1..9557c9a6d6afd107d87d4e0213ee876221c1010c 100644 (file)
@@ -1,26 +1,27 @@
-from .dataclasses_yaml import (
-    dataclass_strictyaml_schema,
-    dataclass_strictyaml,
-    StrictyamlParser,
-)
+from typing import Any, Callable, Optional, Type, TypeVar
 
+from . import types
+from .dataclasses_yaml import StrictyamlParser, dataclass_strictyaml, dataclass_strictyaml_schema
 
-def ignore_exceptions(default, *exception):
-    def decorator(func):
-        def f(*nargs, **nkwargs):
+T = TypeVar("T")
+
+
+def ignore_exceptions(
+    default: Optional[T], *exceptions: Type[BaseException]
+) -> Callable[[Callable[..., Optional[T]]], Callable[..., Optional[T]]]:
+    def decorator(func: Callable[..., Optional[T]]) -> Callable[..., Optional[T]]:
+        def f(*nargs: Any, **nkwargs: Any) -> Optional[T]:
             try:
                 return func(*nargs, **nkwargs)
-            except exception:
-                return default
+            except BaseException as e:
+                if isinstance(e, exceptions):  # pyright: reportUnnecessaryIsInstance=false
+                    return default
+                else:
+                    raise e
 
         return f
 
     return decorator
 
 
-__all__ = [
-    "dataclass_strictyaml_schema",
-    "dataclass_strictyaml",
-    "StrictyamlParser",
-    "ignore_exceptions",
-]
+__all__ = ["dataclass_strictyaml_schema", "dataclass_strictyaml", "StrictyamlParser", "ignore_exceptions", "types"]
index 115933e7b1de456349269776dcb6cb00baa4abac..005cd60a083c124f88489fc0ec2b3d4e6a24b02e 100644 (file)
@@ -1,17 +1,7 @@
-from typing import Any, List, Dict, Tuple, Type, TypeVar, Union
-from strictyaml import (
-    Map,
-    Str,
-    EmptyDict,
-    Int,
-    Float,
-    Seq,
-    MapPattern,
-    FixedSeq,
-    load,
-    YAML,
-)
+from typing import Any, Dict, List, Tuple, Type, TypeVar, Union
+
 import strictyaml
+from strictyaml import YAML, EmptyDict, FixedSeq, Float, Int, Map, MapPattern, Seq, Str, load
 
 
 class _DummyType:
@@ -74,9 +64,7 @@ def _get_strictyaml_type(python_type):
 
     # error handlers for non existent primitive types
     elif python_type not in _TYPE_MAP:
-        raise StrictYAMLSchemaGenerationError(
-            f"Type {python_type} is not supported for YAML schema generation"
-        )
+        raise StrictYAMLSchemaGenerationError(f"Type {python_type} is not supported for YAML schema generation")
 
     # remaining primitive and untyped types
     else:
@@ -131,8 +119,7 @@ def _yamlobj_to_dataclass(cls, obj: YAML) -> Any:
         # Dict[K, V]
         elif origin == Dict and len(args) == 2:
             return {
-                _yamlobj_to_dataclass(args[0], key): _yamlobj_to_dataclass(args[1], val)
-                for key, val in obj.items()
+                _yamlobj_to_dataclass(args[0], key): _yamlobj_to_dataclass(args[1], val) for key, val in obj.items()
             }
 
         # List[T]
@@ -156,9 +143,7 @@ def _yamlobj_to_dataclass(cls, obj: YAML) -> Any:
     anot = cls.__dict__.get("__annotations__", {})
     kwargs = {}
     for name, python_type in anot.items():
-        kwargs[name] = _yamlobj_to_dataclass(
-            python_type, obj[name] if name in obj else None
-        )
+        kwargs[name] = _yamlobj_to_dataclass(python_type, obj[name] if name in obj else None)
     return cls(**kwargs)
 
 
diff --git a/manager/knot_resolver_manager/utils/types.py b/manager/knot_resolver_manager/utils/types.py
new file mode 100644 (file)
index 0000000..9da0614
--- /dev/null
@@ -0,0 +1 @@
+NoneType = type(None)
index 271f72302cc86dbc48d3662c5e09a322aac1e3bc..fba5323ed4bc96265ac839d191083c1b9e28500a 100644 (file)
@@ -1,6 +1,6 @@
 [[package]]
 name = "aiohttp"
-version = "3.7.3"
+version = "3.7.4.post0"
 description = "Async http client/server framework (asyncio)"
 category = "main"
 optional = false
@@ -9,7 +9,7 @@ python-versions = ">=3.6"
 [package.dependencies]
 async-timeout = ">=3.0,<4.0"
 attrs = ">=17.3.0"
-chardet = ">=2.0,<4.0"
+chardet = ">=2.0,<5.0"
 idna-ssl = {version = ">=1.0", markers = "python_version < \"3.7\""}
 multidict = ">=4.5,<7.0"
 typing-extensions = ">=3.6.5"
@@ -118,11 +118,11 @@ python-versions = "*"
 
 [[package]]
 name = "chardet"
-version = "3.0.4"
+version = "4.0.0"
 description = "Universal encoding detector for Python 2 and 3"
 category = "main"
 optional = false
-python-versions = "*"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [[package]]
 name = "click"
@@ -142,7 +142,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [[package]]
 name = "coverage"
-version = "5.4"
+version = "5.5"
 description = "Code coverage measurement for Python"
 category = "dev"
 optional = false
@@ -218,7 +218,7 @@ flake8 = "*"
 
 [[package]]
 name = "gitdb"
-version = "4.0.5"
+version = "4.0.6"
 description = "Git Object Database"
 category = "dev"
 optional = false
@@ -229,7 +229,7 @@ smmap = ">=3.0.1,<4"
 
 [[package]]
 name = "gitpython"
-version = "3.1.13"
+version = "3.1.14"
 description = "Python Git Library"
 category = "dev"
 optional = false
@@ -259,7 +259,7 @@ idna = ">=2.0"
 
 [[package]]
 name = "importlib-metadata"
-version = "3.4.0"
+version = "3.7.3"
 description = "Read metadata from Python packages"
 category = "dev"
 optional = false
@@ -275,7 +275,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake
 
 [[package]]
 name = "importlib-resources"
-version = "5.1.0"
+version = "5.1.2"
 description = "Read resources from Python packages"
 category = "dev"
 optional = false
@@ -286,7 +286,7 @@ zipp = {version = ">=0.4", markers = "python_version < \"3.8\""}
 
 [package.extras]
 docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
-testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "pytest-black (>=0.3.7)", "pytest-mypy"]
+testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "pytest-black (>=0.3.7)", "pytest-mypy"]
 
 [[package]]
 name = "isort"
@@ -342,7 +342,7 @@ python-versions = "*"
 
 [[package]]
 name = "more-itertools"
-version = "8.6.0"
+version = "8.7.0"
 description = "More routines for operating on iterables, beyond itertools"
 category = "dev"
 optional = false
@@ -358,7 +358,7 @@ python-versions = ">=3.6"
 
 [[package]]
 name = "mypy"
-version = "0.800"
+version = "0.812"
 description = "Optional static typing for Python"
 category = "dev"
 optional = false
@@ -521,11 +521,11 @@ python-versions = "*"
 
 [[package]]
 name = "pydocstyle"
-version = "5.1.1"
+version = "6.0.0"
 description = "Python docstring style checker"
 category = "dev"
 optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.6"
 
 [package.dependencies]
 snowballstemmer = "*"
@@ -540,14 +540,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 
 [[package]]
 name = "pygobject"
-version = "3.38.0"
+version = "3.40.0"
 description = "Python bindings for GObject Introspection"
 category = "main"
 optional = false
-python-versions = ">=3.5, <4"
+python-versions = ">=3.6, <4"
 
 [package.dependencies]
-pycairo = ">=1.11.1"
+pycairo = ">=1.16.0"
 
 [[package]]
 name = "pylint"
@@ -682,7 +682,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
 
 [[package]]
 name = "regex"
-version = "2020.11.13"
+version = "2021.3.17"
 description = "Alternative regular expression module, to replace re."
 category = "dev"
 optional = false
@@ -731,14 +731,14 @@ astroid = ">=1.4"
 
 [[package]]
 name = "ruamel.yaml"
-version = "0.16.12"
+version = "0.17.0"
 description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
 category = "main"
 optional = false
 python-versions = "*"
 
 [package.dependencies]
-"ruamel.yaml.clib" = {version = ">=0.1.2", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.9\""}
+"ruamel.yaml.clib" = {version = ">=0.1.2", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.10\""}
 
 [package.extras]
 docs = ["ryd"]
@@ -829,7 +829,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [[package]]
 name = "tox"
-version = "3.21.4"
+version = "3.23.0"
 description = "tox is a generic virtualenv management and test command line tool"
 category = "dev"
 optional = false
@@ -879,20 +879,20 @@ python-versions = "*"
 
 [[package]]
 name = "urllib3"
-version = "1.26.3"
+version = "1.26.4"
 description = "HTTP library with thread-safe connection pooling, file post, and more."
 category = "dev"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
 
 [package.extras]
-brotli = ["brotlipy (>=0.6.0)"]
 secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
 socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
+brotli = ["brotlipy (>=0.6.0)"]
 
 [[package]]
 name = "virtualenv"
-version = "20.4.2"
+version = "20.4.3"
 description = "Virtual Python Environment builder"
 category = "dev"
 optional = false
@@ -941,15 +941,15 @@ typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""}
 
 [[package]]
 name = "zipp"
-version = "3.4.0"
+version = "3.4.1"
 description = "Backport of pathlib-compatible object wrapper for zip files"
 category = "dev"
 optional = false
 python-versions = ">=3.6"
 
 [package.extras]
-docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
-testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
+docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
+testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
 
 [metadata]
 lock-version = "1.1"
@@ -958,43 +958,43 @@ content-hash = "84b5fb8bb68a208f7a3b4027815766c8c6c2e82681789eacacf5838199b14a3d
 
 [metadata.files]
 aiohttp = [
-    {file = "aiohttp-3.7.3-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:328b552513d4f95b0a2eea4c8573e112866107227661834652a8984766aa7656"},
-    {file = "aiohttp-3.7.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c733ef3bdcfe52a1a75564389bad4064352274036e7e234730526d155f04d914"},
-    {file = "aiohttp-3.7.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:2858b2504c8697beb9357be01dc47ef86438cc1cb36ecb6991796d19475faa3e"},
-    {file = "aiohttp-3.7.3-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:d2cfac21e31e841d60dc28c0ec7d4ec47a35c608cb8906435d47ef83ffb22150"},
-    {file = "aiohttp-3.7.3-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:3228b7a51e3ed533f5472f54f70fd0b0a64c48dc1649a0f0e809bec312934d7a"},
-    {file = "aiohttp-3.7.3-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:dcc119db14757b0c7bce64042158307b9b1c76471e655751a61b57f5a0e4d78e"},
-    {file = "aiohttp-3.7.3-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:7d9b42127a6c0bdcc25c3dcf252bb3ddc70454fac593b1b6933ae091396deb13"},
-    {file = "aiohttp-3.7.3-cp36-cp36m-win32.whl", hash = "sha256:df48a623c58180874d7407b4d9ec06a19b84ed47f60a3884345b1a5099c1818b"},
-    {file = "aiohttp-3.7.3-cp36-cp36m-win_amd64.whl", hash = "sha256:0b795072bb1bf87b8620120a6373a3c61bfcb8da7e5c2377f4bb23ff4f0b62c9"},
-    {file = "aiohttp-3.7.3-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:0d438c8ca703b1b714e82ed5b7a4412c82577040dadff479c08405e2a715564f"},
-    {file = "aiohttp-3.7.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8389d6044ee4e2037dca83e3f6994738550f6ee8cfb746762283fad9b932868f"},
-    {file = "aiohttp-3.7.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3ea8c252d8df5e9166bcf3d9edced2af132f4ead8ac422eac723c5781063709a"},
-    {file = "aiohttp-3.7.3-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:78e2f18a82b88cbc37d22365cf8d2b879a492faedb3f2975adb4ed8dfe994d3a"},
-    {file = "aiohttp-3.7.3-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:df3a7b258cc230a65245167a202dd07320a5af05f3d41da1488ba0fa05bc9347"},
-    {file = "aiohttp-3.7.3-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:f326b3c1bbfda5b9308252ee0dcb30b612ee92b0e105d4abec70335fab5b1245"},
-    {file = "aiohttp-3.7.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:5e479df4b2d0f8f02133b7e4430098699450e1b2a826438af6bec9a400530957"},
-    {file = "aiohttp-3.7.3-cp37-cp37m-win32.whl", hash = "sha256:6d42debaf55450643146fabe4b6817bb2a55b23698b0434107e892a43117285e"},
-    {file = "aiohttp-3.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9c58b0b84055d8bc27b7df5a9d141df4ee6ff59821f922dd73155861282f6a3"},
-    {file = "aiohttp-3.7.3-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:f411cb22115cb15452d099fec0ee636b06cf81bfb40ed9c02d30c8dc2bc2e3d1"},
-    {file = "aiohttp-3.7.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c1e0920909d916d3375c7a1fdb0b1c78e46170e8bb42792312b6eb6676b2f87f"},
-    {file = "aiohttp-3.7.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:59d11674964b74a81b149d4ceaff2b674b3b0e4d0f10f0be1533e49c4a28408b"},
-    {file = "aiohttp-3.7.3-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:41608c0acbe0899c852281978492f9ce2c6fbfaf60aff0cefc54a7c4516b822c"},
-    {file = "aiohttp-3.7.3-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:16a3cb5df5c56f696234ea9e65e227d1ebe9c18aa774d36ff42f532139066a5f"},
-    {file = "aiohttp-3.7.3-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:6ccc43d68b81c424e46192a778f97da94ee0630337c9bbe5b2ecc9b0c1c59001"},
-    {file = "aiohttp-3.7.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:d03abec50df423b026a5aa09656bd9d37f1e6a49271f123f31f9b8aed5dc3ea3"},
-    {file = "aiohttp-3.7.3-cp38-cp38-win32.whl", hash = "sha256:39f4b0a6ae22a1c567cb0630c30dd082481f95c13ca528dc501a7766b9c718c0"},
-    {file = "aiohttp-3.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:c68fdf21c6f3573ae19c7ee65f9ff185649a060c9a06535e9c3a0ee0bbac9235"},
-    {file = "aiohttp-3.7.3-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:710376bf67d8ff4500a31d0c207b8941ff4fba5de6890a701d71680474fe2a60"},
-    {file = "aiohttp-3.7.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2406dc1dda01c7f6060ab586e4601f18affb7a6b965c50a8c90ff07569cf782a"},
-    {file = "aiohttp-3.7.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:2a7b7640167ab536c3cb90cfc3977c7094f1c5890d7eeede8b273c175c3910fd"},
-    {file = "aiohttp-3.7.3-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:684850fb1e3e55c9220aad007f8386d8e3e477c4ec9211ae54d968ecdca8c6f9"},
-    {file = "aiohttp-3.7.3-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:1edfd82a98c5161497bbb111b2b70c0813102ad7e0aa81cbeb34e64c93863005"},
-    {file = "aiohttp-3.7.3-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:77149002d9386fae303a4a162e6bce75cc2161347ad2ba06c2f0182561875d45"},
-    {file = "aiohttp-3.7.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:756ae7efddd68d4ea7d89c636b703e14a0c686688d42f588b90778a3c2fc0564"},
-    {file = "aiohttp-3.7.3-cp39-cp39-win32.whl", hash = "sha256:3b0036c978cbcc4a4512278e98e3e6d9e6b834dc973206162eddf98b586ef1c6"},
-    {file = "aiohttp-3.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:e1b95972a0ae3f248a899cdbac92ba2e01d731225f566569311043ce2226f5e7"},
-    {file = "aiohttp-3.7.3.tar.gz", hash = "sha256:9c1a81af067e72261c9cbe33ea792893e83bc6aa987bfbd6fdc1e5e7b22777c4"},
+    {file = "aiohttp-3.7.4.post0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:3cf75f7cdc2397ed4442594b935a11ed5569961333d49b7539ea741be2cc79d5"},
+    {file = "aiohttp-3.7.4.post0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:4b302b45040890cea949ad092479e01ba25911a15e648429c7c5aae9650c67a8"},
+    {file = "aiohttp-3.7.4.post0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:fe60131d21b31fd1a14bd43e6bb88256f69dfc3188b3a89d736d6c71ed43ec95"},
+    {file = "aiohttp-3.7.4.post0-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:393f389841e8f2dfc86f774ad22f00923fdee66d238af89b70ea314c4aefd290"},
+    {file = "aiohttp-3.7.4.post0-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:c6e9dcb4cb338d91a73f178d866d051efe7c62a7166653a91e7d9fb18274058f"},
+    {file = "aiohttp-3.7.4.post0-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:5df68496d19f849921f05f14f31bd6ef53ad4b00245da3195048c69934521809"},
+    {file = "aiohttp-3.7.4.post0-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:0563c1b3826945eecd62186f3f5c7d31abb7391fedc893b7e2b26303b5a9f3fe"},
+    {file = "aiohttp-3.7.4.post0-cp36-cp36m-win32.whl", hash = "sha256:3d78619672183be860b96ed96f533046ec97ca067fd46ac1f6a09cd9b7484287"},
+    {file = "aiohttp-3.7.4.post0-cp36-cp36m-win_amd64.whl", hash = "sha256:f705e12750171c0ab4ef2a3c76b9a4024a62c4103e3a55dd6f99265b9bc6fcfc"},
+    {file = "aiohttp-3.7.4.post0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:230a8f7e24298dea47659251abc0fd8b3c4e38a664c59d4b89cca7f6c09c9e87"},
+    {file = "aiohttp-3.7.4.post0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2e19413bf84934d651344783c9f5e22dee452e251cfd220ebadbed2d9931dbf0"},
+    {file = "aiohttp-3.7.4.post0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:e4b2b334e68b18ac9817d828ba44d8fcb391f6acb398bcc5062b14b2cbeac970"},
+    {file = "aiohttp-3.7.4.post0-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:d012ad7911653a906425d8473a1465caa9f8dea7fcf07b6d870397b774ea7c0f"},
+    {file = "aiohttp-3.7.4.post0-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:40eced07f07a9e60e825554a31f923e8d3997cfc7fb31dbc1328c70826e04cde"},
+    {file = "aiohttp-3.7.4.post0-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:209b4a8ee987eccc91e2bd3ac36adee0e53a5970b8ac52c273f7f8fd4872c94c"},
+    {file = "aiohttp-3.7.4.post0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:14762875b22d0055f05d12abc7f7d61d5fd4fe4642ce1a249abdf8c700bf1fd8"},
+    {file = "aiohttp-3.7.4.post0-cp37-cp37m-win32.whl", hash = "sha256:7615dab56bb07bff74bc865307aeb89a8bfd9941d2ef9d817b9436da3a0ea54f"},
+    {file = "aiohttp-3.7.4.post0-cp37-cp37m-win_amd64.whl", hash = "sha256:d9e13b33afd39ddeb377eff2c1c4f00544e191e1d1dee5b6c51ddee8ea6f0cf5"},
+    {file = "aiohttp-3.7.4.post0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:547da6cacac20666422d4882cfcd51298d45f7ccb60a04ec27424d2f36ba3eaf"},
+    {file = "aiohttp-3.7.4.post0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:af9aa9ef5ba1fd5b8c948bb11f44891968ab30356d65fd0cc6707d989cd521df"},
+    {file = "aiohttp-3.7.4.post0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:64322071e046020e8797117b3658b9c2f80e3267daec409b350b6a7a05041213"},
+    {file = "aiohttp-3.7.4.post0-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:bb437315738aa441251214dad17428cafda9cdc9729499f1d6001748e1d432f4"},
+    {file = "aiohttp-3.7.4.post0-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:e54962802d4b8b18b6207d4a927032826af39395a3bd9196a5af43fc4e60b009"},
+    {file = "aiohttp-3.7.4.post0-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:a00bb73540af068ca7390e636c01cbc4f644961896fa9363154ff43fd37af2f5"},
+    {file = "aiohttp-3.7.4.post0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:79ebfc238612123a713a457d92afb4096e2148be17df6c50fb9bf7a81c2f8013"},
+    {file = "aiohttp-3.7.4.post0-cp38-cp38-win32.whl", hash = "sha256:515dfef7f869a0feb2afee66b957cc7bbe9ad0cdee45aec7fdc623f4ecd4fb16"},
+    {file = "aiohttp-3.7.4.post0-cp38-cp38-win_amd64.whl", hash = "sha256:114b281e4d68302a324dd33abb04778e8557d88947875cbf4e842c2c01a030c5"},
+    {file = "aiohttp-3.7.4.post0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:7b18b97cf8ee5452fa5f4e3af95d01d84d86d32c5e2bfa260cf041749d66360b"},
+    {file = "aiohttp-3.7.4.post0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:15492a6368d985b76a2a5fdd2166cddfea5d24e69eefed4630cbaae5c81d89bd"},
+    {file = "aiohttp-3.7.4.post0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bdb230b4943891321e06fc7def63c7aace16095be7d9cf3b1e01be2f10fba439"},
+    {file = "aiohttp-3.7.4.post0-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:cffe3ab27871bc3ea47df5d8f7013945712c46a3cc5a95b6bee15887f1675c22"},
+    {file = "aiohttp-3.7.4.post0-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:f881853d2643a29e643609da57b96d5f9c9b93f62429dcc1cbb413c7d07f0e1a"},
+    {file = "aiohttp-3.7.4.post0-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:a5ca29ee66f8343ed336816c553e82d6cade48a3ad702b9ffa6125d187e2dedb"},
+    {file = "aiohttp-3.7.4.post0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:17c073de315745a1510393a96e680d20af8e67e324f70b42accbd4cb3315c9fb"},
+    {file = "aiohttp-3.7.4.post0-cp39-cp39-win32.whl", hash = "sha256:932bb1ea39a54e9ea27fc9232163059a0b8855256f4052e776357ad9add6f1c9"},
+    {file = "aiohttp-3.7.4.post0-cp39-cp39-win_amd64.whl", hash = "sha256:02f46fc0e3c5ac58b80d4d56eb0a7c7d97fcef69ace9326289fb9f1955e65cfe"},
+    {file = "aiohttp-3.7.4.post0.tar.gz", hash = "sha256:493d3299ebe5f5a7c66b9819eacdcfbbaaf1a8e84911ddffcdc48888497afecf"},
 ]
 appdirs = [
     {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
@@ -1028,8 +1028,8 @@ certifi = [
     {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"},
 ]
 chardet = [
-    {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"},
-    {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"},
+    {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"},
+    {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"},
 ]
 click = [
     {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
@@ -1040,55 +1040,58 @@ colorama = [
     {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
 ]
 coverage = [
-    {file = "coverage-5.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:6d9c88b787638a451f41f97446a1c9fd416e669b4d9717ae4615bd29de1ac135"},
-    {file = "coverage-5.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:66a5aae8233d766a877c5ef293ec5ab9520929c2578fd2069308a98b7374ea8c"},
-    {file = "coverage-5.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9754a5c265f991317de2bac0c70a746efc2b695cf4d49f5d2cddeac36544fb44"},
-    {file = "coverage-5.4-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:fbb17c0d0822684b7d6c09915677a32319f16ff1115df5ec05bdcaaee40b35f3"},
-    {file = "coverage-5.4-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:b7f7421841f8db443855d2854e25914a79a1ff48ae92f70d0a5c2f8907ab98c9"},
-    {file = "coverage-5.4-cp27-cp27m-win32.whl", hash = "sha256:4a780807e80479f281d47ee4af2eb2df3e4ccf4723484f77da0bb49d027e40a1"},
-    {file = "coverage-5.4-cp27-cp27m-win_amd64.whl", hash = "sha256:87c4b38288f71acd2106f5d94f575bc2136ea2887fdb5dfe18003c881fa6b370"},
-    {file = "coverage-5.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:c6809ebcbf6c1049002b9ac09c127ae43929042ec1f1dbd8bb1615f7cd9f70a0"},
-    {file = "coverage-5.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ba7ca81b6d60a9f7a0b4b4e175dcc38e8fef4992673d9d6e6879fd6de00dd9b8"},
-    {file = "coverage-5.4-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:89fc12c6371bf963809abc46cced4a01ca4f99cba17be5e7d416ed7ef1245d19"},
-    {file = "coverage-5.4-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a8eb7785bd23565b542b01fb39115a975fefb4a82f23d407503eee2c0106247"},
-    {file = "coverage-5.4-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:7e40d3f8eb472c1509b12ac2a7e24158ec352fc8567b77ab02c0db053927e339"},
-    {file = "coverage-5.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1ccae21a076d3d5f471700f6d30eb486da1626c380b23c70ae32ab823e453337"},
-    {file = "coverage-5.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:755c56beeacac6a24c8e1074f89f34f4373abce8b662470d3aa719ae304931f3"},
-    {file = "coverage-5.4-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:322549b880b2d746a7672bf6ff9ed3f895e9c9f108b714e7360292aa5c5d7cf4"},
-    {file = "coverage-5.4-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:60a3307a84ec60578accd35d7f0c71a3a971430ed7eca6567399d2b50ef37b8c"},
-    {file = "coverage-5.4-cp35-cp35m-win32.whl", hash = "sha256:1375bb8b88cb050a2d4e0da901001347a44302aeadb8ceb4b6e5aa373b8ea68f"},
-    {file = "coverage-5.4-cp35-cp35m-win_amd64.whl", hash = "sha256:16baa799ec09cc0dcb43a10680573269d407c159325972dd7114ee7649e56c66"},
-    {file = "coverage-5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2f2cf7a42d4b7654c9a67b9d091ec24374f7c58794858bff632a2039cb15984d"},
-    {file = "coverage-5.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b62046592b44263fa7570f1117d372ae3f310222af1fc1407416f037fb3af21b"},
-    {file = "coverage-5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:812eaf4939ef2284d29653bcfee9665f11f013724f07258928f849a2306ea9f9"},
-    {file = "coverage-5.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:859f0add98707b182b4867359e12bde806b82483fb12a9ae868a77880fc3b7af"},
-    {file = "coverage-5.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:04b14e45d6a8e159c9767ae57ecb34563ad93440fc1b26516a89ceb5b33c1ad5"},
-    {file = "coverage-5.4-cp36-cp36m-win32.whl", hash = "sha256:ebfa374067af240d079ef97b8064478f3bf71038b78b017eb6ec93ede1b6bcec"},
-    {file = "coverage-5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:84df004223fd0550d0ea7a37882e5c889f3c6d45535c639ce9802293b39cd5c9"},
-    {file = "coverage-5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:1b811662ecf72eb2d08872731636aee6559cae21862c36f74703be727b45df90"},
-    {file = "coverage-5.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6b588b5cf51dc0fd1c9e19f622457cc74b7d26fe295432e434525f1c0fae02bc"},
-    {file = "coverage-5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3fe50f1cac369b02d34ad904dfe0771acc483f82a1b54c5e93632916ba847b37"},
-    {file = "coverage-5.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:32ab83016c24c5cf3db2943286b85b0a172dae08c58d0f53875235219b676409"},
-    {file = "coverage-5.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:68fb816a5dd901c6aff352ce49e2a0ffadacdf9b6fae282a69e7a16a02dad5fb"},
-    {file = "coverage-5.4-cp37-cp37m-win32.whl", hash = "sha256:a636160680c6e526b84f85d304e2f0bb4e94f8284dd765a1911de9a40450b10a"},
-    {file = "coverage-5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:bb32ca14b4d04e172c541c69eec5f385f9a075b38fb22d765d8b0ce3af3a0c22"},
-    {file = "coverage-5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4d7165a4e8f41eca6b990c12ee7f44fef3932fac48ca32cecb3a1b2223c21f"},
-    {file = "coverage-5.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a565f48c4aae72d1d3d3f8e8fb7218f5609c964e9c6f68604608e5958b9c60c3"},
-    {file = "coverage-5.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fff1f3a586246110f34dc762098b5afd2de88de507559e63553d7da643053786"},
-    {file = "coverage-5.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a839e25f07e428a87d17d857d9935dd743130e77ff46524abb992b962eb2076c"},
-    {file = "coverage-5.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:6625e52b6f346a283c3d563d1fd8bae8956daafc64bb5bbd2b8f8a07608e3994"},
-    {file = "coverage-5.4-cp38-cp38-win32.whl", hash = "sha256:5bee3970617b3d74759b2d2df2f6a327d372f9732f9ccbf03fa591b5f7581e39"},
-    {file = "coverage-5.4-cp38-cp38-win_amd64.whl", hash = "sha256:03ed2a641e412e42cc35c244508cf186015c217f0e4d496bf6d7078ebe837ae7"},
-    {file = "coverage-5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:14a9f1887591684fb59fdba8feef7123a0da2424b0652e1b58dd5b9a7bb1188c"},
-    {file = "coverage-5.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9564ac7eb1652c3701ac691ca72934dd3009997c81266807aef924012df2f4b3"},
-    {file = "coverage-5.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:0f48fc7dc82ee14aeaedb986e175a429d24129b7eada1b7e94a864e4f0644dde"},
-    {file = "coverage-5.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:107d327071061fd4f4a2587d14c389a27e4e5c93c7cba5f1f59987181903902f"},
-    {file = "coverage-5.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:0cdde51bfcf6b6bd862ee9be324521ec619b20590787d1655d005c3fb175005f"},
-    {file = "coverage-5.4-cp39-cp39-win32.whl", hash = "sha256:c67734cff78383a1f23ceba3b3239c7deefc62ac2b05fa6a47bcd565771e5880"},
-    {file = "coverage-5.4-cp39-cp39-win_amd64.whl", hash = "sha256:c669b440ce46ae3abe9b2d44a913b5fd86bb19eb14a8701e88e3918902ecd345"},
-    {file = "coverage-5.4-pp36-none-any.whl", hash = "sha256:c0ff1c1b4d13e2240821ef23c1efb1f009207cb3f56e16986f713c2b0e7cd37f"},
-    {file = "coverage-5.4-pp37-none-any.whl", hash = "sha256:cd601187476c6bed26a0398353212684c427e10a903aeafa6da40c63309d438b"},
-    {file = "coverage-5.4.tar.gz", hash = "sha256:6d2e262e5e8da6fa56e774fb8e2643417351427604c2b177f8e8c5f75fc928ca"},
+    {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"},
+    {file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"},
+    {file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"},
+    {file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"},
+    {file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"},
+    {file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"},
+    {file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"},
+    {file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"},
+    {file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"},
+    {file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"},
+    {file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"},
+    {file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"},
+    {file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"},
+    {file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"},
+    {file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"},
+    {file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"},
+    {file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"},
+    {file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"},
+    {file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"},
+    {file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"},
+    {file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"},
+    {file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"},
+    {file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"},
+    {file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"},
+    {file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"},
+    {file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"},
+    {file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"},
+    {file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"},
+    {file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"},
+    {file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"},
+    {file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"},
+    {file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"},
+    {file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"},
+    {file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"},
+    {file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"},
+    {file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"},
+    {file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"},
+    {file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"},
+    {file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"},
+    {file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"},
+    {file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"},
+    {file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"},
+    {file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"},
+    {file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"},
+    {file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"},
+    {file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"},
+    {file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"},
+    {file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"},
+    {file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"},
+    {file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"},
+    {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"},
+    {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"},
 ]
 dataclasses = [
     {file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"},
@@ -1171,12 +1174,12 @@ flake8-polyfill = [
     {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"},
 ]
 gitdb = [
-    {file = "gitdb-4.0.5-py3-none-any.whl", hash = "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac"},
-    {file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"},
+    {file = "gitdb-4.0.6-py3-none-any.whl", hash = "sha256:27dea6c52fbcf768530e1af47f2e34afd24a52e53fa310c8279a5589bd7c85bd"},
+    {file = "gitdb-4.0.6.tar.gz", hash = "sha256:42535bb16b5db8983e2c4f6a714d29a8feba7165a12addc63e08fc672dfeccb9"},
 ]
 gitpython = [
-    {file = "GitPython-3.1.13-py3-none-any.whl", hash = "sha256:c5347c81d232d9b8e7f47b68a83e5dc92e7952127133c5f2df9133f2c75a1b29"},
-    {file = "GitPython-3.1.13.tar.gz", hash = "sha256:8621a7e777e276a5ec838b59280ba5272dd144a18169c36c903d8b38b99f750a"},
+    {file = "GitPython-3.1.14-py3-none-any.whl", hash = "sha256:3283ae2fba31c913d857e12e5ba5f9a7772bbc064ae2bb09efafa71b0dd4939b"},
+    {file = "GitPython-3.1.14.tar.gz", hash = "sha256:be27633e7509e58391f10207cd32b2a6cf5b908f92d9cd30da2e514e1137af61"},
 ]
 idna = [
     {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"},
@@ -1186,12 +1189,12 @@ idna-ssl = [
     {file = "idna-ssl-1.1.0.tar.gz", hash = "sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c"},
 ]
 importlib-metadata = [
-    {file = "importlib_metadata-3.4.0-py3-none-any.whl", hash = "sha256:ace61d5fc652dc280e7b6b4ff732a9c2d40db2c0f92bc6cb74e07b73d53a1771"},
-    {file = "importlib_metadata-3.4.0.tar.gz", hash = "sha256:fa5daa4477a7414ae34e95942e4dd07f62adf589143c875c133c1e53c4eff38d"},
+    {file = "importlib_metadata-3.7.3-py3-none-any.whl", hash = "sha256:b74159469b464a99cb8cc3e21973e4d96e05d3024d337313fedb618a6e86e6f4"},
+    {file = "importlib_metadata-3.7.3.tar.gz", hash = "sha256:742add720a20d0467df2f444ae41704000f50e1234f46174b51f9c6031a1bd71"},
 ]
 importlib-resources = [
-    {file = "importlib_resources-5.1.0-py3-none-any.whl", hash = "sha256:885b8eae589179f661c909d699a546cf10d83692553e34dca1bf5eb06f7f6217"},
-    {file = "importlib_resources-5.1.0.tar.gz", hash = "sha256:bfdad047bce441405a49cf8eb48ddce5e56c696e185f59147a8b79e75e9e6380"},
+    {file = "importlib_resources-5.1.2-py3-none-any.whl", hash = "sha256:ebab3efe74d83b04d6bf5cd9a17f0c5c93e60fb60f30c90f56265fce4682a469"},
+    {file = "importlib_resources-5.1.2.tar.gz", hash = "sha256:642586fc4740bd1cad7690f836b3321309402b20b332529f25617ff18e8e1370"},
 ]
 isort = [
     {file = "isort-4.3.21-py2.py3-none-any.whl", hash = "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"},
@@ -1283,8 +1286,8 @@ mccabe = [
     {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
 ]
 more-itertools = [
-    {file = "more-itertools-8.6.0.tar.gz", hash = "sha256:b3a9005928e5bed54076e6e549c792b306fddfe72b2d1d22dd63d42d5d3899cf"},
-    {file = "more_itertools-8.6.0-py3-none-any.whl", hash = "sha256:8e1a2a43b2f2727425f2b5839587ae37093f19153dc26c0927d1048ff6557330"},
+    {file = "more-itertools-8.7.0.tar.gz", hash = "sha256:c5d6da9ca3ff65220c3bfd2a8db06d698f05d4d2b9be57e1deb2be5a45019713"},
+    {file = "more_itertools-8.7.0-py3-none-any.whl", hash = "sha256:5652a9ac72209ed7df8d9c15daf4e1aa0e3d2ccd3c87f8265a0673cd9cbc9ced"},
 ]
 multidict = [
     {file = "multidict-5.1.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f"},
@@ -1326,28 +1329,28 @@ multidict = [
     {file = "multidict-5.1.0.tar.gz", hash = "sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5"},
 ]
 mypy = [
-    {file = "mypy-0.800-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:e1c84c65ff6d69fb42958ece5b1255394714e0aac4df5ffe151bc4fe19c7600a"},
-    {file = "mypy-0.800-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:947126195bfe4709c360e89b40114c6746ae248f04d379dca6f6ab677aa07641"},
-    {file = "mypy-0.800-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:b95068a3ce3b50332c40e31a955653be245666a4bc7819d3c8898aa9fb9ea496"},
-    {file = "mypy-0.800-cp35-cp35m-win_amd64.whl", hash = "sha256:ca7ad5aed210841f1e77f5f2f7d725b62c78fa77519312042c719ed2ab937876"},
-    {file = "mypy-0.800-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e32b7b282c4ed4e378bba8b8dfa08e1cfa6f6574067ef22f86bee5b1039de0c9"},
-    {file = "mypy-0.800-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:e497a544391f733eca922fdcb326d19e894789cd4ff61d48b4b195776476c5cf"},
-    {file = "mypy-0.800-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:5615785d3e2f4f03ab7697983d82c4b98af5c321614f51b8f1034eb9ebe48363"},
-    {file = "mypy-0.800-cp36-cp36m-win_amd64.whl", hash = "sha256:2b216eacca0ec0ee124af9429bfd858d5619a0725ee5f88057e6e076f9eb1a7b"},
-    {file = "mypy-0.800-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e3b8432f8df19e3c11235c4563a7250666dc9aa7cdda58d21b4177b20256ca9f"},
-    {file = "mypy-0.800-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d16c54b0dffb861dc6318a8730952265876d90c5101085a4bc56913e8521ba19"},
-    {file = "mypy-0.800-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:0d2fc8beb99cd88f2d7e20d69131353053fbecea17904ee6f0348759302c52fa"},
-    {file = "mypy-0.800-cp37-cp37m-win_amd64.whl", hash = "sha256:aa9d4901f3ee1a986a3a79fe079ffbf7f999478c281376f48faa31daaa814e86"},
-    {file = "mypy-0.800-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:319ee5c248a7c3f94477f92a729b7ab06bf8a6d04447ef3aa8c9ba2aa47c6dcf"},
-    {file = "mypy-0.800-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:74f5aa50d0866bc6fb8e213441c41e466c86678c800700b87b012ed11c0a13e0"},
-    {file = "mypy-0.800-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:a301da58d566aca05f8f449403c710c50a9860782148332322decf73a603280b"},
-    {file = "mypy-0.800-cp38-cp38-win_amd64.whl", hash = "sha256:b9150db14a48a8fa114189bfe49baccdff89da8c6639c2717750c7ae62316738"},
-    {file = "mypy-0.800-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5fdf935a46aa20aa937f2478480ebf4be9186e98e49cc3843af9a5795a49a25"},
-    {file = "mypy-0.800-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6f8425fecd2ba6007e526209bb985ce7f49ed0d2ac1cc1a44f243380a06a84fb"},
-    {file = "mypy-0.800-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:5ff616787122774f510caeb7b980542a7cc2222be3f00837a304ea85cd56e488"},
-    {file = "mypy-0.800-cp39-cp39-win_amd64.whl", hash = "sha256:90b6f46dc2181d74f80617deca611925d7e63007cf416397358aa42efb593e07"},
-    {file = "mypy-0.800-py3-none-any.whl", hash = "sha256:3e0c159a7853e3521e3f582adb1f3eac66d0b0639d434278e2867af3a8c62653"},
-    {file = "mypy-0.800.tar.gz", hash = "sha256:e0202e37756ed09daf4b0ba64ad2c245d357659e014c3f51d8cd0681ba66940a"},
+    {file = "mypy-0.812-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a26f8ec704e5a7423c8824d425086705e381b4f1dfdef6e3a1edab7ba174ec49"},
+    {file = "mypy-0.812-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:28fb5479c494b1bab244620685e2eb3c3f988d71fd5d64cc753195e8ed53df7c"},
+    {file = "mypy-0.812-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:9743c91088d396c1a5a3c9978354b61b0382b4e3c440ce83cf77994a43e8c521"},
+    {file = "mypy-0.812-cp35-cp35m-win_amd64.whl", hash = "sha256:d7da2e1d5f558c37d6e8c1246f1aec1e7349e4913d8fb3cb289a35de573fe2eb"},
+    {file = "mypy-0.812-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4eec37370483331d13514c3f55f446fc5248d6373e7029a29ecb7b7494851e7a"},
+    {file = "mypy-0.812-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d65cc1df038ef55a99e617431f0553cd77763869eebdf9042403e16089fe746c"},
+    {file = "mypy-0.812-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:61a3d5b97955422964be6b3baf05ff2ce7f26f52c85dd88db11d5e03e146a3a6"},
+    {file = "mypy-0.812-cp36-cp36m-win_amd64.whl", hash = "sha256:25adde9b862f8f9aac9d2d11971f226bd4c8fbaa89fb76bdadb267ef22d10064"},
+    {file = "mypy-0.812-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:552a815579aa1e995f39fd05dde6cd378e191b063f031f2acfe73ce9fb7f9e56"},
+    {file = "mypy-0.812-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:499c798053cdebcaa916eef8cd733e5584b5909f789de856b482cd7d069bdad8"},
+    {file = "mypy-0.812-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:5873888fff1c7cf5b71efbe80e0e73153fe9212fafdf8e44adfe4c20ec9f82d7"},
+    {file = "mypy-0.812-cp37-cp37m-win_amd64.whl", hash = "sha256:9f94aac67a2045ec719ffe6111df543bac7874cee01f41928f6969756e030564"},
+    {file = "mypy-0.812-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d23e0ea196702d918b60c8288561e722bf437d82cb7ef2edcd98cfa38905d506"},
+    {file = "mypy-0.812-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:674e822aa665b9fd75130c6c5f5ed9564a38c6cea6a6432ce47eafb68ee578c5"},
+    {file = "mypy-0.812-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:abf7e0c3cf117c44d9285cc6128856106183938c68fd4944763003decdcfeb66"},
+    {file = "mypy-0.812-cp38-cp38-win_amd64.whl", hash = "sha256:0d0a87c0e7e3a9becdfbe936c981d32e5ee0ccda3e0f07e1ef2c3d1a817cf73e"},
+    {file = "mypy-0.812-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7ce3175801d0ae5fdfa79b4f0cfed08807af4d075b402b7e294e6aa72af9aa2a"},
+    {file = "mypy-0.812-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:b09669bcda124e83708f34a94606e01b614fa71931d356c1f1a5297ba11f110a"},
+    {file = "mypy-0.812-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:33f159443db0829d16f0a8d83d94df3109bb6dd801975fe86bacb9bf71628e97"},
+    {file = "mypy-0.812-cp39-cp39-win_amd64.whl", hash = "sha256:3f2aca7f68580dc2508289c729bd49ee929a436208d2b2b6aab15745a70a57df"},
+    {file = "mypy-0.812-py3-none-any.whl", hash = "sha256:2f9b3407c58347a452fc0736861593e105139b905cca7d097e413453a1d650b4"},
+    {file = "mypy-0.812.tar.gz", hash = "sha256:cd07039aa5df222037005b08fbbfd69b3ab0b0bd7a07d7906de75ae52c4e3119"},
 ]
 mypy-extensions = [
     {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
@@ -1408,15 +1411,15 @@ pydbus = [
     {file = "pydbus-0.6.0.tar.gz", hash = "sha256:4207162eff54223822c185da06c1ba8a34137a9602f3da5a528eedf3f78d0f2c"},
 ]
 pydocstyle = [
-    {file = "pydocstyle-5.1.1-py3-none-any.whl", hash = "sha256:aca749e190a01726a4fb472dd4ef23b5c9da7b9205c0a7857c06533de13fd678"},
-    {file = "pydocstyle-5.1.1.tar.gz", hash = "sha256:19b86fa8617ed916776a11cd8bc0197e5b9856d5433b777f51a3defe13075325"},
+    {file = "pydocstyle-6.0.0-py3-none-any.whl", hash = "sha256:d4449cf16d7e6709f63192146706933c7a334af7c0f083904799ccb851c50f6d"},
+    {file = "pydocstyle-6.0.0.tar.gz", hash = "sha256:164befb520d851dbcf0e029681b91f4f599c62c5cd8933fd54b1bfbd50e89e1f"},
 ]
 pyflakes = [
     {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"},
     {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"},
 ]
 pygobject = [
-    {file = "PyGObject-3.38.0.tar.gz", hash = "sha256:051b950f509f2e9f125add96c1493bde987c527f7a0c15a1f7b69d6d1c3cd8e6"},
+    {file = "PyGObject-3.40.0.tar.gz", hash = "sha256:98d83f71e6313dadc29793450fec23b2eaa5c3f1c4b073d0a4f9c31b5cdb5fca"},
 ]
 pylint = [
     {file = "pylint-2.5.3-py3-none-any.whl", hash = "sha256:d0ece7d223fe422088b0e8f13fa0a1e8eb745ebffcb8ed53d3e95394b6101a1c"},
@@ -1484,47 +1487,47 @@ pyyaml = [
     {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
 ]
 regex = [
-    {file = "regex-2020.11.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85"},
-    {file = "regex-2020.11.13-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a63f1a07932c9686d2d416fb295ec2c01ab246e89b4d58e5fa468089cab44b70"},
-    {file = "regex-2020.11.13-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6e4b08c6f8daca7d8f07c8d24e4331ae7953333dbd09c648ed6ebd24db5a10ee"},
-    {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bba349276b126947b014e50ab3316c027cac1495992f10e5682dc677b3dfa0c5"},
-    {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:56e01daca75eae420bce184edd8bb341c8eebb19dd3bce7266332258f9fb9dd7"},
-    {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:6a8ce43923c518c24a2579fda49f093f1397dad5d18346211e46f134fc624e31"},
-    {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:1ab79fcb02b930de09c76d024d279686ec5d532eb814fd0ed1e0051eb8bd2daa"},
-    {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:9801c4c1d9ae6a70aeb2128e5b4b68c45d4f0af0d1535500884d644fa9b768c6"},
-    {file = "regex-2020.11.13-cp36-cp36m-win32.whl", hash = "sha256:49cae022fa13f09be91b2c880e58e14b6da5d10639ed45ca69b85faf039f7a4e"},
-    {file = "regex-2020.11.13-cp36-cp36m-win_amd64.whl", hash = "sha256:749078d1eb89484db5f34b4012092ad14b327944ee7f1c4f74d6279a6e4d1884"},
-    {file = "regex-2020.11.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2f4007bff007c96a173e24dcda236e5e83bde4358a557f9ccf5e014439eae4b"},
-    {file = "regex-2020.11.13-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:38c8fd190db64f513fe4e1baa59fed086ae71fa45083b6936b52d34df8f86a88"},
-    {file = "regex-2020.11.13-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5862975b45d451b6db51c2e654990c1820523a5b07100fc6903e9c86575202a0"},
-    {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:262c6825b309e6485ec2493ffc7e62a13cf13fb2a8b6d212f72bd53ad34118f1"},
-    {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bafb01b4688833e099d79e7efd23f99172f501a15c44f21ea2118681473fdba0"},
-    {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:e32f5f3d1b1c663af7f9c4c1e72e6ffe9a78c03a31e149259f531e0fed826512"},
-    {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:3bddc701bdd1efa0d5264d2649588cbfda549b2899dc8d50417e47a82e1387ba"},
-    {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:02951b7dacb123d8ea6da44fe45ddd084aa6777d4b2454fa0da61d569c6fa538"},
-    {file = "regex-2020.11.13-cp37-cp37m-win32.whl", hash = "sha256:0d08e71e70c0237883d0bef12cad5145b84c3705e9c6a588b2a9c7080e5af2a4"},
-    {file = "regex-2020.11.13-cp37-cp37m-win_amd64.whl", hash = "sha256:1fa7ee9c2a0e30405e21031d07d7ba8617bc590d391adfc2b7f1e8b99f46f444"},
-    {file = "regex-2020.11.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:baf378ba6151f6e272824b86a774326f692bc2ef4cc5ce8d5bc76e38c813a55f"},
-    {file = "regex-2020.11.13-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e3faaf10a0d1e8e23a9b51d1900b72e1635c2d5b0e1bea1c18022486a8e2e52d"},
-    {file = "regex-2020.11.13-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2a11a3e90bd9901d70a5b31d7dd85114755a581a5da3fc996abfefa48aee78af"},
-    {file = "regex-2020.11.13-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1ebb090a426db66dd80df8ca85adc4abfcbad8a7c2e9a5ec7513ede522e0a8f"},
-    {file = "regex-2020.11.13-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:b2b1a5ddae3677d89b686e5c625fc5547c6e492bd755b520de5332773a8af06b"},
-    {file = "regex-2020.11.13-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2c99e97d388cd0a8d30f7c514d67887d8021541b875baf09791a3baad48bb4f8"},
-    {file = "regex-2020.11.13-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:c084582d4215593f2f1d28b65d2a2f3aceff8342aa85afd7be23a9cad74a0de5"},
-    {file = "regex-2020.11.13-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:a3d748383762e56337c39ab35c6ed4deb88df5326f97a38946ddd19028ecce6b"},
-    {file = "regex-2020.11.13-cp38-cp38-win32.whl", hash = "sha256:7913bd25f4ab274ba37bc97ad0e21c31004224ccb02765ad984eef43e04acc6c"},
-    {file = "regex-2020.11.13-cp38-cp38-win_amd64.whl", hash = "sha256:6c54ce4b5d61a7129bad5c5dc279e222afd00e721bf92f9ef09e4fae28755683"},
-    {file = "regex-2020.11.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1862a9d9194fae76a7aaf0150d5f2a8ec1da89e8b55890b1786b8f88a0f619dc"},
-    {file = "regex-2020.11.13-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4902e6aa086cbb224241adbc2f06235927d5cdacffb2425c73e6570e8d862364"},
-    {file = "regex-2020.11.13-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7a25fcbeae08f96a754b45bdc050e1fb94b95cab046bf56b016c25e9ab127b3e"},
-    {file = "regex-2020.11.13-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:d2d8ce12b7c12c87e41123997ebaf1a5767a5be3ec545f64675388970f415e2e"},
-    {file = "regex-2020.11.13-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f7d29a6fc4760300f86ae329e3b6ca28ea9c20823df123a2ea8693e967b29917"},
-    {file = "regex-2020.11.13-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:717881211f46de3ab130b58ec0908267961fadc06e44f974466d1887f865bd5b"},
-    {file = "regex-2020.11.13-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3128e30d83f2e70b0bed9b2a34e92707d0877e460b402faca908c6667092ada9"},
-    {file = "regex-2020.11.13-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:8f6a2229e8ad946e36815f2a03386bb8353d4bde368fdf8ca5f0cb97264d3b5c"},
-    {file = "regex-2020.11.13-cp39-cp39-win32.whl", hash = "sha256:f8f295db00ef5f8bae530fc39af0b40486ca6068733fb860b42115052206466f"},
-    {file = "regex-2020.11.13-cp39-cp39-win_amd64.whl", hash = "sha256:a15f64ae3a027b64496a71ab1f722355e570c3fac5ba2801cafce846bf5af01d"},
-    {file = "regex-2020.11.13.tar.gz", hash = "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562"},
+    {file = "regex-2021.3.17-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b97ec5d299c10d96617cc851b2e0f81ba5d9d6248413cd374ef7f3a8871ee4a6"},
+    {file = "regex-2021.3.17-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:cb4ee827857a5ad9b8ae34d3c8cc51151cb4a3fe082c12ec20ec73e63cc7c6f0"},
+    {file = "regex-2021.3.17-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:633497504e2a485a70a3268d4fc403fe3063a50a50eed1039083e9471ad0101c"},
+    {file = "regex-2021.3.17-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:a59a2ee329b3de764b21495d78c92ab00b4ea79acef0f7ae8c1067f773570afa"},
+    {file = "regex-2021.3.17-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:f85d6f41e34f6a2d1607e312820971872944f1661a73d33e1e82d35ea3305e14"},
+    {file = "regex-2021.3.17-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:4651f839dbde0816798e698626af6a2469eee6d9964824bb5386091255a1694f"},
+    {file = "regex-2021.3.17-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:39c44532d0e4f1639a89e52355b949573e1e2c5116106a395642cbbae0ff9bcd"},
+    {file = "regex-2021.3.17-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:3d9a7e215e02bd7646a91fb8bcba30bc55fd42a719d6b35cf80e5bae31d9134e"},
+    {file = "regex-2021.3.17-cp36-cp36m-win32.whl", hash = "sha256:159fac1a4731409c830d32913f13f68346d6b8e39650ed5d704a9ce2f9ef9cb3"},
+    {file = "regex-2021.3.17-cp36-cp36m-win_amd64.whl", hash = "sha256:13f50969028e81765ed2a1c5fcfdc246c245cf8d47986d5172e82ab1a0c42ee5"},
+    {file = "regex-2021.3.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b9d8d286c53fe0cbc6d20bf3d583cabcd1499d89034524e3b94c93a5ab85ca90"},
+    {file = "regex-2021.3.17-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:201e2619a77b21a7780580ab7b5ce43835e242d3e20fef50f66a8df0542e437f"},
+    {file = "regex-2021.3.17-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d47d359545b0ccad29d572ecd52c9da945de7cd6cf9c0cfcb0269f76d3555689"},
+    {file = "regex-2021.3.17-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ea2f41445852c660ba7c3ebf7d70b3779b20d9ca8ba54485a17740db49f46932"},
+    {file = "regex-2021.3.17-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:486a5f8e11e1f5bbfcad87f7c7745eb14796642323e7e1829a331f87a713daaa"},
+    {file = "regex-2021.3.17-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:18e25e0afe1cf0f62781a150c1454b2113785401ba285c745acf10c8ca8917df"},
+    {file = "regex-2021.3.17-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:a2ee026f4156789df8644d23ef423e6194fad0bc53575534101bb1de5d67e8ce"},
+    {file = "regex-2021.3.17-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:4c0788010a93ace8a174d73e7c6c9d3e6e3b7ad99a453c8ee8c975ddd9965643"},
+    {file = "regex-2021.3.17-cp37-cp37m-win32.whl", hash = "sha256:575a832e09d237ae5fedb825a7a5bc6a116090dd57d6417d4f3b75121c73e3be"},
+    {file = "regex-2021.3.17-cp37-cp37m-win_amd64.whl", hash = "sha256:8e65e3e4c6feadf6770e2ad89ad3deb524bcb03d8dc679f381d0568c024e0deb"},
+    {file = "regex-2021.3.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a0df9a0ad2aad49ea3c7f65edd2ffb3d5c59589b85992a6006354f6fb109bb18"},
+    {file = "regex-2021.3.17-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b98bc9db003f1079caf07b610377ed1ac2e2c11acc2bea4892e28cc5b509d8d5"},
+    {file = "regex-2021.3.17-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:808404898e9a765e4058bf3d7607d0629000e0a14a6782ccbb089296b76fa8fe"},
+    {file = "regex-2021.3.17-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:5770a51180d85ea468234bc7987f5597803a4c3d7463e7323322fe4a1b181578"},
+    {file = "regex-2021.3.17-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:976a54d44fd043d958a69b18705a910a8376196c6b6ee5f2596ffc11bff4420d"},
+    {file = "regex-2021.3.17-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:63f3ca8451e5ff7133ffbec9eda641aeab2001be1a01878990f6c87e3c44b9d5"},
+    {file = "regex-2021.3.17-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:bcd945175c29a672f13fce13a11893556cd440e37c1b643d6eeab1988c8b209c"},
+    {file = "regex-2021.3.17-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:3d9356add82cff75413bec360c1eca3e58db4a9f5dafa1f19650958a81e3249d"},
+    {file = "regex-2021.3.17-cp38-cp38-win32.whl", hash = "sha256:f5d0c921c99297354cecc5a416ee4280bd3f20fd81b9fb671ca6be71499c3fdf"},
+    {file = "regex-2021.3.17-cp38-cp38-win_amd64.whl", hash = "sha256:14de88eda0976020528efc92d0a1f8830e2fb0de2ae6005a6fc4e062553031fa"},
+    {file = "regex-2021.3.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4c2e364491406b7888c2ad4428245fc56c327e34a5dfe58fd40df272b3c3dab3"},
+    {file = "regex-2021.3.17-cp39-cp39-manylinux1_i686.whl", hash = "sha256:8bd4f91f3fb1c9b1380d6894bd5b4a519409135bec14c0c80151e58394a4e88a"},
+    {file = "regex-2021.3.17-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:882f53afe31ef0425b405a3f601c0009b44206ea7f55ee1c606aad3cc213a52c"},
+    {file = "regex-2021.3.17-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:07ef35301b4484bce843831e7039a84e19d8d33b3f8b2f9aab86c376813d0139"},
+    {file = "regex-2021.3.17-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:360a01b5fa2ad35b3113ae0c07fb544ad180603fa3b1f074f52d98c1096fa15e"},
+    {file = "regex-2021.3.17-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:709f65bb2fa9825f09892617d01246002097f8f9b6dde8d1bb4083cf554701ba"},
+    {file = "regex-2021.3.17-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:c66221e947d7207457f8b6f42b12f613b09efa9669f65a587a2a71f6a0e4d106"},
+    {file = "regex-2021.3.17-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:c782da0e45aff131f0bed6e66fbcfa589ff2862fc719b83a88640daa01a5aff7"},
+    {file = "regex-2021.3.17-cp39-cp39-win32.whl", hash = "sha256:dc9963aacb7da5177e40874585d7407c0f93fb9d7518ec58b86e562f633f36cd"},
+    {file = "regex-2021.3.17-cp39-cp39-win_amd64.whl", hash = "sha256:a0d04128e005142260de3733591ddf476e4902c0c23c1af237d9acf3c96e1b38"},
+    {file = "regex-2021.3.17.tar.gz", hash = "sha256:4b8a1fb724904139149a43e172850f35aa6ea97fb0545244dc0b805e0154ed68"},
 ]
 requests = [
     {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"},
@@ -1538,8 +1541,8 @@ requirements-detector = [
     {file = "requirements-detector-0.7.tar.gz", hash = "sha256:0d1e13e61ed243f9c3c86e6cbb19980bcb3a0e0619cde2ec1f3af70fdbee6f7b"},
 ]
 "ruamel.yaml" = [
-    {file = "ruamel.yaml-0.16.12-py2.py3-none-any.whl", hash = "sha256:012b9470a0ea06e4e44e99e7920277edf6b46eee0232a04487ea73a7386340a5"},
-    {file = "ruamel.yaml-0.16.12.tar.gz", hash = "sha256:076cc0bc34f1966d920a49f18b52b6ad559fbe656a0748e3535cf7b3f29ebf9e"},
+    {file = "ruamel.yaml-0.17.0-py2.py3-none-any.whl", hash = "sha256:3a41b30235cc6ff7baee0321ffa99e7f94bbc7c7e0f2cac1d75b6b24fc24f202"},
+    {file = "ruamel.yaml-0.17.0.tar.gz", hash = "sha256:3572505e63dd35b5dea62cd0386d03c4f2a53da29a3af09f428114cc85c564aa"},
 ]
 "ruamel.yaml.clib" = [
     {file = "ruamel.yaml.clib-0.2.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:28116f204103cb3a108dfd37668f20abe6e3cafd0d3fd40dba126c732457b3cc"},
@@ -1605,8 +1608,8 @@ tomlkit = [
     {file = "tomlkit-0.7.0.tar.gz", hash = "sha256:ac57f29693fab3e309ea789252fcce3061e19110085aa31af5446ca749325618"},
 ]
 tox = [
-    {file = "tox-3.21.4-py2.py3-none-any.whl", hash = "sha256:65d0e90ceb816638a50d64f4b47b11da767b284c0addda2294cb3cd69bd72425"},
-    {file = "tox-3.21.4.tar.gz", hash = "sha256:cf7fef81a3a2434df4d7af2a6d1bf606d2970220addfbe7dea2615bd4bb2c252"},
+    {file = "tox-3.23.0-py2.py3-none-any.whl", hash = "sha256:e007673f3595cede9b17a7c4962389e4305d4a3682a6c5a4159a1453b4f326aa"},
+    {file = "tox-3.23.0.tar.gz", hash = "sha256:05a4dbd5e4d3d8269b72b55600f0b0303e2eb47ad5c6fe76d3576f4c58d93661"},
 ]
 tox-pyenv = [
     {file = "tox-pyenv-1.1.0.tar.gz", hash = "sha256:916c2213577aec0b3b5452c5bfb32fd077f3a3196f50a81ad57d7ef3fc2599e4"},
@@ -1650,12 +1653,12 @@ typing-extensions = [
     {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"},
 ]
 urllib3 = [
-    {file = "urllib3-1.26.3-py2.py3-none-any.whl", hash = "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80"},
-    {file = "urllib3-1.26.3.tar.gz", hash = "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73"},
+    {file = "urllib3-1.26.4-py2.py3-none-any.whl", hash = "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df"},
+    {file = "urllib3-1.26.4.tar.gz", hash = "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"},
 ]
 virtualenv = [
-    {file = "virtualenv-20.4.2-py2.py3-none-any.whl", hash = "sha256:2be72df684b74df0ea47679a7df93fd0e04e72520022c57b479d8f881485dbe3"},
-    {file = "virtualenv-20.4.2.tar.gz", hash = "sha256:147b43894e51dd6bba882cf9c282447f780e2251cd35172403745fc381a0a80d"},
+    {file = "virtualenv-20.4.3-py2.py3-none-any.whl", hash = "sha256:83f95875d382c7abafe06bd2a4cdd1b363e1bb77e02f155ebe8ac082a916b37c"},
+    {file = "virtualenv-20.4.3.tar.gz", hash = "sha256:49ec4eb4c224c6f7dd81bb6d0a28a09ecae5894f4e593c89b0db0885f565a107"},
 ]
 wcwidth = [
     {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
@@ -1704,6 +1707,6 @@ yarl = [
     {file = "yarl-1.6.3.tar.gz", hash = "sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10"},
 ]
 zipp = [
-    {file = "zipp-3.4.0-py3-none-any.whl", hash = "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108"},
-    {file = "zipp-3.4.0.tar.gz", hash = "sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb"},
+    {file = "zipp-3.4.1-py3-none-any.whl", hash = "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098"},
+    {file = "zipp-3.4.1.tar.gz", hash = "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76"},
 ]
index fdf6b36a6b619e53749d275a812fc3527893a4ba..d5c5368d9a92069813fa4cd6edaa99a566df79b7 100644 (file)
@@ -36,7 +36,7 @@ run = { cmd = "scripts/run", help = "Run the manager" }
 run-debug = { cmd = "scripts/run-debug", help = "Run the manager under debugger" }
 test = { cmd = "pytest --cov=knot_resolver_manager --show-capture=all tests/", help = "Run tests" }
 check = { cmd = "scripts/codecheck", help = "Run static code analysis" }
-format = { cmd = "poetry run black knot_resolver_manager/ tests/", help = "Run 'Black' code formater" }
+format = { shell = "poetry run black knot_resolver_manager/ tests/; isort -rc .", help = "Run code formatter" }
 fixdeps = { shell = "poetry install; yarn install", help = "Install/update dependencies according to configuration files"}
 commit = { shell = "scripts/commit", help = "Invoke every single check before commiting" }
 container-build = { cmd = "scripts/container-build", help = "Build containers (no arguments = all, otherwise arguments are tags that should be built)" }
@@ -53,6 +53,18 @@ tox = { cmd = "tox", help = "Run tests in tox" }
 integration = {cmd = "python integration/runner.py", help = "Run integration tests" }
 
 
+[tool.black]
+line-length = 120
+target_version = ['py38']
+include = '\.py$'
+
+[tool.isort]
+line_length=120                # corresponds to -w  flag
+multi_line_output=3            # corresponds to -m  flag
+include_trailing_comma=true    # corresponds to -tc flag
+skip_glob = '^((?!py$).)*$'    # isort all Python files
+float_to_top=true
+
 [tool.tox]
 legacy_tox_ini = """
 [tox]
index 61815ecdb5339ffdcd63e67d43a0b6f8bcbcc2df..33fa6f076ae74b58bd94dcd4659666a54643926f 100644 (file)
@@ -3,6 +3,7 @@
     "knot_resolver_manager"
   ],
   "exclude": [
-    "knot_resolver_manager/compat/asyncio.py"
-  ]
+    "knot_resolver_manager/utils/dataclasses_yaml.py"
+  ],
+  "typeCheckingMode": "strict"
 }
\ No newline at end of file
index a66a4ca85ef6ccc5b3bccd6d0c094c4ff8f153a0..d83c83d60ba53f61c5fa75198a6efea5288139db 100755 (executable)
@@ -1,11 +1,12 @@
 #!/usr/bin/env python
 
 import subprocess
-from typing import Dict, List, Optional
-import click
+import sys
 import time
 from pathlib import Path, PurePath
-import sys
+from typing import Dict, List, Optional
+
+import click
 
 PODMAN_EXECUTABLE = "/usr/bin/podman"
 
index 5e9a566bca3b52cbad9360158e72e32b3e1e069a..3f04d4e55e04bd7958fdd45ae431a45f8c539611 100644 (file)
@@ -1,10 +1,12 @@
-from knot_resolver_manager.utils.dataclasses_yaml import dataclass_strictyaml
-from knot_resolver_manager.utils import dataclass_strictyaml_schema
-from typing import List, Dict, Optional, Tuple
-from strictyaml import Map, Str, EmptyDict, Int, Float, Seq, MapPattern, FixedSeq
-import strictyaml
-import pytest
 from dataclasses import dataclass
+from typing import Dict, List, Optional, Tuple
+
+import pytest
+import strictyaml
+from strictyaml import EmptyDict, FixedSeq, Float, Int, Map, MapPattern, Seq, Str
+
+from knot_resolver_manager.utils import dataclass_strictyaml_schema
+from knot_resolver_manager.utils.dataclasses_yaml import dataclass_strictyaml
 
 
 def _schema_eq(schema1, schema2) -> bool:
@@ -72,9 +74,7 @@ def test_dict_field():
     class TestClass:
         field: Dict[str, int]
 
-    assert _schema_eq(
-        TestClass.STRICTYAML_SCHEMA, Map({"field": MapPattern(Str(), Int())})
-    )
+    assert _schema_eq(TestClass.STRICTYAML_SCHEMA, Map({"field": MapPattern(Str(), Int())}))
 
 
 def test_optional_field():
@@ -82,9 +82,7 @@ def test_optional_field():
     class TestClass:
         field: Optional[int]
 
-    assert _schema_eq(
-        TestClass.STRICTYAML_SCHEMA, Map({strictyaml.Optional("field"): Int()})
-    )
+    assert _schema_eq(TestClass.STRICTYAML_SCHEMA, Map({strictyaml.Optional("field"): Int()}))
 
 
 def test_nested_dict_list():
@@ -92,9 +90,7 @@ def test_nested_dict_list():
     class TestClass:
         field: Dict[str, List[int]]
 
-    assert _schema_eq(
-        TestClass.STRICTYAML_SCHEMA, Map({"field": MapPattern(Str(), Seq(Int()))})
-    )
+    assert _schema_eq(TestClass.STRICTYAML_SCHEMA, Map({"field": MapPattern(Str(), Seq(Int()))}))
 
 
 @pytest.mark.xfail(strict=True)
@@ -107,9 +103,7 @@ def test_nested_dict_key_list():
     class TestClass:
         field: Dict[List[int], List[int]]
 
-    assert _schema_eq(
-        TestClass.STRICTYAML_SCHEMA, Map({"field": MapPattern(Seq(Int()), Seq(Int()))})
-    )
+    assert _schema_eq(TestClass.STRICTYAML_SCHEMA, Map({"field": MapPattern(Seq(Int()), Seq(Int()))}))
 
 
 def test_nested_list():
@@ -117,9 +111,7 @@ def test_nested_list():
     class TestClass:
         field: List[List[List[List[int]]]]
 
-    assert _schema_eq(
-        TestClass.STRICTYAML_SCHEMA, Map({"field": Seq(Seq(Seq(Seq(Int()))))})
-    )
+    assert _schema_eq(TestClass.STRICTYAML_SCHEMA, Map({"field": Seq(Seq(Seq(Seq(Int()))))}))
 
 
 def test_tuple_field():
@@ -127,9 +119,7 @@ def test_tuple_field():
     class TestClass:
         field: Tuple[str, int]
 
-    assert _schema_eq(
-        TestClass.STRICTYAML_SCHEMA, Map({"field": FixedSeq([Str(), Int()])})
-    )
+    assert _schema_eq(TestClass.STRICTYAML_SCHEMA, Map({"field": FixedSeq([Str(), Int()])}))
 
 
 def test_nested_tuple():
@@ -152,9 +142,7 @@ def test_chained_classes():
     class CompoundClass:
         c: TestClass
 
-    assert _schema_eq(
-        CompoundClass.STRICTYAML_SCHEMA, Map({"c": Map({"field": Int()})})
-    )
+    assert _schema_eq(CompoundClass.STRICTYAML_SCHEMA, Map({"c": Map({"field": Int()})}))
 
 
 def test_combined_with_dataclass():
index 3951a746165c3e3a69bede6ccfebec1291b080f1..0905c47e0335d155dec51f3bf86da46a95e3b612 100644 (file)
@@ -1,13 +1,12 @@
-from knot_resolver_manager.utils.dataclasses_yaml import (
-    StrictyamlParser,
-    dataclass_strictyaml,
-)
-from knot_resolver_manager.utils import dataclass_strictyaml_schema
-from typing import List, Dict, Optional, Tuple
-from strictyaml import Map, Str, EmptyDict, Int, Float, Seq, MapPattern, FixedSeq
-import strictyaml
-import pytest
 from dataclasses import dataclass
+from typing import Dict, List, Optional, Tuple
+
+import pytest
+import strictyaml
+from strictyaml import EmptyDict, FixedSeq, Float, Int, Map, MapPattern, Seq, Str
+
+from knot_resolver_manager.utils import dataclass_strictyaml_schema
+from knot_resolver_manager.utils.dataclasses_yaml import StrictyamlParser, dataclass_strictyaml
 
 
 def test_parsing_primitive():
diff --git a/manager/typings/READMEmd b/manager/typings/READMEmd
new file mode 100644 (file)
index 0000000..2e2c88b
--- /dev/null
@@ -0,0 +1,8 @@
+# Type stubs
+
+See (pyright documentation)[https://github.com/microsoft/pyright/blob/master/docs/type-stubs.md]
+
+Generate stubs using this command (replacing `jinja2` for an appropriate package):
+```
+poetry run yarn pyright --createstub jinja2
+```
\ No newline at end of file
diff --git a/manager/typings/jinja2/__init__.pyi b/manager/typings/jinja2/__init__.pyi
new file mode 100644 (file)
index 0000000..10e44fc
--- /dev/null
@@ -0,0 +1,12 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from jinja2.bccache import BytecodeCache as BytecodeCache, FileSystemBytecodeCache as FileSystemBytecodeCache, MemcachedBytecodeCache as MemcachedBytecodeCache
+from jinja2.environment import Environment as Environment, Template as Template
+from jinja2.exceptions import TemplateAssertionError as TemplateAssertionError, TemplateError as TemplateError, TemplateNotFound as TemplateNotFound, TemplateSyntaxError as TemplateSyntaxError, TemplatesNotFound as TemplatesNotFound, UndefinedError as UndefinedError
+from jinja2.filters import contextfilter as contextfilter, environmentfilter as environmentfilter, evalcontextfilter as evalcontextfilter
+from jinja2.loaders import BaseLoader as BaseLoader, ChoiceLoader as ChoiceLoader, DictLoader as DictLoader, FileSystemLoader as FileSystemLoader, FunctionLoader as FunctionLoader, ModuleLoader as ModuleLoader, PackageLoader as PackageLoader, PrefixLoader as PrefixLoader
+from jinja2.runtime import DebugUndefined as DebugUndefined, StrictUndefined as StrictUndefined, Undefined as Undefined, make_logging_undefined as make_logging_undefined
+from jinja2.utils import Markup as Markup, clear_caches as clear_caches, contextfunction as contextfunction, environmentfunction as environmentfunction, escape as escape, evalcontextfunction as evalcontextfunction, is_undefined as is_undefined, select_autoescape as select_autoescape
+
diff --git a/manager/typings/jinja2/_compat.pyi b/manager/typings/jinja2/_compat.pyi
new file mode 100644 (file)
index 0000000..0efa85e
--- /dev/null
@@ -0,0 +1,37 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+import sys
+from typing import Any, Optional
+from urllib.parse import quote_from_bytes
+
+if sys.version_info >= (3, ):
+    url_quote = quote_from_bytes
+else:
+    ...
+PY2: Any
+PYPY: Any
+unichr: Any
+range_type: Any
+text_type: Any
+string_types: Any
+integer_types: Any
+iterkeys: Any
+itervalues: Any
+iteritems: Any
+NativeStringIO: Any
+def reraise(tp, value, tb: Optional[Any] = ...):
+    ...
+
+ifilter: Any
+imap: Any
+izip: Any
+intern: Any
+implements_iterator: Any
+implements_to_string: Any
+encode_filename: Any
+get_next: Any
+def with_metaclass(meta, *bases):
+    ...
+
diff --git a/manager/typings/jinja2/_stringdefs.pyi b/manager/typings/jinja2/_stringdefs.pyi
new file mode 100644 (file)
index 0000000..de4f8ae
--- /dev/null
@@ -0,0 +1,45 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any
+
+Cc: str
+Cf: str
+Cn: str
+Co: str
+Cs: Any
+Ll: str
+Lm: str
+Lo: str
+Lt: str
+Lu: str
+Mc: str
+Me: str
+Mn: str
+Nd: str
+Nl: str
+No: str
+Pc: str
+Pd: str
+Pe: str
+Pf: str
+Pi: str
+Po: str
+Ps: str
+Sc: str
+Sk: str
+Sm: str
+So: str
+Zl: str
+Zp: str
+Zs: str
+cats: Any
+def combine(*args):
+    ...
+
+xid_start: str
+xid_continue: str
+def allexcept(*args):
+    ...
+
diff --git a/manager/typings/jinja2/bccache.pyi b/manager/typings/jinja2/bccache.pyi
new file mode 100644 (file)
index 0000000..e050cb8
--- /dev/null
@@ -0,0 +1,92 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any, Optional
+
+marshal_dump: Any
+marshal_load: Any
+bc_version: int
+bc_magic: Any
+class Bucket:
+    environment: Any
+    key: Any
+    checksum: Any
+    def __init__(self, environment, key, checksum) -> None:
+        ...
+    
+    code: Any
+    def reset(self):
+        ...
+    
+    def load_bytecode(self, f):
+        ...
+    
+    def write_bytecode(self, f):
+        ...
+    
+    def bytecode_from_string(self, string):
+        ...
+    
+    def bytecode_to_string(self):
+        ...
+    
+
+
+class BytecodeCache:
+    def load_bytecode(self, bucket):
+        ...
+    
+    def dump_bytecode(self, bucket):
+        ...
+    
+    def clear(self):
+        ...
+    
+    def get_cache_key(self, name, filename: Optional[Any] = ...):
+        ...
+    
+    def get_source_checksum(self, source):
+        ...
+    
+    def get_bucket(self, environment, name, filename, source):
+        ...
+    
+    def set_bucket(self, bucket):
+        ...
+    
+
+
+class FileSystemBytecodeCache(BytecodeCache):
+    directory: Any
+    pattern: Any
+    def __init__(self, directory: Optional[Any] = ..., pattern: str = ...) -> None:
+        ...
+    
+    def load_bytecode(self, bucket):
+        ...
+    
+    def dump_bytecode(self, bucket):
+        ...
+    
+    def clear(self):
+        ...
+    
+
+
+class MemcachedBytecodeCache(BytecodeCache):
+    client: Any
+    prefix: Any
+    timeout: Any
+    ignore_memcache_errors: Any
+    def __init__(self, client, prefix: str = ..., timeout: Optional[Any] = ..., ignore_memcache_errors: bool = ...) -> None:
+        ...
+    
+    def load_bytecode(self, bucket):
+        ...
+    
+    def dump_bytecode(self, bucket):
+        ...
+    
+
+
diff --git a/manager/typings/jinja2/compiler.pyi b/manager/typings/jinja2/compiler.pyi
new file mode 100644 (file)
index 0000000..e5a1c74
--- /dev/null
@@ -0,0 +1,397 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any, Optional
+from jinja2.visitor import NodeVisitor
+
+operators: Any
+dict_item_iter: str
+unoptimize_before_dead_code: bool
+def generate(node, environment, name, filename, stream: Optional[Any] = ..., defer_init: bool = ...):
+    ...
+
+def has_safe_repr(value):
+    ...
+
+def find_undeclared(nodes, names):
+    ...
+
+class Identifiers:
+    declared: Any
+    outer_undeclared: Any
+    undeclared: Any
+    declared_locally: Any
+    declared_parameter: Any
+    def __init__(self) -> None:
+        ...
+    
+    def add_special(self, name):
+        ...
+    
+    def is_declared(self, name):
+        ...
+    
+    def copy(self):
+        ...
+    
+
+
+class Frame:
+    eval_ctx: Any
+    identifiers: Any
+    toplevel: bool
+    rootlevel: bool
+    require_output_check: Any
+    buffer: Any
+    block: Any
+    assigned_names: Any
+    parent: Any
+    def __init__(self, eval_ctx, parent: Optional[Any] = ...) -> None:
+        ...
+    
+    def copy(self):
+        ...
+    
+    def inspect(self, nodes):
+        ...
+    
+    def find_shadowed(self, extra: Any = ...):
+        ...
+    
+    def inner(self):
+        ...
+    
+    def soft(self):
+        ...
+    
+    __copy__: Any
+
+
+class VisitorExit(RuntimeError):
+    ...
+
+
+class DependencyFinderVisitor(NodeVisitor):
+    filters: Any
+    tests: Any
+    def __init__(self) -> None:
+        ...
+    
+    def visit_Filter(self, node):
+        ...
+    
+    def visit_Test(self, node):
+        ...
+    
+    def visit_Block(self, node):
+        ...
+    
+
+
+class UndeclaredNameVisitor(NodeVisitor):
+    names: Any
+    undeclared: Any
+    def __init__(self, names) -> None:
+        ...
+    
+    def visit_Name(self, node):
+        ...
+    
+    def visit_Block(self, node):
+        ...
+    
+
+
+class FrameIdentifierVisitor(NodeVisitor):
+    identifiers: Any
+    def __init__(self, identifiers) -> None:
+        ...
+    
+    def visit_Name(self, node):
+        ...
+    
+    def visit_If(self, node):
+        ...
+    
+    def visit_Macro(self, node):
+        ...
+    
+    def visit_Import(self, node):
+        ...
+    
+    def visit_FromImport(self, node):
+        ...
+    
+    def visit_Assign(self, node):
+        ...
+    
+    def visit_For(self, node):
+        ...
+    
+    def visit_CallBlock(self, node):
+        ...
+    
+    def visit_FilterBlock(self, node):
+        ...
+    
+    def visit_AssignBlock(self, node):
+        ...
+    
+    def visit_Scope(self, node):
+        ...
+    
+    def visit_Block(self, node):
+        ...
+    
+
+
+class CompilerExit(Exception):
+    ...
+
+
+class CodeGenerator(NodeVisitor):
+    environment: Any
+    name: Any
+    filename: Any
+    stream: Any
+    created_block_context: bool
+    defer_init: Any
+    import_aliases: Any
+    blocks: Any
+    extends_so_far: int
+    has_known_extends: bool
+    code_lineno: int
+    tests: Any
+    filters: Any
+    debug_info: Any
+    def __init__(self, environment, name, filename, stream: Optional[Any] = ..., defer_init: bool = ...) -> None:
+        ...
+    
+    def fail(self, msg, lineno):
+        ...
+    
+    def temporary_identifier(self):
+        ...
+    
+    def buffer(self, frame):
+        ...
+    
+    def return_buffer_contents(self, frame):
+        ...
+    
+    def indent(self):
+        ...
+    
+    def outdent(self, step: int = ...):
+        ...
+    
+    def start_write(self, frame, node: Optional[Any] = ...):
+        ...
+    
+    def end_write(self, frame):
+        ...
+    
+    def simple_write(self, s, frame, node: Optional[Any] = ...):
+        ...
+    
+    def blockvisit(self, nodes, frame):
+        ...
+    
+    def write(self, x):
+        ...
+    
+    def writeline(self, x, node: Optional[Any] = ..., extra: int = ...):
+        ...
+    
+    def newline(self, node: Optional[Any] = ..., extra: int = ...):
+        ...
+    
+    def signature(self, node, frame, extra_kwargs: Optional[Any] = ...):
+        ...
+    
+    def pull_locals(self, frame):
+        ...
+    
+    def pull_dependencies(self, nodes):
+        ...
+    
+    def unoptimize_scope(self, frame):
+        ...
+    
+    def push_scope(self, frame, extra_vars: Any = ...):
+        ...
+    
+    def pop_scope(self, aliases, frame):
+        ...
+    
+    def function_scoping(self, node, frame, children: Optional[Any] = ..., find_special: bool = ...):
+        ...
+    
+    def macro_body(self, node, frame, children: Optional[Any] = ...):
+        ...
+    
+    def macro_def(self, node, frame):
+        ...
+    
+    def position(self, node):
+        ...
+    
+    def visit_Template(self, node, frame: Optional[Any] = ...):
+        ...
+    
+    def visit_Block(self, node, frame):
+        ...
+    
+    def visit_Extends(self, node, frame):
+        ...
+    
+    def visit_Include(self, node, frame):
+        ...
+    
+    def visit_Import(self, node, frame):
+        ...
+    
+    def visit_FromImport(self, node, frame):
+        ...
+    
+    def visit_For(self, node, frame):
+        ...
+    
+    def visit_If(self, node, frame):
+        ...
+    
+    def visit_Macro(self, node, frame):
+        ...
+    
+    def visit_CallBlock(self, node, frame):
+        ...
+    
+    def visit_FilterBlock(self, node, frame):
+        ...
+    
+    def visit_ExprStmt(self, node, frame):
+        ...
+    
+    def visit_Output(self, node, frame):
+        ...
+    
+    def make_assignment_frame(self, frame):
+        ...
+    
+    def export_assigned_vars(self, frame, assignment_frame):
+        ...
+    
+    def visit_Assign(self, node, frame):
+        ...
+    
+    def visit_AssignBlock(self, node, frame):
+        ...
+    
+    def visit_Name(self, node, frame):
+        ...
+    
+    def visit_Const(self, node, frame):
+        ...
+    
+    def visit_TemplateData(self, node, frame):
+        ...
+    
+    def visit_Tuple(self, node, frame):
+        ...
+    
+    def visit_List(self, node, frame):
+        ...
+    
+    def visit_Dict(self, node, frame):
+        ...
+    
+    def binop(self, interceptable: bool = ...):
+        ...
+    
+    def uaop(self, interceptable: bool = ...):
+        ...
+    
+    visit_Add: Any
+    visit_Sub: Any
+    visit_Mul: Any
+    visit_Div: Any
+    visit_FloorDiv: Any
+    visit_Pow: Any
+    visit_Mod: Any
+    visit_And: Any
+    visit_Or: Any
+    visit_Pos: Any
+    visit_Neg: Any
+    visit_Not: Any
+    def visit_Concat(self, node, frame):
+        ...
+    
+    def visit_Compare(self, node, frame):
+        ...
+    
+    def visit_Operand(self, node, frame):
+        ...
+    
+    def visit_Getattr(self, node, frame):
+        ...
+    
+    def visit_Getitem(self, node, frame):
+        ...
+    
+    def visit_Slice(self, node, frame):
+        ...
+    
+    def visit_Filter(self, node, frame):
+        ...
+    
+    def visit_Test(self, node, frame):
+        ...
+    
+    def visit_CondExpr(self, node, frame):
+        ...
+    
+    def visit_Call(self, node, frame, forward_caller: bool = ...):
+        ...
+    
+    def visit_Keyword(self, node, frame):
+        ...
+    
+    def visit_MarkSafe(self, node, frame):
+        ...
+    
+    def visit_MarkSafeIfAutoescape(self, node, frame):
+        ...
+    
+    def visit_EnvironmentAttribute(self, node, frame):
+        ...
+    
+    def visit_ExtensionAttribute(self, node, frame):
+        ...
+    
+    def visit_ImportedName(self, node, frame):
+        ...
+    
+    def visit_InternalName(self, node, frame):
+        ...
+    
+    def visit_ContextReference(self, node, frame):
+        ...
+    
+    def visit_Continue(self, node, frame):
+        ...
+    
+    def visit_Break(self, node, frame):
+        ...
+    
+    def visit_Scope(self, node, frame):
+        ...
+    
+    def visit_EvalContextModifier(self, node, frame):
+        ...
+    
+    def visit_ScopedEvalContextModifier(self, node, frame):
+        ...
+    
+
+
diff --git a/manager/typings/jinja2/constants.pyi b/manager/typings/jinja2/constants.pyi
new file mode 100644 (file)
index 0000000..3ddd49a
--- /dev/null
@@ -0,0 +1,5 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+LOREM_IPSUM_WORDS: str
diff --git a/manager/typings/jinja2/debug.pyi b/manager/typings/jinja2/debug.pyi
new file mode 100644 (file)
index 0000000..8098fcd
--- /dev/null
@@ -0,0 +1,72 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any, Optional
+
+tproxy: Any
+raise_helper: str
+class TracebackFrameProxy:
+    tb: Any
+    def __init__(self, tb) -> None:
+        ...
+    
+    @property
+    def tb_next(self):
+        ...
+    
+    def set_next(self, next):
+        ...
+    
+    @property
+    def is_jinja_frame(self):
+        ...
+    
+    def __getattr__(self, name):
+        ...
+    
+
+
+def make_frame_proxy(frame):
+    ...
+
+class ProcessedTraceback:
+    exc_type: Any
+    exc_value: Any
+    frames: Any
+    def __init__(self, exc_type, exc_value, frames) -> None:
+        ...
+    
+    def render_as_text(self, limit: Optional[Any] = ...):
+        ...
+    
+    def render_as_html(self, full: bool = ...):
+        ...
+    
+    @property
+    def is_template_syntax_error(self):
+        ...
+    
+    @property
+    def exc_info(self):
+        ...
+    
+    @property
+    def standard_exc_info(self):
+        ...
+    
+
+
+def make_traceback(exc_info, source_hint: Optional[Any] = ...):
+    ...
+
+def translate_syntax_error(error, source: Optional[Any] = ...):
+    ...
+
+def translate_exception(exc_info, initial_skip: int = ...):
+    ...
+
+def fake_exc_info(exc_info, filename, lineno):
+    ...
+
+tb_set_next: Any
diff --git a/manager/typings/jinja2/defaults.pyi b/manager/typings/jinja2/defaults.pyi
new file mode 100644 (file)
index 0000000..e2e5940
--- /dev/null
@@ -0,0 +1,24 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any, Dict, Optional
+from jinja2.filters import FILTERS
+from jinja2.tests import TESTS
+
+DEFAULT_FILTERS = FILTERS
+DEFAULT_TESTS = TESTS
+BLOCK_START_STRING: str
+BLOCK_END_STRING: str
+VARIABLE_START_STRING: str
+VARIABLE_END_STRING: str
+COMMENT_START_STRING: str
+COMMENT_END_STRING: str
+LINE_STATEMENT_PREFIX: Optional[str]
+LINE_COMMENT_PREFIX: Optional[str]
+TRIM_BLOCKS: bool
+LSTRIP_BLOCKS: bool
+NEWLINE_SEQUENCE: str
+KEEP_TRAILING_NEWLINE: bool
+DEFAULT_NAMESPACE: Dict[str, Any]
+DEFAULT_POLICIES = Dict[str, Any]
diff --git a/manager/typings/jinja2/environment.pyi b/manager/typings/jinja2/environment.pyi
new file mode 100644 (file)
index 0000000..83c23e4
--- /dev/null
@@ -0,0 +1,240 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+import sys
+from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Sequence, Text, Type, Union
+from .bccache import BytecodeCache
+from .loaders import BaseLoader
+from .runtime import Context, Undefined
+
+if sys.version_info >= (3, 6):
+    ...
+def get_spontaneous_environment(*args):
+    ...
+
+def create_cache(size):
+    ...
+
+def copy_cache(cache):
+    ...
+
+def load_extensions(environment, extensions):
+    ...
+
+class Environment:
+    sandboxed: bool
+    overlayed: bool
+    linked_to: Any
+    shared: bool
+    exception_handler: Any
+    exception_formatter: Any
+    code_generator_class: Any
+    context_class: Any
+    block_start_string: Text
+    block_end_string: Text
+    variable_start_string: Text
+    variable_end_string: Text
+    comment_start_string: Text
+    comment_end_string: Text
+    line_statement_prefix: Text
+    line_comment_prefix: Text
+    trim_blocks: bool
+    lstrip_blocks: Any
+    newline_sequence: Text
+    keep_trailing_newline: bool
+    undefined: Type[Undefined]
+    optimized: bool
+    finalize: Callable[..., Any]
+    autoescape: Any
+    filters: Any
+    tests: Any
+    globals: Dict[str, Any]
+    loader: BaseLoader
+    cache: Any
+    bytecode_cache: BytecodeCache
+    auto_reload: bool
+    extensions: List[Any]
+    def __init__(self, block_start_string: Text = ..., block_end_string: Text = ..., variable_start_string: Text = ..., variable_end_string: Text = ..., comment_start_string: Any = ..., comment_end_string: Text = ..., line_statement_prefix: Text = ..., line_comment_prefix: Text = ..., trim_blocks: bool = ..., lstrip_blocks: bool = ..., newline_sequence: Text = ..., keep_trailing_newline: bool = ..., extensions: List[Any] = ..., optimized: bool = ..., undefined: Type[Undefined] = ..., finalize: Optional[Callable[..., Any]] = ..., autoescape: Union[bool, Callable[[str], bool]] = ..., loader: Optional[BaseLoader] = ..., cache_size: int = ..., auto_reload: bool = ..., bytecode_cache: Optional[BytecodeCache] = ..., enable_async: bool = ...) -> None:
+        ...
+    
+    def add_extension(self, extension):
+        ...
+    
+    def extend(self, **attributes):
+        ...
+    
+    def overlay(self, block_start_string: Text = ..., block_end_string: Text = ..., variable_start_string: Text = ..., variable_end_string: Text = ..., comment_start_string: Any = ..., comment_end_string: Text = ..., line_statement_prefix: Text = ..., line_comment_prefix: Text = ..., trim_blocks: bool = ..., lstrip_blocks: bool = ..., extensions: List[Any] = ..., optimized: bool = ..., undefined: Type[Undefined] = ..., finalize: Callable[..., Any] = ..., autoescape: bool = ..., loader: Optional[BaseLoader] = ..., cache_size: int = ..., auto_reload: bool = ..., bytecode_cache: Optional[BytecodeCache] = ...):
+        ...
+    
+    lexer: Any
+    def iter_extensions(self):
+        ...
+    
+    def getitem(self, obj, argument):
+        ...
+    
+    def getattr(self, obj, attribute):
+        ...
+    
+    def call_filter(self, name, value, args: Optional[Any] = ..., kwargs: Optional[Any] = ..., context: Optional[Any] = ..., eval_ctx: Optional[Any] = ...):
+        ...
+    
+    def call_test(self, name, value, args: Optional[Any] = ..., kwargs: Optional[Any] = ...):
+        ...
+    
+    def parse(self, source, name: Optional[Any] = ..., filename: Optional[Any] = ...):
+        ...
+    
+    def lex(self, source, name: Optional[Any] = ..., filename: Optional[Any] = ...):
+        ...
+    
+    def preprocess(self, source: Text, name: Optional[Any] = ..., filename: Optional[Any] = ...):
+        ...
+    
+    def compile(self, source, name: Optional[Any] = ..., filename: Optional[Any] = ..., raw: bool = ..., defer_init: bool = ...):
+        ...
+    
+    def compile_expression(self, source: Text, undefined_to_none: bool = ...):
+        ...
+    
+    def compile_templates(self, target, extensions: Optional[Any] = ..., filter_func: Optional[Any] = ..., zip: str = ..., log_function: Optional[Any] = ..., ignore_errors: bool = ..., py_compile: bool = ...):
+        ...
+    
+    def list_templates(self, extensions: Optional[Any] = ..., filter_func: Optional[Any] = ...):
+        ...
+    
+    def handle_exception(self, exc_info: Optional[Any] = ..., rendered: bool = ..., source_hint: Optional[Any] = ...):
+        ...
+    
+    def join_path(self, template: Union[Template, Text], parent: Text) -> Text:
+        ...
+    
+    def get_template(self, name: Union[Template, Text], parent: Optional[Text] = ..., globals: Optional[Any] = ...) -> Template:
+        ...
+    
+    def select_template(self, names: Sequence[Union[Template, Text]], parent: Optional[Text] = ..., globals: Optional[Dict[str, Any]] = ...) -> Template:
+        ...
+    
+    def get_or_select_template(self, template_name_or_list: Union[Union[Template, Text], Sequence[Union[Template, Text]]], parent: Optional[Text] = ..., globals: Optional[Dict[str, Any]] = ...) -> Template:
+        ...
+    
+    def from_string(self, source: Text, globals: Optional[Dict[str, Any]] = ..., template_class: Optional[Type[Template]] = ...) -> Template:
+        ...
+    
+    def make_globals(self, d: Optional[Dict[str, Any]]) -> Dict[str, Any]:
+        ...
+    
+    def install_gettext_translations(self, translations: Any, newstyle: Optional[bool] = ...):
+        ...
+    
+    def install_null_translations(self, newstyle: Optional[bool] = ...):
+        ...
+    
+    def install_gettext_callables(self, gettext: Callable[..., Any], ngettext: Callable[..., Any], newstyle: Optional[bool] = ...):
+        ...
+    
+    def uninstall_gettext_translations(self, translations: Any):
+        ...
+    
+    def extract_translations(self, source: Any, gettext_functions: Any):
+        ...
+    
+    newstyle_gettext: bool
+
+
+class Template:
+    name: Optional[str]
+    filename: Optional[str]
+    def __new__(cls, source, block_start_string: Any = ..., block_end_string: Any = ..., variable_start_string: Any = ..., variable_end_string: Any = ..., comment_start_string: Any = ..., comment_end_string: Any = ..., line_statement_prefix: Any = ..., line_comment_prefix: Any = ..., trim_blocks: Any = ..., lstrip_blocks: Any = ..., newline_sequence: Any = ..., keep_trailing_newline: Any = ..., extensions: Any = ..., optimized: bool = ..., undefined: Any = ..., finalize: Optional[Any] = ..., autoescape: bool = ...):
+        ...
+    
+    environment: Environment = ...
+    @classmethod
+    def from_code(cls, environment, code, globals, uptodate: Optional[Any] = ...):
+        ...
+    
+    @classmethod
+    def from_module_dict(cls, environment, module_dict, globals):
+        ...
+    
+    def render(self, *args: Any, **kwargs: Any) -> Text:
+        ...
+    
+    def stream(self, *args, **kwargs) -> TemplateStream:
+        ...
+    
+    def generate(self, *args, **kwargs) -> Iterator[Text]:
+        ...
+    
+    def new_context(self, vars: Optional[Dict[str, Any]] = ..., shared: bool = ..., locals: Optional[Dict[str, Any]] = ...) -> Context:
+        ...
+    
+    def make_module(self, vars: Optional[Dict[str, Any]] = ..., shared: bool = ..., locals: Optional[Dict[str, Any]] = ...) -> Context:
+        ...
+    
+    @property
+    def module(self) -> Any:
+        ...
+    
+    def get_corresponding_lineno(self, lineno):
+        ...
+    
+    @property
+    def is_up_to_date(self) -> bool:
+        ...
+    
+    @property
+    def debug_info(self):
+        ...
+    
+    if sys.version_info >= (3, 6):
+        def render_async(self, *args: Any, **kwargs: Any) -> Awaitable[Text]:
+            ...
+        
+        def generate_async(self, *args, **kwargs) -> AsyncIterator[Text]:
+            ...
+        
+
+
+class TemplateModule:
+    __name__: Any
+    def __init__(self, template, context) -> None:
+        ...
+    
+    def __html__(self):
+        ...
+    
+
+
+class TemplateExpression:
+    def __init__(self, template, undefined_to_none) -> None:
+        ...
+    
+    def __call__(self, *args, **kwargs):
+        ...
+    
+
+
+class TemplateStream:
+    def __init__(self, gen) -> None:
+        ...
+    
+    def dump(self, fp, encoding: Optional[Text] = ..., errors: Text = ...):
+        ...
+    
+    buffered: bool
+    def disable_buffering(self) -> None:
+        ...
+    
+    def enable_buffering(self, size: int = ...) -> None:
+        ...
+    
+    def __iter__(self):
+        ...
+    
+    def __next__(self):
+        ...
+    
+
+
diff --git a/manager/typings/jinja2/exceptions.pyi b/manager/typings/jinja2/exceptions.pyi
new file mode 100644 (file)
index 0000000..dcdbd31
--- /dev/null
@@ -0,0 +1,66 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any, Optional, Text
+
+class TemplateError(Exception):
+    def __init__(self, message: Optional[Text] = ...) -> None:
+        ...
+    
+    @property
+    def message(self):
+        ...
+    
+    def __unicode__(self):
+        ...
+    
+
+
+class TemplateNotFound(IOError, LookupError, TemplateError):
+    message: Any
+    name: Any
+    templates: Any
+    def __init__(self, name, message: Optional[Text] = ...) -> None:
+        ...
+    
+
+
+class TemplatesNotFound(TemplateNotFound):
+    templates: Any
+    def __init__(self, names: Any = ..., message: Optional[Text] = ...) -> None:
+        ...
+    
+
+
+class TemplateSyntaxError(TemplateError):
+    lineno: int
+    name: Text
+    filename: Text
+    source: Text
+    translated: bool
+    def __init__(self, message: Text, lineno: int, name: Optional[Text] = ..., filename: Optional[Text] = ...) -> None:
+        ...
+    
+
+
+class TemplateAssertionError(TemplateSyntaxError):
+    ...
+
+
+class TemplateRuntimeError(TemplateError):
+    ...
+
+
+class UndefinedError(TemplateRuntimeError):
+    ...
+
+
+class SecurityError(TemplateRuntimeError):
+    ...
+
+
+class FilterArgumentError(TemplateRuntimeError):
+    ...
+
+
diff --git a/manager/typings/jinja2/ext.pyi b/manager/typings/jinja2/ext.pyi
new file mode 100644 (file)
index 0000000..2fb8826
--- /dev/null
@@ -0,0 +1,105 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any, Optional
+
+GETTEXT_FUNCTIONS: Any
+class ExtensionRegistry(type):
+    def __new__(cls, name, bases, d):
+        ...
+    
+
+
+class Extension:
+    tags: Any
+    priority: int
+    environment: Any
+    def __init__(self, environment) -> None:
+        ...
+    
+    def bind(self, environment):
+        ...
+    
+    def preprocess(self, source, name, filename: Optional[Any] = ...):
+        ...
+    
+    def filter_stream(self, stream):
+        ...
+    
+    def parse(self, parser):
+        ...
+    
+    def attr(self, name, lineno: Optional[Any] = ...):
+        ...
+    
+    def call_method(self, name, args: Optional[Any] = ..., kwargs: Optional[Any] = ..., dyn_args: Optional[Any] = ..., dyn_kwargs: Optional[Any] = ..., lineno: Optional[Any] = ...):
+        ...
+    
+
+
+class InternationalizationExtension(Extension):
+    tags: Any
+    def __init__(self, environment) -> None:
+        ...
+    
+    def parse(self, parser):
+        ...
+    
+
+
+class ExprStmtExtension(Extension):
+    tags: Any
+    def parse(self, parser):
+        ...
+    
+
+
+class LoopControlExtension(Extension):
+    tags: Any
+    def parse(self, parser):
+        ...
+    
+
+
+class WithExtension(Extension):
+    tags: Any
+    def parse(self, parser):
+        ...
+    
+
+
+class AutoEscapeExtension(Extension):
+    tags: Any
+    def parse(self, parser):
+        ...
+    
+
+
+def extract_from_ast(node, gettext_functions: Any = ..., babel_style: bool = ...):
+    ...
+
+class _CommentFinder:
+    tokens: Any
+    comment_tags: Any
+    offset: int
+    last_lineno: int
+    def __init__(self, tokens, comment_tags) -> None:
+        ...
+    
+    def find_backwards(self, offset):
+        ...
+    
+    def find_comments(self, lineno):
+        ...
+    
+
+
+def babel_extract(fileobj, keywords, comment_tags, options):
+    ...
+
+i18n: Any
+do: Any
+loopcontrols: Any
+with_: Any
+autoescape: Any
diff --git a/manager/typings/jinja2/filters.pyi b/manager/typings/jinja2/filters.pyi
new file mode 100644 (file)
index 0000000..9e758f2
--- /dev/null
@@ -0,0 +1,154 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any, NamedTuple, Optional
+
+def contextfilter(f):
+    ...
+
+def evalcontextfilter(f):
+    ...
+
+def environmentfilter(f):
+    ...
+
+def make_attrgetter(environment, attribute):
+    ...
+
+def do_forceescape(value):
+    ...
+
+def do_urlencode(value):
+    ...
+
+def do_replace(eval_ctx, s, old, new, count: Optional[Any] = ...):
+    ...
+
+def do_upper(s):
+    ...
+
+def do_lower(s):
+    ...
+
+def do_xmlattr(_eval_ctx, d, autospace: bool = ...):
+    ...
+
+def do_capitalize(s):
+    ...
+
+def do_title(s):
+    ...
+
+def do_dictsort(value, case_sensitive: bool = ..., by: str = ...):
+    ...
+
+def do_sort(environment, value, reverse: bool = ..., case_sensitive: bool = ..., attribute: Optional[Any] = ...):
+    ...
+
+def do_default(value, default_value: str = ..., boolean: bool = ...):
+    ...
+
+def do_join(eval_ctx, value, d: str = ..., attribute: Optional[Any] = ...):
+    ...
+
+def do_center(value, width: int = ...):
+    ...
+
+def do_first(environment, seq):
+    ...
+
+def do_last(environment, seq):
+    ...
+
+def do_random(environment, seq):
+    ...
+
+def do_filesizeformat(value, binary: bool = ...):
+    ...
+
+def do_pprint(value, verbose: bool = ...):
+    ...
+
+def do_urlize(eval_ctx, value, trim_url_limit: Optional[Any] = ..., nofollow: bool = ..., target: Optional[Any] = ...):
+    ...
+
+def do_indent(s, width: int = ..., indentfirst: bool = ...):
+    ...
+
+def do_truncate(s, length: int = ..., killwords: bool = ..., end: str = ...):
+    ...
+
+def do_wordwrap(environment, s, width: int = ..., break_long_words: bool = ..., wrapstring: Optional[Any] = ...):
+    ...
+
+def do_wordcount(s):
+    ...
+
+def do_int(value, default: int = ..., base: int = ...):
+    ...
+
+def do_float(value, default: float = ...):
+    ...
+
+def do_format(value, *args, **kwargs):
+    ...
+
+def do_trim(value):
+    ...
+
+def do_striptags(value):
+    ...
+
+def do_slice(value, slices, fill_with: Optional[Any] = ...):
+    ...
+
+def do_batch(value, linecount, fill_with: Optional[Any] = ...):
+    ...
+
+def do_round(value, precision: int = ..., method: str = ...):
+    ...
+
+def do_groupby(environment, value, attribute):
+    ...
+
+class _GroupTuple(NamedTuple):
+    grouper: Any
+    list: Any
+    ...
+
+
+def do_sum(environment, iterable, attribute: Optional[Any] = ..., start: int = ...):
+    ...
+
+def do_list(value):
+    ...
+
+def do_mark_safe(value):
+    ...
+
+def do_mark_unsafe(value):
+    ...
+
+def do_reverse(value):
+    ...
+
+def do_attr(environment, obj, name):
+    ...
+
+def do_map(*args, **kwargs):
+    ...
+
+def do_select(*args, **kwargs):
+    ...
+
+def do_reject(*args, **kwargs):
+    ...
+
+def do_selectattr(*args, **kwargs):
+    ...
+
+def do_rejectattr(*args, **kwargs):
+    ...
+
+FILTERS: Any
diff --git a/manager/typings/jinja2/lexer.pyi b/manager/typings/jinja2/lexer.pyi
new file mode 100644 (file)
index 0000000..f61f63a
--- /dev/null
@@ -0,0 +1,180 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any, Optional, Tuple
+
+whitespace_re: Any
+string_re: Any
+integer_re: Any
+name_re: Any
+float_re: Any
+newline_re: Any
+TOKEN_ADD: Any
+TOKEN_ASSIGN: Any
+TOKEN_COLON: Any
+TOKEN_COMMA: Any
+TOKEN_DIV: Any
+TOKEN_DOT: Any
+TOKEN_EQ: Any
+TOKEN_FLOORDIV: Any
+TOKEN_GT: Any
+TOKEN_GTEQ: Any
+TOKEN_LBRACE: Any
+TOKEN_LBRACKET: Any
+TOKEN_LPAREN: Any
+TOKEN_LT: Any
+TOKEN_LTEQ: Any
+TOKEN_MOD: Any
+TOKEN_MUL: Any
+TOKEN_NE: Any
+TOKEN_PIPE: Any
+TOKEN_POW: Any
+TOKEN_RBRACE: Any
+TOKEN_RBRACKET: Any
+TOKEN_RPAREN: Any
+TOKEN_SEMICOLON: Any
+TOKEN_SUB: Any
+TOKEN_TILDE: Any
+TOKEN_WHITESPACE: Any
+TOKEN_FLOAT: Any
+TOKEN_INTEGER: Any
+TOKEN_NAME: Any
+TOKEN_STRING: Any
+TOKEN_OPERATOR: Any
+TOKEN_BLOCK_BEGIN: Any
+TOKEN_BLOCK_END: Any
+TOKEN_VARIABLE_BEGIN: Any
+TOKEN_VARIABLE_END: Any
+TOKEN_RAW_BEGIN: Any
+TOKEN_RAW_END: Any
+TOKEN_COMMENT_BEGIN: Any
+TOKEN_COMMENT_END: Any
+TOKEN_COMMENT: Any
+TOKEN_LINESTATEMENT_BEGIN: Any
+TOKEN_LINESTATEMENT_END: Any
+TOKEN_LINECOMMENT_BEGIN: Any
+TOKEN_LINECOMMENT_END: Any
+TOKEN_LINECOMMENT: Any
+TOKEN_DATA: Any
+TOKEN_INITIAL: Any
+TOKEN_EOF: Any
+operators: Any
+reverse_operators: Any
+operator_re: Any
+ignored_tokens: Any
+ignore_if_empty: Any
+def describe_token(token):
+    ...
+
+def describe_token_expr(expr):
+    ...
+
+def count_newlines(value):
+    ...
+
+def compile_rules(environment):
+    ...
+
+class Failure:
+    message: Any
+    error_class: Any
+    def __init__(self, message, cls: Any = ...) -> None:
+        ...
+    
+    def __call__(self, lineno, filename):
+        ...
+    
+
+
+class Token(Tuple[int, Any, Any]):
+    lineno: Any
+    type: Any
+    value: Any
+    def __new__(cls, lineno, type, value):
+        ...
+    
+    def test(self, expr):
+        ...
+    
+    def test_any(self, *iterable):
+        ...
+    
+
+
+class TokenStreamIterator:
+    stream: Any
+    def __init__(self, stream) -> None:
+        ...
+    
+    def __iter__(self):
+        ...
+    
+    def __next__(self):
+        ...
+    
+
+
+class TokenStream:
+    name: Any
+    filename: Any
+    closed: bool
+    current: Any
+    def __init__(self, generator, name, filename) -> None:
+        ...
+    
+    def __iter__(self):
+        ...
+    
+    def __bool__(self):
+        ...
+    
+    __nonzero__: Any
+    eos: Any
+    def push(self, token):
+        ...
+    
+    def look(self):
+        ...
+    
+    def skip(self, n: int = ...):
+        ...
+    
+    def next_if(self, expr):
+        ...
+    
+    def skip_if(self, expr):
+        ...
+    
+    def __next__(self):
+        ...
+    
+    def close(self):
+        ...
+    
+    def expect(self, expr):
+        ...
+    
+
+
+def get_lexer(environment):
+    ...
+
+class Lexer:
+    newline_sequence: Any
+    keep_trailing_newline: Any
+    rules: Any
+    def __init__(self, environment) -> None:
+        ...
+    
+    def tokenize(self, source, name: Optional[Any] = ..., filename: Optional[Any] = ..., state: Optional[Any] = ...):
+        ...
+    
+    def wrap(self, stream, name: Optional[Any] = ..., filename: Optional[Any] = ...):
+        ...
+    
+    def tokeniter(self, source, name, filename: Optional[Any] = ..., state: Optional[Any] = ...):
+        ...
+    
+
+
diff --git a/manager/typings/jinja2/loaders.pyi b/manager/typings/jinja2/loaders.pyi
new file mode 100644 (file)
index 0000000..80b6a26
--- /dev/null
@@ -0,0 +1,144 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+import sys
+from types import ModuleType
+from typing import Any, Callable, Iterable, List, Optional, Text, Tuple, Union
+from .environment import Environment
+
+if sys.version_info >= (3, 7):
+    ...
+else:
+    _SearchPath = Union[Text, Iterable[Text]]
+def split_template_path(template: Text) -> List[Text]:
+    ...
+
+class BaseLoader:
+    has_source_access: bool
+    def get_source(self, environment, template):
+        ...
+    
+    def list_templates(self):
+        ...
+    
+    def load(self, environment, name, globals: Optional[Any] = ...):
+        ...
+    
+
+
+class FileSystemLoader(BaseLoader):
+    searchpath: Text
+    encoding: Any
+    followlinks: Any
+    def __init__(self, searchpath: _SearchPath, encoding: Text = ..., followlinks: bool = ...) -> None:
+        ...
+    
+    def get_source(self, environment: Environment, template: Text) -> Tuple[Text, Text, Callable[..., Any]]:
+        ...
+    
+    def list_templates(self):
+        ...
+    
+
+
+class PackageLoader(BaseLoader):
+    encoding: Text
+    manager: Any
+    filesystem_bound: Any
+    provider: Any
+    package_path: Any
+    def __init__(self, package_name: Text, package_path: Text = ..., encoding: Text = ...) -> None:
+        ...
+    
+    def get_source(self, environment: Environment, template: Text) -> Tuple[Text, Text, Callable[..., Any]]:
+        ...
+    
+    def list_templates(self):
+        ...
+    
+
+
+class DictLoader(BaseLoader):
+    mapping: Any
+    def __init__(self, mapping) -> None:
+        ...
+    
+    def get_source(self, environment: Environment, template: Text) -> Tuple[Text, Text, Callable[..., Any]]:
+        ...
+    
+    def list_templates(self):
+        ...
+    
+
+
+class FunctionLoader(BaseLoader):
+    load_func: Any
+    def __init__(self, load_func) -> None:
+        ...
+    
+    def get_source(self, environment: Environment, template: Text) -> Tuple[Text, Optional[Text], Optional[Callable[..., Any]]]:
+        ...
+    
+
+
+class PrefixLoader(BaseLoader):
+    mapping: Any
+    delimiter: Any
+    def __init__(self, mapping, delimiter: str = ...) -> None:
+        ...
+    
+    def get_loader(self, template):
+        ...
+    
+    def get_source(self, environment: Environment, template: Text) -> Tuple[Text, Text, Callable[..., Any]]:
+        ...
+    
+    def load(self, environment, name, globals: Optional[Any] = ...):
+        ...
+    
+    def list_templates(self):
+        ...
+    
+
+
+class ChoiceLoader(BaseLoader):
+    loaders: Any
+    def __init__(self, loaders) -> None:
+        ...
+    
+    def get_source(self, environment: Environment, template: Text) -> Tuple[Text, Text, Callable[..., Any]]:
+        ...
+    
+    def load(self, environment, name, globals: Optional[Any] = ...):
+        ...
+    
+    def list_templates(self):
+        ...
+    
+
+
+class _TemplateModule(ModuleType):
+    ...
+
+
+class ModuleLoader(BaseLoader):
+    has_source_access: bool
+    module: Any
+    package_name: Any
+    def __init__(self, path) -> None:
+        ...
+    
+    @staticmethod
+    def get_template_key(name):
+        ...
+    
+    @staticmethod
+    def get_module_filename(name):
+        ...
+    
+    def load(self, environment, name, globals: Optional[Any] = ...):
+        ...
+    
+
+
diff --git a/manager/typings/jinja2/meta.pyi b/manager/typings/jinja2/meta.pyi
new file mode 100644 (file)
index 0000000..d6edd5c
--- /dev/null
@@ -0,0 +1,26 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any
+from jinja2.compiler import CodeGenerator
+
+class TrackingCodeGenerator(CodeGenerator):
+    undeclared_identifiers: Any
+    def __init__(self, environment) -> None:
+        ...
+    
+    def write(self, x):
+        ...
+    
+    def pull_locals(self, frame):
+        ...
+    
+
+
+def find_undeclared_variables(ast):
+    ...
+
+def find_referenced_templates(ast):
+    ...
+
diff --git a/manager/typings/jinja2/nodes.pyi b/manager/typings/jinja2/nodes.pyi
new file mode 100644 (file)
index 0000000..9f04e55
--- /dev/null
@@ -0,0 +1,456 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+import typing
+from typing import Any, Optional
+
+class Impossible(Exception):
+    ...
+
+
+class NodeType(type):
+    def __new__(cls, name, bases, d):
+        ...
+    
+
+
+class EvalContext:
+    environment: Any
+    autoescape: Any
+    volatile: bool
+    def __init__(self, environment, template_name: Optional[Any] = ...) -> None:
+        ...
+    
+    def save(self):
+        ...
+    
+    def revert(self, old):
+        ...
+    
+
+
+def get_eval_context(node, ctx):
+    ...
+
+class Node:
+    fields: Any
+    attributes: Any
+    abstract: bool
+    def __init__(self, *fields, **attributes) -> None:
+        ...
+    
+    def iter_fields(self, exclude: Optional[Any] = ..., only: Optional[Any] = ...):
+        ...
+    
+    def iter_child_nodes(self, exclude: Optional[Any] = ..., only: Optional[Any] = ...):
+        ...
+    
+    def find(self, node_type):
+        ...
+    
+    def find_all(self, node_type):
+        ...
+    
+    def set_ctx(self, ctx):
+        ...
+    
+    def set_lineno(self, lineno, override: bool = ...):
+        ...
+    
+    def set_environment(self, environment):
+        ...
+    
+    def __eq__(self, other) -> bool:
+        ...
+    
+    def __ne__(self, other) -> bool:
+        ...
+    
+    __hash__: Any
+
+
+class Stmt(Node):
+    abstract: bool
+    ...
+
+
+class Helper(Node):
+    abstract: bool
+    ...
+
+
+class Template(Node):
+    fields: Any
+    ...
+
+
+class Output(Stmt):
+    fields: Any
+    ...
+
+
+class Extends(Stmt):
+    fields: Any
+    ...
+
+
+class For(Stmt):
+    fields: Any
+    ...
+
+
+class If(Stmt):
+    fields: Any
+    ...
+
+
+class Macro(Stmt):
+    fields: Any
+    name: str
+    args: typing.List[Any]
+    defaults: typing.List[Any]
+    body: typing.List[Any]
+    ...
+
+
+class CallBlock(Stmt):
+    fields: Any
+    ...
+
+
+class FilterBlock(Stmt):
+    fields: Any
+    ...
+
+
+class Block(Stmt):
+    fields: Any
+    ...
+
+
+class Include(Stmt):
+    fields: Any
+    ...
+
+
+class Import(Stmt):
+    fields: Any
+    ...
+
+
+class FromImport(Stmt):
+    fields: Any
+    ...
+
+
+class ExprStmt(Stmt):
+    fields: Any
+    ...
+
+
+class Assign(Stmt):
+    fields: Any
+    ...
+
+
+class AssignBlock(Stmt):
+    fields: Any
+    ...
+
+
+class Expr(Node):
+    abstract: bool
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+    def can_assign(self):
+        ...
+    
+
+
+class BinExpr(Expr):
+    fields: Any
+    operator: Any
+    abstract: bool
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class UnaryExpr(Expr):
+    fields: Any
+    operator: Any
+    abstract: bool
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Name(Expr):
+    fields: Any
+    def can_assign(self):
+        ...
+    
+
+
+class Literal(Expr):
+    abstract: bool
+    ...
+
+
+class Const(Literal):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+    @classmethod
+    def from_untrusted(cls, value, lineno: Optional[Any] = ..., environment: Optional[Any] = ...):
+        ...
+    
+
+
+class TemplateData(Literal):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Tuple(Literal):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+    def can_assign(self):
+        ...
+    
+
+
+class List(Literal):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Dict(Literal):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Pair(Helper):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Keyword(Helper):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class CondExpr(Expr):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Filter(Expr):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Test(Expr):
+    fields: Any
+    ...
+
+
+class Call(Expr):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Getitem(Expr):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+    def can_assign(self):
+        ...
+    
+
+
+class Getattr(Expr):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+    def can_assign(self):
+        ...
+    
+
+
+class Slice(Expr):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Concat(Expr):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Compare(Expr):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Operand(Helper):
+    fields: Any
+    ...
+
+
+class Mul(BinExpr):
+    operator: str
+    ...
+
+
+class Div(BinExpr):
+    operator: str
+    ...
+
+
+class FloorDiv(BinExpr):
+    operator: str
+    ...
+
+
+class Add(BinExpr):
+    operator: str
+    ...
+
+
+class Sub(BinExpr):
+    operator: str
+    ...
+
+
+class Mod(BinExpr):
+    operator: str
+    ...
+
+
+class Pow(BinExpr):
+    operator: str
+    ...
+
+
+class And(BinExpr):
+    operator: str
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Or(BinExpr):
+    operator: str
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class Not(UnaryExpr):
+    operator: str
+    ...
+
+
+class Neg(UnaryExpr):
+    operator: str
+    ...
+
+
+class Pos(UnaryExpr):
+    operator: str
+    ...
+
+
+class EnvironmentAttribute(Expr):
+    fields: Any
+    ...
+
+
+class ExtensionAttribute(Expr):
+    fields: Any
+    ...
+
+
+class ImportedName(Expr):
+    fields: Any
+    ...
+
+
+class InternalName(Expr):
+    fields: Any
+    def __init__(self) -> None:
+        ...
+    
+
+
+class MarkSafe(Expr):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class MarkSafeIfAutoescape(Expr):
+    fields: Any
+    def as_const(self, eval_ctx: Optional[Any] = ...):
+        ...
+    
+
+
+class ContextReference(Expr):
+    ...
+
+
+class Continue(Stmt):
+    ...
+
+
+class Break(Stmt):
+    ...
+
+
+class Scope(Stmt):
+    fields: Any
+    ...
+
+
+class EvalContextModifier(Stmt):
+    fields: Any
+    ...
+
+
+class ScopedEvalContextModifier(EvalContextModifier):
+    fields: Any
+    ...
+
+
diff --git a/manager/typings/jinja2/optimizer.pyi b/manager/typings/jinja2/optimizer.pyi
new file mode 100644 (file)
index 0000000..84ded1a
--- /dev/null
@@ -0,0 +1,42 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any
+from jinja2.visitor import NodeTransformer
+
+def optimize(node, environment):
+    ...
+
+class Optimizer(NodeTransformer):
+    environment: Any
+    def __init__(self, environment) -> None:
+        ...
+    
+    def visit_If(self, node):
+        ...
+    
+    def fold(self, node):
+        ...
+    
+    visit_Add: Any
+    visit_Sub: Any
+    visit_Mul: Any
+    visit_Div: Any
+    visit_FloorDiv: Any
+    visit_Pow: Any
+    visit_Mod: Any
+    visit_And: Any
+    visit_Or: Any
+    visit_Pos: Any
+    visit_Neg: Any
+    visit_Not: Any
+    visit_Compare: Any
+    visit_Getitem: Any
+    visit_Getattr: Any
+    visit_Call: Any
+    visit_Filter: Any
+    visit_Test: Any
+    visit_CondExpr: Any
+
+
diff --git a/manager/typings/jinja2/parser.pyi b/manager/typings/jinja2/parser.pyi
new file mode 100644 (file)
index 0000000..7d7fd41
--- /dev/null
@@ -0,0 +1,168 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any, Optional
+
+class Parser:
+    environment: Any
+    stream: Any
+    name: Any
+    filename: Any
+    closed: bool
+    extensions: Any
+    def __init__(self, environment, source, name: Optional[Any] = ..., filename: Optional[Any] = ..., state: Optional[Any] = ...) -> None:
+        ...
+    
+    def fail(self, msg, lineno: Optional[Any] = ..., exc: Any = ...):
+        ...
+    
+    def fail_unknown_tag(self, name, lineno: Optional[Any] = ...):
+        ...
+    
+    def fail_eof(self, end_tokens: Optional[Any] = ..., lineno: Optional[Any] = ...):
+        ...
+    
+    def is_tuple_end(self, extra_end_rules: Optional[Any] = ...):
+        ...
+    
+    def free_identifier(self, lineno: Optional[Any] = ...):
+        ...
+    
+    def parse_statement(self):
+        ...
+    
+    def parse_statements(self, end_tokens, drop_needle: bool = ...):
+        ...
+    
+    def parse_set(self):
+        ...
+    
+    def parse_for(self):
+        ...
+    
+    def parse_if(self):
+        ...
+    
+    def parse_block(self):
+        ...
+    
+    def parse_extends(self):
+        ...
+    
+    def parse_import_context(self, node, default):
+        ...
+    
+    def parse_include(self):
+        ...
+    
+    def parse_import(self):
+        ...
+    
+    def parse_from(self):
+        ...
+    
+    def parse_signature(self, node):
+        ...
+    
+    def parse_call_block(self):
+        ...
+    
+    def parse_filter_block(self):
+        ...
+    
+    def parse_macro(self):
+        ...
+    
+    def parse_print(self):
+        ...
+    
+    def parse_assign_target(self, with_tuple: bool = ..., name_only: bool = ..., extra_end_rules: Optional[Any] = ...):
+        ...
+    
+    def parse_expression(self, with_condexpr: bool = ...):
+        ...
+    
+    def parse_condexpr(self):
+        ...
+    
+    def parse_or(self):
+        ...
+    
+    def parse_and(self):
+        ...
+    
+    def parse_not(self):
+        ...
+    
+    def parse_compare(self):
+        ...
+    
+    def parse_add(self):
+        ...
+    
+    def parse_sub(self):
+        ...
+    
+    def parse_concat(self):
+        ...
+    
+    def parse_mul(self):
+        ...
+    
+    def parse_div(self):
+        ...
+    
+    def parse_floordiv(self):
+        ...
+    
+    def parse_mod(self):
+        ...
+    
+    def parse_pow(self):
+        ...
+    
+    def parse_unary(self, with_filter: bool = ...):
+        ...
+    
+    def parse_primary(self):
+        ...
+    
+    def parse_tuple(self, simplified: bool = ..., with_condexpr: bool = ..., extra_end_rules: Optional[Any] = ..., explicit_parentheses: bool = ...):
+        ...
+    
+    def parse_list(self):
+        ...
+    
+    def parse_dict(self):
+        ...
+    
+    def parse_postfix(self, node):
+        ...
+    
+    def parse_filter_expr(self, node):
+        ...
+    
+    def parse_subscript(self, node):
+        ...
+    
+    def parse_subscribed(self):
+        ...
+    
+    def parse_call(self, node):
+        ...
+    
+    def parse_filter(self, node, start_inline: bool = ...):
+        ...
+    
+    def parse_test(self, node):
+        ...
+    
+    def subparse(self, end_tokens: Optional[Any] = ...):
+        ...
+    
+    def parse(self):
+        ...
+    
+
+
diff --git a/manager/typings/jinja2/runtime.pyi b/manager/typings/jinja2/runtime.pyi
new file mode 100644 (file)
index 0000000..97ff119
--- /dev/null
@@ -0,0 +1,214 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any, Dict, Optional, Text, Union
+from jinja2.environment import Environment
+
+to_string: Any
+identity: Any
+def markup_join(seq):
+    ...
+
+def unicode_join(seq):
+    ...
+
+class TemplateReference:
+    def __init__(self, context) -> None:
+        ...
+    
+    def __getitem__(self, name):
+        ...
+    
+
+
+class Context:
+    parent: Union[Context, Dict[str, Any]]
+    vars: Dict[str, Any]
+    environment: Environment
+    eval_ctx: Any
+    exported_vars: Any
+    name: Text
+    blocks: Dict[str, Any]
+    def __init__(self, environment: Environment, parent: Union[Context, Dict[str, Any]], name: Text, blocks: Dict[str, Any]) -> None:
+        ...
+    
+    def super(self, name, current):
+        ...
+    
+    def get(self, key, default: Optional[Any] = ...):
+        ...
+    
+    def resolve(self, key):
+        ...
+    
+    def get_exported(self):
+        ...
+    
+    def get_all(self):
+        ...
+    
+    def call(__self, __obj, *args, **kwargs):
+        ...
+    
+    def derived(self, locals: Optional[Any] = ...):
+        ...
+    
+    keys: Any
+    values: Any
+    items: Any
+    iterkeys: Any
+    itervalues: Any
+    iteritems: Any
+    def __contains__(self, name):
+        ...
+    
+    def __getitem__(self, key):
+        ...
+    
+
+
+class BlockReference:
+    name: Any
+    def __init__(self, name, context, stack, depth) -> None:
+        ...
+    
+    @property
+    def super(self):
+        ...
+    
+    def __call__(self):
+        ...
+    
+
+
+class LoopContext:
+    index0: int
+    depth0: Any
+    def __init__(self, iterable, recurse: Optional[Any] = ..., depth0: int = ...) -> None:
+        ...
+    
+    def cycle(self, *args):
+        ...
+    
+    first: Any
+    last: Any
+    index: Any
+    revindex: Any
+    revindex0: Any
+    depth: Any
+    def __len__(self):
+        ...
+    
+    def __iter__(self):
+        ...
+    
+    def loop(self, iterable):
+        ...
+    
+    __call__: Any
+    @property
+    def length(self):
+        ...
+    
+
+
+class LoopContextIterator:
+    context: Any
+    def __init__(self, context) -> None:
+        ...
+    
+    def __iter__(self):
+        ...
+    
+    def __next__(self):
+        ...
+    
+
+
+class Macro:
+    name: Any
+    arguments: Any
+    defaults: Any
+    catch_kwargs: Any
+    catch_varargs: Any
+    caller: Any
+    def __init__(self, environment, func, name, arguments, defaults, catch_kwargs, catch_varargs, caller) -> None:
+        ...
+    
+    def __call__(self, *args, **kwargs):
+        ...
+    
+
+
+class Undefined:
+    def __init__(self, hint: Optional[Any] = ..., obj: Any = ..., name: Optional[Any] = ..., exc: Any = ...) -> None:
+        ...
+    
+    def __getattr__(self, name):
+        ...
+    
+    __add__: Any
+    __radd__: Any
+    __mul__: Any
+    __rmul__: Any
+    __div__: Any
+    __rdiv__: Any
+    __truediv__: Any
+    __rtruediv__: Any
+    __floordiv__: Any
+    __rfloordiv__: Any
+    __mod__: Any
+    __rmod__: Any
+    __pos__: Any
+    __neg__: Any
+    __call__: Any
+    __getitem__: Any
+    __lt__: Any
+    __le__: Any
+    __gt__: Any
+    __ge__: Any
+    __int__: Any
+    __float__: Any
+    __complex__: Any
+    __pow__: Any
+    __rpow__: Any
+    def __eq__(self, other) -> bool:
+        ...
+    
+    def __ne__(self, other) -> bool:
+        ...
+    
+    def __hash__(self) -> int:
+        ...
+    
+    def __len__(self):
+        ...
+    
+    def __iter__(self):
+        ...
+    
+    def __nonzero__(self):
+        ...
+    
+    __bool__: Any
+
+
+def make_logging_undefined(logger: Optional[Any] = ..., base: Optional[Any] = ...):
+    ...
+
+class DebugUndefined(Undefined):
+    ...
+
+
+class StrictUndefined(Undefined):
+    __iter__: Any
+    __len__: Any
+    __nonzero__: Any
+    __eq__: Any
+    __ne__: Any
+    __bool__: Any
+    __hash__: Any
+    ...
+
+
diff --git a/manager/typings/jinja2/sandbox.pyi b/manager/typings/jinja2/sandbox.pyi
new file mode 100644 (file)
index 0000000..62652d3
--- /dev/null
@@ -0,0 +1,69 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any
+from jinja2.environment import Environment
+
+MAX_RANGE: int
+UNSAFE_FUNCTION_ATTRIBUTES: Any
+UNSAFE_METHOD_ATTRIBUTES: Any
+UNSAFE_GENERATOR_ATTRIBUTES: Any
+def safe_range(*args):
+    ...
+
+def unsafe(f):
+    ...
+
+def is_internal_attribute(obj, attr):
+    ...
+
+def modifies_known_mutable(obj, attr):
+    ...
+
+class SandboxedEnvironment(Environment):
+    sandboxed: bool
+    default_binop_table: Any
+    default_unop_table: Any
+    intercepted_binops: Any
+    intercepted_unops: Any
+    def intercept_unop(self, operator):
+        ...
+    
+    binop_table: Any
+    unop_table: Any
+    def __init__(self, *args, **kwargs) -> None:
+        ...
+    
+    def is_safe_attribute(self, obj, attr, value):
+        ...
+    
+    def is_safe_callable(self, obj):
+        ...
+    
+    def call_binop(self, context, operator, left, right):
+        ...
+    
+    def call_unop(self, context, operator, arg):
+        ...
+    
+    def getitem(self, obj, argument):
+        ...
+    
+    def getattr(self, obj, attribute):
+        ...
+    
+    def unsafe_undefined(self, obj, attribute):
+        ...
+    
+    def call(__self, __context, __obj, *args, **kwargs):
+        ...
+    
+
+
+class ImmutableSandboxedEnvironment(SandboxedEnvironment):
+    def is_safe_attribute(self, obj, attr, value):
+        ...
+    
+
+
diff --git a/manager/typings/jinja2/tests.pyi b/manager/typings/jinja2/tests.pyi
new file mode 100644 (file)
index 0000000..7d2f759
--- /dev/null
@@ -0,0 +1,58 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from typing import Any
+
+number_re: Any
+regex_type: Any
+test_callable: Any
+def test_odd(value):
+    ...
+
+def test_even(value):
+    ...
+
+def test_divisibleby(value, num):
+    ...
+
+def test_defined(value):
+    ...
+
+def test_undefined(value):
+    ...
+
+def test_none(value):
+    ...
+
+def test_lower(value):
+    ...
+
+def test_upper(value):
+    ...
+
+def test_string(value):
+    ...
+
+def test_mapping(value):
+    ...
+
+def test_number(value):
+    ...
+
+def test_sequence(value):
+    ...
+
+def test_equalto(value, other):
+    ...
+
+def test_sameas(value, other):
+    ...
+
+def test_iterable(value):
+    ...
+
+def test_escaped(value):
+    ...
+
+TESTS: Any
diff --git a/manager/typings/jinja2/utils.pyi b/manager/typings/jinja2/utils.pyi
new file mode 100644 (file)
index 0000000..66cbea5
--- /dev/null
@@ -0,0 +1,165 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+from _typeshed import AnyPath
+from typing import Any, Callable, IO, Iterable, Optional, Protocol, Text, TypeVar, Union
+from typing_extensions import Literal
+from markupsafe import Markup as Markup
+
+missing: Any
+internal_code: Any
+concat: Any
+_CallableT = TypeVar("_CallableT", bound=Callable[..., Any])
+class _ContextFunction(Protocol[_CallableT]):
+    contextfunction: Literal[True]
+    __call__: _CallableT
+    ...
+
+
+class _EvalContextFunction(Protocol[_CallableT]):
+    evalcontextfunction: Literal[True]
+    __call__: _CallableT
+    ...
+
+
+class _EnvironmentFunction(Protocol[_CallableT]):
+    environmentfunction: Literal[True]
+    __call__: _CallableT
+    ...
+
+
+def contextfunction(f: _CallableT) -> _ContextFunction[_CallableT]:
+    ...
+
+def evalcontextfunction(f: _CallableT) -> _EvalContextFunction[_CallableT]:
+    ...
+
+def environmentfunction(f: _CallableT) -> _EnvironmentFunction[_CallableT]:
+    ...
+
+def internalcode(f: _CallableT) -> _CallableT:
+    ...
+
+def is_undefined(obj: object) -> bool:
+    ...
+
+def select_autoescape(enabled_extensions: Iterable[str] = ..., disabled_extensions: Iterable[str] = ..., default_for_string: bool = ..., default: bool = ...) -> Callable[[str], bool]:
+    ...
+
+def consume(iterable: Iterable[object]) -> None:
+    ...
+
+def clear_caches() -> None:
+    ...
+
+def import_string(import_name: str, silent: bool = ...) -> Any:
+    ...
+
+def open_if_exists(filename: AnyPath, mode: str = ...) -> Optional[IO[Any]]:
+    ...
+
+def object_type_repr(obj: object) -> str:
+    ...
+
+def pformat(obj: object, verbose: bool = ...) -> str:
+    ...
+
+def urlize(text: Union[Markup, Text], trim_url_limit: Optional[int] = ..., rel: Optional[Union[Markup, Text]] = ..., target: Optional[Union[Markup, Text]] = ...) -> str:
+    ...
+
+def generate_lorem_ipsum(n: int = ..., html: bool = ..., min: int = ..., max: int = ...) -> Union[Markup, str]:
+    ...
+
+def unicode_urlencode(obj: object, charset: str = ..., for_qs: bool = ...) -> str:
+    ...
+
+class LRUCache:
+    capacity: Any
+    def __init__(self, capacity) -> None:
+        ...
+    
+    def __getnewargs__(self):
+        ...
+    
+    def copy(self):
+        ...
+    
+    def get(self, key, default: Optional[Any] = ...):
+        ...
+    
+    def setdefault(self, key, default: Optional[Any] = ...):
+        ...
+    
+    def clear(self):
+        ...
+    
+    def __contains__(self, key):
+        ...
+    
+    def __len__(self):
+        ...
+    
+    def __getitem__(self, key):
+        ...
+    
+    def __setitem__(self, key, value):
+        ...
+    
+    def __delitem__(self, key):
+        ...
+    
+    def items(self):
+        ...
+    
+    def iteritems(self):
+        ...
+    
+    def values(self):
+        ...
+    
+    def itervalue(self):
+        ...
+    
+    def keys(self):
+        ...
+    
+    def iterkeys(self):
+        ...
+    
+    __iter__: Any
+    def __reversed__(self):
+        ...
+    
+    __copy__: Any
+
+
+class Cycler:
+    items: Any
+    def __init__(self, *items) -> None:
+        ...
+    
+    pos: int
+    def reset(self):
+        ...
+    
+    @property
+    def current(self):
+        ...
+    
+    def __next__(self):
+        ...
+    
+
+
+class Joiner:
+    sep: Any
+    used: bool
+    def __init__(self, sep: str = ...) -> None:
+        ...
+    
+    def __call__(self):
+        ...
+    
+
+
diff --git a/manager/typings/jinja2/visitor.pyi b/manager/typings/jinja2/visitor.pyi
new file mode 100644 (file)
index 0000000..f738bf0
--- /dev/null
@@ -0,0 +1,25 @@
+"""
+This type stub file was generated by pyright.
+"""
+
+class NodeVisitor:
+    def get_visitor(self, node):
+        ...
+    
+    def visit(self, node, *args, **kwargs):
+        ...
+    
+    def generic_visit(self, node, *args, **kwargs):
+        ...
+    
+
+
+class NodeTransformer(NodeVisitor):
+    def generic_visit(self, node, *args, **kwargs):
+        ...
+    
+    def visit_list(self, node, *args, **kwargs):
+        ...
+    
+
+