Compare commits
	
		
			6 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | ec35f5f2c8 | ||
|   | 9ae25e6744 | ||
|   | 758f10c513 | ||
|   | 140d27ef96 | ||
|   | 209840b771 | ||
|   | 20fd58b8d7 | 
| @@ -19,7 +19,7 @@ import sys | ||||
| root_directory = os.path.dirname(os.getcwd()) | ||||
| sys.path.insert(0, root_directory) | ||||
|  | ||||
| import sanic | ||||
| import sanic  # noqa: E402 | ||||
|  | ||||
|  | ||||
| # -- General configuration ------------------------------------------------ | ||||
|   | ||||
| @@ -25,5 +25,6 @@ def key_exist_handler(request): | ||||
|  | ||||
|     return text("num does not exist in request") | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     app.run(host="0.0.0.0", port=8000, debug=True) | ||||
|   | ||||
| @@ -69,5 +69,6 @@ async def runner(app: Sanic, app_server: AsyncioServer): | ||||
|         app.is_running = False | ||||
|         app.is_stopping = True | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     https.run(port=HTTPS_PORT, debug=True) | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import requests | ||||
|  | ||||
|  | ||||
| # Warning: This is a heavy process. | ||||
|  | ||||
| data = "" | ||||
|   | ||||
| @@ -35,6 +35,7 @@ async def after_server_stop(app, loop): | ||||
| async def test(request): | ||||
|     return response.json({"answer": "42"}) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     asyncio.set_event_loop(uvloop.new_event_loop()) | ||||
|     serv_coro = app.create_server( | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import re | ||||
|  | ||||
| from pathlib import Path | ||||
| from textwrap import indent | ||||
|  | ||||
|   | ||||
							
								
								
									
										7
									
								
								guide/pyproject.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								guide/pyproject.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| [tool.ruff] | ||||
| extend = "../pyproject.toml" | ||||
|  | ||||
| [tool.ruff.isort] | ||||
| known-first-party = ["webapp"] | ||||
| lines-after-imports = 1 | ||||
| lines-between-types = 1 | ||||
| @@ -2,7 +2,6 @@ from __future__ import annotations | ||||
|  | ||||
| from html5tagger import Builder, Document  # type: ignore | ||||
|  | ||||
|  | ||||
| class BaseRenderer: | ||||
|     def __init__(self, base_title: str): | ||||
|         self.base_title = base_title | ||||
|   | ||||
| @@ -7,7 +7,6 @@ from pygments.token import (  # Error,; Generic,; Number,; Operator, | ||||
|     Token, | ||||
| ) | ||||
|  | ||||
|  | ||||
| class SanicCodeStyle(Style): | ||||
|     styles = { | ||||
|         Token: "#777", | ||||
|   | ||||
| @@ -6,7 +6,6 @@ from typing import Generator | ||||
| from html5tagger import Builder | ||||
| from sanic import Request | ||||
|  | ||||
|  | ||||
| class BaseLayout: | ||||
|     def __init__(self, builder: Builder): | ||||
|         self.builder = builder | ||||
|   | ||||
| @@ -3,7 +3,6 @@ from datetime import datetime | ||||
| from html5tagger import Builder, E  # type: ignore | ||||
| from sanic import Request | ||||
|  | ||||
|  | ||||
| def do_footer(builder: Builder, request: Request) -> None: | ||||
|     builder.footer( | ||||
|         _pagination(request), | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| from webapp.display.layouts.models import MenuItem | ||||
|  | ||||
| from html5tagger import Builder, E  # type: ignore | ||||
| from sanic import Request | ||||
|  | ||||
| from webapp.display.layouts.models import MenuItem | ||||
|  | ||||
| def do_navbar(builder: Builder, request: Request) -> None: | ||||
|     navbar_items = [ | ||||
|   | ||||
| @@ -1,9 +1,8 @@ | ||||
| from webapp.display.layouts.models import MenuItem | ||||
| from webapp.display.text import slugify | ||||
|  | ||||
| from html5tagger import Builder, E  # type: ignore | ||||
| from sanic import Request | ||||
|  | ||||
| from webapp.display.layouts.models import MenuItem | ||||
| from webapp.display.text import slugify | ||||
|  | ||||
| def do_sidebar(builder: Builder, request: Request) -> None: | ||||
|     builder.a(class_="burger")(E.span().span().span().span()) | ||||
|   | ||||
| @@ -8,7 +8,6 @@ from sanic import Request | ||||
|  | ||||
| from .base import BaseLayout | ||||
|  | ||||
|  | ||||
| class HomeLayout(BaseLayout): | ||||
|     @contextmanager | ||||
|     def layout( | ||||
|   | ||||
| @@ -1,15 +1,14 @@ | ||||
| from contextlib import contextmanager | ||||
| from typing import Generator | ||||
|  | ||||
| from sanic import Request | ||||
|  | ||||
| from webapp.display.layouts.elements.footer import do_footer | ||||
| from webapp.display.layouts.elements.navbar import do_navbar | ||||
| from webapp.display.layouts.elements.sidebar import do_sidebar | ||||
|  | ||||
| from sanic import Request | ||||
|  | ||||
| from .base import BaseLayout | ||||
|  | ||||
|  | ||||
| class MainLayout(BaseLayout): | ||||
|     @contextmanager | ||||
|     def layout( | ||||
|   | ||||
| @@ -2,7 +2,6 @@ from __future__ import annotations | ||||
|  | ||||
| from msgspec import Struct, field | ||||
|  | ||||
|  | ||||
| class MenuItem(Struct, kw_only=False, omit_defaults=True): | ||||
|     label: str | ||||
|     path: str | None = None | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| import re | ||||
|  | ||||
| from textwrap import dedent | ||||
|  | ||||
| from html5tagger import HTML, Builder, E  # type: ignore | ||||
| from mistune import HTMLRenderer, create_markdown, escape | ||||
| from mistune.directives import RSTDirective, TableOfContents | ||||
| from mistune.util import safe_entity | ||||
| @@ -8,8 +10,6 @@ from pygments import highlight | ||||
| from pygments.formatters import html | ||||
| from pygments.lexers import get_lexer_by_name | ||||
|  | ||||
| from html5tagger import HTML, Builder, E  # type: ignore | ||||
|  | ||||
| from .code_style import SanicCodeStyle | ||||
| from .plugins.attrs import Attributes | ||||
| from .plugins.columns import Column | ||||
| @@ -20,7 +20,6 @@ from .plugins.span import span | ||||
| from .plugins.tabs import Tabs | ||||
| from .text import slugify | ||||
|  | ||||
|  | ||||
| class DocsRenderer(HTMLRenderer): | ||||
|     def block_code(self, code: str, info: str | None = None): | ||||
|         builder = Builder("Block") | ||||
|   | ||||
| @@ -3,6 +3,7 @@ from __future__ import annotations | ||||
| import importlib | ||||
| import inspect | ||||
| import pkgutil | ||||
|  | ||||
| from collections import defaultdict | ||||
| from dataclasses import dataclass, field | ||||
| from html import escape | ||||
| @@ -10,12 +11,10 @@ from html import escape | ||||
| from docstring_parser import Docstring, DocstringParam, DocstringRaises | ||||
| from docstring_parser import parse as parse_docstring | ||||
| from docstring_parser.common import DocstringExample | ||||
|  | ||||
| from html5tagger import HTML, Builder, E  # type: ignore | ||||
|  | ||||
| from ..markdown import render_markdown, slugify | ||||
|  | ||||
|  | ||||
| @dataclass | ||||
| class DocObject: | ||||
|     name: str | ||||
|   | ||||
| @@ -3,15 +3,14 @@ from __future__ import annotations | ||||
| from contextlib import contextmanager | ||||
| from typing import Type | ||||
|  | ||||
| from webapp.display.base import BaseRenderer | ||||
|  | ||||
| from html5tagger import HTML, Builder  # type: ignore | ||||
| from sanic import Request | ||||
|  | ||||
| from webapp.display.base import BaseRenderer | ||||
|  | ||||
| from ..layouts.base import BaseLayout | ||||
| from .page import Page | ||||
|  | ||||
|  | ||||
| class PageRenderer(BaseRenderer): | ||||
|     def render(self, request: Request, language: str, path: str) -> Builder: | ||||
|         builder = self.get_builder( | ||||
|   | ||||
| @@ -2,13 +2,11 @@ from re import Match | ||||
| from textwrap import dedent | ||||
| from typing import Any | ||||
|  | ||||
| from html5tagger import HTML, E | ||||
| from mistune.block_parser import BlockParser | ||||
| from mistune.core import BlockState | ||||
| from mistune.directives import DirectivePlugin | ||||
|  | ||||
| from html5tagger import HTML, E | ||||
|  | ||||
|  | ||||
| class Attributes(DirectivePlugin): | ||||
|     def __call__(self, directive, md): | ||||
|         directive.register("attrs", self.parse) | ||||
|   | ||||
| @@ -8,7 +8,6 @@ from mistune.core import BlockState | ||||
| from mistune.directives import DirectivePlugin, RSTDirective | ||||
| from mistune.markdown import Markdown | ||||
|  | ||||
|  | ||||
| class Column(DirectivePlugin): | ||||
|     def parse( | ||||
|         self, block: BlockParser, m: Match, state: BlockState | ||||
|   | ||||
| @@ -2,7 +2,6 @@ from mistune.core import BlockState | ||||
| from mistune.directives import DirectivePlugin, RSTDirective | ||||
| from mistune.markdown import Markdown | ||||
|  | ||||
|  | ||||
| class Hook(DirectivePlugin): | ||||
|     def __call__(  # type: ignore | ||||
|         self, directive: RSTDirective, md: Markdown | ||||
|   | ||||
| @@ -3,15 +3,13 @@ from re import Match | ||||
| from textwrap import dedent | ||||
| from typing import Any | ||||
|  | ||||
| from html5tagger import HTML, E | ||||
| from mistune import HTMLRenderer | ||||
| from mistune.block_parser import BlockParser | ||||
| from mistune.core import BlockState | ||||
| from mistune.directives import DirectivePlugin, RSTDirective | ||||
| from mistune.markdown import Markdown | ||||
|  | ||||
| from html5tagger import HTML, E | ||||
|  | ||||
|  | ||||
| class Mermaid(DirectivePlugin): | ||||
|     def parse( | ||||
|         self, block: BlockParser, m: Match, state: BlockState | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| from mistune.directives import Admonition | ||||
|  | ||||
| from html5tagger import HTML, E | ||||
|  | ||||
| from mistune.directives import Admonition | ||||
|  | ||||
| class Notification(Admonition): | ||||
|     SUPPORTED_NAMES = { | ||||
|   | ||||
| @@ -2,7 +2,6 @@ import re | ||||
|  | ||||
| from mistune.markdown import Markdown | ||||
|  | ||||
|  | ||||
| def parse_inline_span(inline, m: re.Match, state): | ||||
|     state.append_token( | ||||
|         { | ||||
|   | ||||
| @@ -8,7 +8,6 @@ from mistune.core import BlockState | ||||
| from mistune.directives import DirectivePlugin, RSTDirective | ||||
| from mistune.markdown import Markdown | ||||
|  | ||||
|  | ||||
| class Tabs(DirectivePlugin): | ||||
|     def parse( | ||||
|         self, block: BlockParser, m: Match, state: BlockState | ||||
|   | ||||
| @@ -1,15 +1,14 @@ | ||||
| from contextlib import contextmanager | ||||
| from urllib.parse import unquote | ||||
|  | ||||
| from webapp.display.search.search import Searcher | ||||
|  | ||||
| from html5tagger import Builder, E  # type: ignore | ||||
| from sanic import Request | ||||
|  | ||||
| from webapp.display.search.search import Searcher | ||||
|  | ||||
| from ..base import BaseRenderer | ||||
| from ..layouts.main import MainLayout | ||||
|  | ||||
|  | ||||
| class SearchRenderer(BaseRenderer): | ||||
|     def render( | ||||
|         self, request: Request, language: str, searcher: Searcher, full: bool | ||||
|   | ||||
| @@ -5,8 +5,8 @@ from pathlib import Path | ||||
| from typing import ClassVar | ||||
|  | ||||
| from msgspec import Struct | ||||
| from webapp.display.page import Page | ||||
|  | ||||
| from webapp.display.page import Page | ||||
|  | ||||
| class Stemmer: | ||||
|     STOP_WORDS: ClassVar[set[str]] = set( | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| # from urllib.parse import unquote | ||||
|  | ||||
| from sanic import Blueprint, Request, Sanic, html | ||||
|  | ||||
| from webapp.display.page import Page | ||||
| from webapp.display.search.renderer import SearchRenderer | ||||
| from webapp.display.search.search import Document, Searcher, Stemmer | ||||
|  | ||||
| from sanic import Blueprint, Request, Sanic, html | ||||
|  | ||||
| bp = Blueprint("search", url_prefix="/<language>/search") | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| from pathlib import Path | ||||
|  | ||||
| from msgspec import yaml | ||||
| from webapp.display.layouts.models import GeneralConfig, MenuItem | ||||
|  | ||||
| from webapp.display.layouts.models import GeneralConfig, MenuItem | ||||
|  | ||||
| def load_menu(path: Path) -> list[MenuItem]: | ||||
|     loaded = yaml.decode(path.read_bytes(), type=dict[str, list[MenuItem]]) | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| from pathlib import Path | ||||
|  | ||||
| from sanic import Request, Sanic, html, redirect | ||||
|  | ||||
| from webapp.display.layouts.models import MenuItem | ||||
| from webapp.display.page import Page, PageRenderer | ||||
| from webapp.endpoint.view import bp | ||||
| @@ -7,9 +9,6 @@ from webapp.worker.config import load_config, load_menu | ||||
| from webapp.worker.reload import setup_livereload | ||||
| from webapp.worker.style import setup_style | ||||
|  | ||||
| from sanic import Request, Sanic, html, redirect | ||||
|  | ||||
|  | ||||
| def _compile_sidebar_order(items: list[MenuItem]) -> list[str]: | ||||
|     order = [] | ||||
|     for item in items: | ||||
|   | ||||
| @@ -8,7 +8,6 @@ import ujson | ||||
|  | ||||
| from sanic import Request, Sanic, Websocket | ||||
|  | ||||
|  | ||||
| def setup_livereload(app: Sanic) -> None: | ||||
|     @app.main_process_start | ||||
|     async def main_process_start(app: Sanic): | ||||
|   | ||||
| @@ -1,11 +1,10 @@ | ||||
| # from scss.compiler import compile_string | ||||
|  | ||||
| from pygments.formatters import html | ||||
| from sass import compile as compile_scss | ||||
| from webapp.display.code_style import SanicCodeStyle | ||||
|  | ||||
| from sanic import Sanic | ||||
| from sass import compile as compile_scss | ||||
|  | ||||
| from webapp.display.code_style import SanicCodeStyle | ||||
|  | ||||
| def setup_style(app: Sanic) -> None: | ||||
|     index = app.config.STYLE_DIR / "index.scss" | ||||
|   | ||||
| @@ -2,6 +2,19 @@ | ||||
| requires = ["setuptools", "wheel"] | ||||
| build-backend = "setuptools.build_meta" | ||||
|  | ||||
| [tool.ruff] | ||||
| extend-select = ["I"] | ||||
| ignore = ["D100", "D101", "D102", "D103", "E402", "E741", "F811", "F821"] | ||||
| line-length = 79 | ||||
| show-source = true | ||||
| show-fixes = true | ||||
|  | ||||
| [tool.ruff.isort] | ||||
| known-first-party = ["sanic"] | ||||
| known-third-party = ["pytest"] | ||||
| lines-after-imports = 2 | ||||
| lines-between-types = 1 | ||||
|  | ||||
| [tool.black] | ||||
| line-length = 79 | ||||
|  | ||||
|   | ||||
| @@ -349,8 +349,7 @@ def parse_content_header(value: str) -> Tuple[str, Options]: | ||||
|         options: Dict[str, Union[int, str]] = {} | ||||
|     else: | ||||
|         options = { | ||||
|             m.group(1) | ||||
|             .lower(): (m.group(2) or m.group(3)) | ||||
|             m.group(1).lower(): (m.group(2) or m.group(3)) | ||||
|             .replace("%22", '"') | ||||
|             .replace("%0D%0A", "\n") | ||||
|             for m in _param.finditer(value[pos:]) | ||||
|   | ||||
| @@ -3,7 +3,6 @@ from __future__ import annotations | ||||
| import os | ||||
| import ssl | ||||
|  | ||||
| from pathlib import Path, PurePath | ||||
| from typing import Any, Dict, Iterable, Optional, Union | ||||
|  | ||||
| from sanic.log import logger | ||||
| @@ -40,23 +39,23 @@ def create_context( | ||||
|  | ||||
|  | ||||
| def shorthand_to_ctx( | ||||
|     ctxdef: Union[None, ssl.SSLContext, dict, PurePath, str] | ||||
|     ctxdef: Union[None, ssl.SSLContext, dict, str] | ||||
| ) -> Optional[ssl.SSLContext]: | ||||
|     """Convert an ssl argument shorthand to an SSLContext object.""" | ||||
|     if ctxdef is None or isinstance(ctxdef, ssl.SSLContext): | ||||
|         return ctxdef | ||||
|     if isinstance(ctxdef, (PurePath, str)): | ||||
|         return load_cert_dir(Path(ctxdef)) | ||||
|     if isinstance(ctxdef, str): | ||||
|         return load_cert_dir(ctxdef) | ||||
|     if isinstance(ctxdef, dict): | ||||
|         return CertSimple(**ctxdef) | ||||
|     raise ValueError( | ||||
|         f"Invalid ssl argument {type(ctxdef)}." | ||||
|         " Expecting one/list of: certdir | dict | SSLContext" | ||||
|         " Expecting a list of certdirs, a dict or an SSLContext." | ||||
|     ) | ||||
|  | ||||
|  | ||||
| def process_to_context( | ||||
|     ssldef: Union[None, ssl.SSLContext, dict, PurePath, str, list, tuple] | ||||
|     ssldef: Union[None, ssl.SSLContext, dict, str, list, tuple] | ||||
| ) -> Optional[ssl.SSLContext]: | ||||
|     """Process app.run ssl argument from easy formats to full SSLContext.""" | ||||
|     return ( | ||||
| @@ -66,11 +65,11 @@ def process_to_context( | ||||
|     ) | ||||
|  | ||||
|  | ||||
| def load_cert_dir(p: Path) -> ssl.SSLContext: | ||||
|     if p.is_file(): | ||||
| def load_cert_dir(p: str) -> ssl.SSLContext: | ||||
|     if os.path.isfile(p): | ||||
|         raise ValueError(f"Certificate folder expected but {p} is a file.") | ||||
|     keyfile = p / "privkey.pem" | ||||
|     certfile = p / "fullchain.pem" | ||||
|     keyfile = os.path.join(p, "privkey.pem") | ||||
|     certfile = os.path.join(p, "fullchain.pem") | ||||
|     if not os.access(keyfile, os.R_OK): | ||||
|         raise ValueError( | ||||
|             f"Certificate not found or permission denied {keyfile}" | ||||
|   | ||||
| @@ -14,7 +14,7 @@ class ExceptionMixin(metaclass=SanicMeta): | ||||
|     def exception( | ||||
|         self, | ||||
|         *exceptions: Union[Type[Exception], List[Type[Exception]]], | ||||
|         apply: bool = True | ||||
|         apply: bool = True, | ||||
|     ) -> Callable: | ||||
|         """Decorator used to register an exception handler for the current application or blueprint instance. | ||||
|  | ||||
|   | ||||
| @@ -25,7 +25,7 @@ class MiddlewareMixin(metaclass=SanicMeta): | ||||
|         attach_to: str = "request", | ||||
|         apply: bool = True, | ||||
|         *, | ||||
|         priority: int = 0 | ||||
|         priority: int = 0, | ||||
|     ) -> MiddlewareType: | ||||
|         ... | ||||
|  | ||||
| @@ -36,7 +36,7 @@ class MiddlewareMixin(metaclass=SanicMeta): | ||||
|         attach_to: str = "request", | ||||
|         apply: bool = True, | ||||
|         *, | ||||
|         priority: int = 0 | ||||
|         priority: int = 0, | ||||
|     ) -> Callable[[MiddlewareType], MiddlewareType]: | ||||
|         ... | ||||
|  | ||||
| @@ -46,7 +46,7 @@ class MiddlewareMixin(metaclass=SanicMeta): | ||||
|         attach_to: str = "request", | ||||
|         apply: bool = True, | ||||
|         *, | ||||
|         priority: int = 0 | ||||
|         priority: int = 0, | ||||
|     ) -> Union[MiddlewareType, Callable[[MiddlewareType], MiddlewareType]]: | ||||
|         """Decorator for registering middleware. | ||||
|  | ||||
|   | ||||
| @@ -44,12 +44,8 @@ class ConnInfo: | ||||
|         self.server_name = "" | ||||
|         self.cert: Dict[str, Any] = {} | ||||
|         self.network_paths: List[Any] = [] | ||||
|         sslobj: Optional[SSLObject] = transport.get_extra_info( | ||||
|             "ssl_object" | ||||
|         )  # type: ignore | ||||
|         sslctx: Optional[SSLContext] = transport.get_extra_info( | ||||
|             "ssl_context" | ||||
|         )  # type: ignore | ||||
|         sslobj: Optional[SSLObject] = transport.get_extra_info("ssl_object")  # type: ignore | ||||
|         sslctx: Optional[SSLContext] = transport.get_extra_info("ssl_context")  # type: ignore | ||||
|         if sslobj: | ||||
|             self.ssl = True | ||||
|             self.server_name = getattr(sslobj, "sanic_server_name", None) or "" | ||||
|   | ||||
| @@ -57,9 +57,7 @@ class WebsocketFrameAssembler: | ||||
|         self.read_mutex = asyncio.Lock() | ||||
|         self.write_mutex = asyncio.Lock() | ||||
|  | ||||
|         self.completed_queue = asyncio.Queue( | ||||
|             maxsize=1 | ||||
|         )  # type: asyncio.Queue[Data] | ||||
|         self.completed_queue = asyncio.Queue(maxsize=1)  # type: asyncio.Queue[Data] | ||||
|  | ||||
|         # put() sets this event to tell get() that a message can be fetched. | ||||
|         self.message_complete = asyncio.Event() | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| from collections.abc import Mapping | ||||
| from typing import Any, Dict, ItemsView, Iterator, KeysView, List | ||||
| from typing import Any, Dict, ItemsView, Iterator, KeysView, List, ValuesView | ||||
| from typing import Mapping as MappingType | ||||
| from typing import ValuesView | ||||
|  | ||||
|  | ||||
| dict | ||||
|   | ||||
| @@ -1,12 +1,14 @@ | ||||
| #!/usr/bin/env python | ||||
|  | ||||
| from os import path | ||||
| import sys | ||||
|  | ||||
| from os import path | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     try: | ||||
|         import towncrier | ||||
|         import click | ||||
|         import towncrier | ||||
|     except ImportError: | ||||
|         print( | ||||
|             "Please make sure you have a installed towncrier and click before using this tool" | ||||
|   | ||||
| @@ -1,18 +1,21 @@ | ||||
| #!/usr/bin/env python | ||||
|  | ||||
| import sys | ||||
|  | ||||
| from argparse import ArgumentParser, Namespace | ||||
| from collections import OrderedDict | ||||
| from configparser import RawConfigParser | ||||
| from datetime import datetime | ||||
| from json import dumps | ||||
| from os import path, chdir | ||||
| from subprocess import Popen, PIPE | ||||
| from os import chdir, path | ||||
| from subprocess import PIPE, Popen | ||||
|  | ||||
| from jinja2 import Environment, BaseLoader | ||||
| from requests import patch | ||||
| import sys | ||||
| import towncrier | ||||
|  | ||||
| from jinja2 import BaseLoader, Environment | ||||
| from requests import patch | ||||
|  | ||||
|  | ||||
| GIT_COMMANDS = { | ||||
|     "get_tag": ["git describe --tags --abbrev=0"], | ||||
|     "commit_version_change": [ | ||||
| @@ -78,7 +81,7 @@ def _run_shell_command(command: list): | ||||
|         output, error = process.communicate() | ||||
|         return_code = process.returncode | ||||
|         return output.decode("utf-8"), error, return_code | ||||
|     except: | ||||
|     except Exception: | ||||
|         return None, None, -1 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| import bottle | ||||
| import ujson | ||||
|  | ||||
| from bottle import route, run | ||||
| from bottle import route | ||||
|  | ||||
|  | ||||
| @route("/") | ||||
|   | ||||
| @@ -3,8 +3,6 @@ import os | ||||
| import sys | ||||
| import timeit | ||||
|  | ||||
| import asyncpg | ||||
|  | ||||
| from sanic.response import json | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ | ||||
| import ujson | ||||
|  | ||||
| from wheezy.http import HTTPResponse, WSGIApplication | ||||
| from wheezy.http.response import json_response | ||||
| from wheezy.routing import url | ||||
| from wheezy.web.handlers import BaseHandler | ||||
| from wheezy.web.middleware import ( | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| import asyncio | ||||
| import logging | ||||
|  | ||||
| from collections import deque, namedtuple | ||||
| @@ -12,7 +11,7 @@ from pytest import MonkeyPatch | ||||
|  | ||||
| from sanic import Sanic | ||||
| from sanic.application.state import Mode | ||||
| from sanic.asgi import ASGIApp, Lifespan, MockTransport | ||||
| from sanic.asgi import Lifespan, MockTransport | ||||
| from sanic.exceptions import BadRequest, Forbidden, ServiceUnavailable | ||||
| from sanic.request import Request | ||||
| from sanic.response import json, text | ||||
|   | ||||
| @@ -22,7 +22,7 @@ def test_bp_group_indexing(app: Sanic): | ||||
|     group = Blueprint.group(blueprint_1, blueprint_2) | ||||
|     assert group[0] == blueprint_1 | ||||
|  | ||||
|     with raises(expected_exception=IndexError) as e: | ||||
|     with raises(expected_exception=IndexError): | ||||
|         _ = group[3] | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,5 @@ | ||||
| import asyncio | ||||
|  | ||||
| from asyncio import CancelledError | ||||
|  | ||||
| import pytest | ||||
|  | ||||
| from sanic import Request, Sanic, json | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,7 @@ from unittest.mock import Mock | ||||
| import pytest | ||||
|  | ||||
| from bs4 import BeautifulSoup | ||||
| from pytest import LogCaptureFixture, MonkeyPatch, WarningsRecorder | ||||
| from pytest import LogCaptureFixture, MonkeyPatch | ||||
|  | ||||
| from sanic import Sanic, handlers | ||||
| from sanic.exceptions import BadRequest, Forbidden, NotFound, ServerError | ||||
| @@ -169,7 +169,7 @@ def test_exception_handler_lookup(exception_handler_app: Sanic): | ||||
|         pass | ||||
|  | ||||
|     try: | ||||
|         ModuleNotFoundError | ||||
|         ModuleNotFoundError  # noqa: F823 | ||||
|     except Exception: | ||||
|  | ||||
|         class ModuleNotFoundError(ImportError): | ||||
|   | ||||
| @@ -1,14 +1,12 @@ | ||||
| import sys | ||||
|  | ||||
| from unittest.mock import MagicMock | ||||
|  | ||||
| import pytest | ||||
|  | ||||
| from sanic import Sanic | ||||
|  | ||||
|  | ||||
| try: | ||||
|     import sanic_ext | ||||
|     import sanic_ext  # noqa: F401 | ||||
|  | ||||
|     SANIC_EXT_IN_ENV = True | ||||
| except ImportError: | ||||
|   | ||||
| @@ -57,7 +57,7 @@ def raised_ceiling(): | ||||
|             # Chrome, Firefox: | ||||
|             # Content-Disposition: form-data; name="foo%22;bar\"; filename="😀" | ||||
|             'form-data; name="foo%22;bar\\"; filename="😀"', | ||||
|             ("form-data", {"name": 'foo";bar\\', "filename": "😀"}) | ||||
|             ("form-data", {"name": 'foo";bar\\', "filename": "😀"}), | ||||
|             # cgi: ('form-data', {'name': 'foo%22;bar"; filename="😀'}) | ||||
|             # werkzeug (pre 2.3.0): ('form-data', {'name': 'foo%22;bar"; filename='}) | ||||
|         ), | ||||
|   | ||||
| @@ -14,7 +14,6 @@ from sanic_testing.testing import HOST, PORT | ||||
| from sanic import Blueprint, text | ||||
| from sanic.compat import use_context | ||||
| from sanic.log import logger | ||||
| from sanic.server.socket import configure_socket | ||||
|  | ||||
|  | ||||
| @pytest.mark.skipif( | ||||
|   | ||||
| @@ -573,7 +573,7 @@ def test_streaming_echo(): | ||||
|  | ||||
|     async def client(app, reader, writer): | ||||
|         # Unfortunately httpx does not support 2-way streaming, so do it by hand. | ||||
|         host = f"host: localhost:8000\r\n".encode() | ||||
|         host = "host: localhost:8000\r\n".encode() | ||||
|         writer.write( | ||||
|             b"POST /echo HTTP/1.1\r\n" + host + b"content-length: 2\r\n" | ||||
|             b"content-type: text/plain; charset=utf-8\r\n" | ||||
| @@ -581,7 +581,7 @@ def test_streaming_echo(): | ||||
|         ) | ||||
|         # Read response | ||||
|         res = b"" | ||||
|         while not b"\r\n\r\n" in res: | ||||
|         while b"\r\n\r\n" not in res: | ||||
|             res += await reader.read(4096) | ||||
|         assert res.startswith(b"HTTP/1.1 200 OK\r\n") | ||||
|         assert res.endswith(b"\r\n\r\n") | ||||
| @@ -589,7 +589,7 @@ def test_streaming_echo(): | ||||
|  | ||||
|         async def read_chunk(): | ||||
|             nonlocal buffer | ||||
|             while not b"\r\n" in buffer: | ||||
|             while b"\r\n" not in buffer: | ||||
|                 data = await reader.read(4096) | ||||
|                 assert data | ||||
|                 buffer += data | ||||
| @@ -618,6 +618,6 @@ def test_streaming_echo(): | ||||
|         assert res == b"-" | ||||
|  | ||||
|         res = await read_chunk() | ||||
|         assert res == None | ||||
|         assert res is None | ||||
|  | ||||
|     app.run(access_log=False, single_process=True) | ||||
|   | ||||
| @@ -2011,11 +2011,11 @@ def test_server_name_and_url_for(app): | ||||
|     app.config.SERVER_NAME = "my-server"  # This means default port | ||||
|     assert app.url_for("handler", _external=True) == "http://my-server/foo" | ||||
|     request, response = app.test_client.get("/foo") | ||||
|     assert request.url_for("handler") == f"http://my-server/foo" | ||||
|     assert request.url_for("handler") == "http://my-server/foo" | ||||
|  | ||||
|     app.config.SERVER_NAME = "https://my-server/path" | ||||
|     request, response = app.test_client.get("/foo") | ||||
|     url = f"https://my-server/path/foo" | ||||
|     url = "https://my-server/path/foo" | ||||
|     assert app.url_for("handler", _external=True) == url | ||||
|     assert request.url_for("handler") == url | ||||
|  | ||||
| @@ -2180,7 +2180,7 @@ def test_safe_method_with_body_ignored(app): | ||||
|     ) | ||||
|  | ||||
|     assert request.body == b"" | ||||
|     assert request.json == None | ||||
|     assert request.json is None | ||||
|     assert response.body == b"OK" | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -610,7 +610,7 @@ def test_multiple_responses( | ||||
|  | ||||
|     @app.get("/4") | ||||
|     async def handler4(request: Request): | ||||
|         response = await request.respond(headers={"one": "one"}) | ||||
|         await request.respond(headers={"one": "one"}) | ||||
|         return json({"foo": "bar"}, headers={"one": "two"}) | ||||
|  | ||||
|     @app.get("/5") | ||||
| @@ -641,10 +641,6 @@ def test_multiple_responses( | ||||
|         "been responded to." | ||||
|     ) | ||||
|  | ||||
|     error_msg3 = ( | ||||
|         "Response stream was ended, no more " | ||||
|         "response data is allowed to be sent." | ||||
|     ) | ||||
|  | ||||
|     with caplog.at_level(ERROR): | ||||
|         _, response = app.test_client.get("/1") | ||||
| @@ -769,7 +765,7 @@ def test_file_response_headers( | ||||
|     assert ( | ||||
|         "cache-control" in headers | ||||
|         and f"max-age={test_max_age}" in headers.get("cache-control") | ||||
|         and f"public" in headers.get("cache-control") | ||||
|         and "public" in headers.get("cache-control") | ||||
|     ) | ||||
|     assert ( | ||||
|         "expires" in headers | ||||
| @@ -800,14 +796,14 @@ def test_file_response_headers( | ||||
|  | ||||
|     _, response = app.test_client.get(f"/files/no_cache/{file_name}") | ||||
|     headers = response.headers | ||||
|     assert "cache-control" in headers and f"no-cache" == headers.get( | ||||
|     assert "cache-control" in headers and "no-cache" == headers.get( | ||||
|         "cache-control" | ||||
|     ) | ||||
|     assert response.status == 200 | ||||
|  | ||||
|     _, response = app.test_client.get(f"/files/no_store/{file_name}") | ||||
|     headers = response.headers | ||||
|     assert "cache-control" in headers and f"no-store" == headers.get( | ||||
|     assert "cache-control" in headers and "no-store" == headers.get( | ||||
|         "cache-control" | ||||
|     ) | ||||
|     assert response.status == 200 | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| # flake8: noqa: E501 | ||||
|  | ||||
| import subprocess | ||||
| import sys | ||||
|  | ||||
| from pathlib import Path | ||||
| from typing import List, Tuple | ||||
|   | ||||
		Reference in New Issue
	
	Block a user