Merge branch 'master' into py39
This commit is contained in:
		| @@ -1,3 +1,28 @@ | |||||||
|  | Version 20.9.1 | ||||||
|  | =============== | ||||||
|  |  | ||||||
|  | Bugfixes | ||||||
|  | ******** | ||||||
|  |    | ||||||
|  |   * | ||||||
|  |     `#1954 <https://github.com/huge-success/sanic/pull/1954>`_ | ||||||
|  |     Fix static route registration on blueprints | ||||||
|  |   * | ||||||
|  |     `#1957 <https://github.com/huge-success/sanic/pull/1957>`_ | ||||||
|  |     Removes duplicate headers in ASGI streaming body | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Version 19.12.3 | ||||||
|  | =============== | ||||||
|  |  | ||||||
|  | Bugfixes | ||||||
|  | ******** | ||||||
|  |    | ||||||
|  |   * | ||||||
|  |     `#1959 <https://github.com/huge-success/sanic/pull/1959>`_ | ||||||
|  |     Removes duplicate headers in ASGI streaming body | ||||||
|  |  | ||||||
|  |  | ||||||
| Version 20.9.0 | Version 20.9.0 | ||||||
| =============== | =============== | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,8 +26,8 @@ Sanic | Build fast. Run fast. | |||||||
|    :target: https://gitter.im/sanic-python/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge |    :target: https://gitter.im/sanic-python/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge | ||||||
| .. |Codecov| image:: https://codecov.io/gh/huge-success/sanic/branch/master/graph/badge.svg | .. |Codecov| image:: https://codecov.io/gh/huge-success/sanic/branch/master/graph/badge.svg | ||||||
|     :target: https://codecov.io/gh/huge-success/sanic |     :target: https://codecov.io/gh/huge-success/sanic | ||||||
| .. |Build Status| image:: https://travis-ci.org/huge-success/sanic.svg?branch=master | .. |Build Status| image:: https://travis-ci.com/huge-success/sanic.svg?branch=master | ||||||
|    :target: https://travis-ci.org/huge-success/sanic |    :target: https://travis-ci.com/huge-success/sanic | ||||||
| .. |AppVeyor Build Status| image:: https://ci.appveyor.com/api/projects/status/d8pt3ids0ynexi8c/branch/master?svg=true | .. |AppVeyor Build Status| image:: https://ci.appveyor.com/api/projects/status/d8pt3ids0ynexi8c/branch/master?svg=true | ||||||
|    :target: https://ci.appveyor.com/project/huge-success/sanic |    :target: https://ci.appveyor.com/project/huge-success/sanic | ||||||
| .. |Documentation| image:: https://readthedocs.org/projects/sanic/badge/?version=latest | .. |Documentation| image:: https://readthedocs.org/projects/sanic/badge/?version=latest | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								changelogs/1970.misc.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								changelogs/1970.misc.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | Adds py.typed file to expose type information to other packages. | ||||||
| @@ -88,5 +88,5 @@ When `stream_large_files` is `True`, Sanic will use `file_stream()` instead of ` | |||||||
|  |  | ||||||
|     app = Sanic(__name__) |     app = Sanic(__name__) | ||||||
|  |  | ||||||
|     chunk_size = 1024 * 1024 * 8 # Set chunk size to 8KB |     chunk_size = 1024 * 1024 * 8 # Set chunk size to 8MiB | ||||||
|     app.static('/large_video.mp4', '/home/ubuntu/large_video.mp4', stream_large_files=chunk_size) |     app.static('/large_video.mp4', '/home/ubuntu/large_video.mp4', stream_large_files=chunk_size) | ||||||
|   | |||||||
| @@ -1,28 +1,83 @@ | |||||||
| import os | import os | ||||||
| import sys | import sys | ||||||
|  |  | ||||||
| from argparse import ArgumentParser | from argparse import ArgumentParser, RawDescriptionHelpFormatter | ||||||
| from importlib import import_module | from importlib import import_module | ||||||
| from typing import Any, Dict, Optional | from typing import Any, Dict, Optional | ||||||
|  |  | ||||||
|  | from sanic import __version__ | ||||||
| from sanic.app import Sanic | from sanic.app import Sanic | ||||||
|  | from sanic.config import BASE_LOGO | ||||||
| from sanic.log import logger | from sanic.log import logger | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class SanicArgumentParser(ArgumentParser): | ||||||
|  |     def add_bool_arguments(self, *args, **kwargs): | ||||||
|  |         group = self.add_mutually_exclusive_group() | ||||||
|  |         group.add_argument(*args, action="store_true", **kwargs) | ||||||
|  |         kwargs["help"] = "no " + kwargs["help"] | ||||||
|  |         group.add_argument( | ||||||
|  |             "--no-" + args[0][2:], *args[1:], action="store_false", **kwargs | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |  | ||||||
| def main(): | def main(): | ||||||
|     parser = ArgumentParser(prog="sanic") |     parser = SanicArgumentParser( | ||||||
|     parser.add_argument("--host", dest="host", type=str, default="127.0.0.1") |         prog="sanic", | ||||||
|     parser.add_argument("--port", dest="port", type=int, default=8000) |         description=BASE_LOGO, | ||||||
|     parser.add_argument("--unix", dest="unix", type=str, default="") |         formatter_class=RawDescriptionHelpFormatter, | ||||||
|  |     ) | ||||||
|  |     parser.add_argument( | ||||||
|  |         "-H", | ||||||
|  |         "--host", | ||||||
|  |         dest="host", | ||||||
|  |         type=str, | ||||||
|  |         default="127.0.0.1", | ||||||
|  |         help="host address [default 127.0.0.1]", | ||||||
|  |     ) | ||||||
|  |     parser.add_argument( | ||||||
|  |         "-p", | ||||||
|  |         "--port", | ||||||
|  |         dest="port", | ||||||
|  |         type=int, | ||||||
|  |         default=8000, | ||||||
|  |         help="port to serve on [default 8000]", | ||||||
|  |     ) | ||||||
|  |     parser.add_argument( | ||||||
|  |         "-u", | ||||||
|  |         "--unix", | ||||||
|  |         dest="unix", | ||||||
|  |         type=str, | ||||||
|  |         default="", | ||||||
|  |         help="location of unix socket", | ||||||
|  |     ) | ||||||
|     parser.add_argument( |     parser.add_argument( | ||||||
|         "--cert", dest="cert", type=str, help="location of certificate for SSL" |         "--cert", dest="cert", type=str, help="location of certificate for SSL" | ||||||
|     ) |     ) | ||||||
|     parser.add_argument( |     parser.add_argument( | ||||||
|         "--key", dest="key", type=str, help="location of keyfile for SSL." |         "--key", dest="key", type=str, help="location of keyfile for SSL." | ||||||
|     ) |     ) | ||||||
|     parser.add_argument("--workers", dest="workers", type=int, default=1) |     parser.add_argument( | ||||||
|  |         "-w", | ||||||
|  |         "--workers", | ||||||
|  |         dest="workers", | ||||||
|  |         type=int, | ||||||
|  |         default=1, | ||||||
|  |         help="number of worker processes [default 1]", | ||||||
|  |     ) | ||||||
|     parser.add_argument("--debug", dest="debug", action="store_true") |     parser.add_argument("--debug", dest="debug", action="store_true") | ||||||
|     parser.add_argument("module") |     parser.add_bool_arguments( | ||||||
|  |         "--access-logs", dest="access_log", help="display access logs" | ||||||
|  |     ) | ||||||
|  |     parser.add_argument( | ||||||
|  |         "-v", | ||||||
|  |         "--version", | ||||||
|  |         action="version", | ||||||
|  |         version=f"Sanic {__version__}", | ||||||
|  |     ) | ||||||
|  |     parser.add_argument( | ||||||
|  |         "module", help="path to your Sanic app. Example: path.to.server:app" | ||||||
|  |     ) | ||||||
|     args = parser.parse_args() |     args = parser.parse_args() | ||||||
|  |  | ||||||
|     try: |     try: | ||||||
| @@ -30,9 +85,12 @@ def main(): | |||||||
|         if module_path not in sys.path: |         if module_path not in sys.path: | ||||||
|             sys.path.append(module_path) |             sys.path.append(module_path) | ||||||
|  |  | ||||||
|         module_parts = args.module.split(".") |         if ":" in args.module: | ||||||
|         module_name = ".".join(module_parts[:-1]) |             module_name, app_name = args.module.rsplit(":", 1) | ||||||
|         app_name = module_parts[-1] |         else: | ||||||
|  |             module_parts = args.module.split(".") | ||||||
|  |             module_name = ".".join(module_parts[:-1]) | ||||||
|  |             app_name = module_parts[-1] | ||||||
|  |  | ||||||
|         module = import_module(module_name) |         module = import_module(module_name) | ||||||
|         app = getattr(module, app_name, None) |         app = getattr(module, app_name, None) | ||||||
| @@ -57,6 +115,7 @@ def main(): | |||||||
|             unix=args.unix, |             unix=args.unix, | ||||||
|             workers=args.workers, |             workers=args.workers, | ||||||
|             debug=args.debug, |             debug=args.debug, | ||||||
|  |             access_log=args.access_log, | ||||||
|             ssl=ssl, |             ssl=ssl, | ||||||
|         ) |         ) | ||||||
|     except ImportError as e: |     except ImportError as e: | ||||||
|   | |||||||
							
								
								
									
										20
									
								
								sanic/app.py
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								sanic/app.py
									
									
									
									
									
								
							| @@ -68,7 +68,7 @@ class Sanic: | |||||||
|  |  | ||||||
|         self.name = name |         self.name = name | ||||||
|         self.asgi = False |         self.asgi = False | ||||||
|         self.router = router or Router() |         self.router = router or Router(self) | ||||||
|         self.request_class = request_class |         self.request_class = request_class | ||||||
|         self.error_handler = error_handler or ErrorHandler() |         self.error_handler = error_handler or ErrorHandler() | ||||||
|         self.config = Config(load_env=load_env) |         self.config = Config(load_env=load_env) | ||||||
| @@ -900,7 +900,9 @@ class Sanic: | |||||||
|         name = None |         name = None | ||||||
|         try: |         try: | ||||||
|             # Fetch handler from router |             # Fetch handler from router | ||||||
|             handler, args, kwargs, uri, name = self.router.get(request) |             handler, args, kwargs, uri, name, endpoint = self.router.get( | ||||||
|  |                 request | ||||||
|  |             ) | ||||||
|  |  | ||||||
|             # -------------------------------------------- # |             # -------------------------------------------- # | ||||||
|             # Request Middleware |             # Request Middleware | ||||||
| @@ -922,16 +924,8 @@ class Sanic: | |||||||
|                             "handler from the router" |                             "handler from the router" | ||||||
|                         ) |                         ) | ||||||
|                     ) |                     ) | ||||||
|                 else: |  | ||||||
|                     if not getattr(handler, "__blueprintname__", False): |                 request.endpoint = endpoint | ||||||
|                         request.endpoint = self._build_endpoint_name( |  | ||||||
|                             handler.__name__ |  | ||||||
|                         ) |  | ||||||
|                     else: |  | ||||||
|                         request.endpoint = self._build_endpoint_name( |  | ||||||
|                             getattr(handler, "__blueprintname__", ""), |  | ||||||
|                             handler.__name__, |  | ||||||
|                         ) |  | ||||||
|  |  | ||||||
|                 # Run response handler |                 # Run response handler | ||||||
|                 response = handler(request, *args, **kwargs) |                 response = handler(request, *args, **kwargs) | ||||||
| @@ -1454,6 +1448,8 @@ class Sanic: | |||||||
|         asgi_app = await ASGIApp.create(self, scope, receive, send) |         asgi_app = await ASGIApp.create(self, scope, receive, send) | ||||||
|         await asgi_app() |         await asgi_app() | ||||||
|  |  | ||||||
|  |     _asgi_single_callable = True  # We conform to ASGI 3.0 single-callable | ||||||
|  |  | ||||||
|     # -------------------------------------------------------------------- # |     # -------------------------------------------------------------------- # | ||||||
|     # Configuration |     # Configuration | ||||||
|     # -------------------------------------------------------------------- # |     # -------------------------------------------------------------------- # | ||||||
|   | |||||||
| @@ -312,13 +312,19 @@ class ASGIApp: | |||||||
|         callback = None if self.ws else self.stream_callback |         callback = None if self.ws else self.stream_callback | ||||||
|         await handler(self.request, None, callback) |         await handler(self.request, None, callback) | ||||||
|  |  | ||||||
|     async def stream_callback(self, response: HTTPResponse) -> None: |     _asgi_single_callable = True  # We conform to ASGI 3.0 single-callable | ||||||
|  |  | ||||||
|  |     async def stream_callback( | ||||||
|  |         self, response: Union[HTTPResponse, StreamingHTTPResponse] | ||||||
|  |     ) -> None: | ||||||
|         """ |         """ | ||||||
|         Write the response. |         Write the response. | ||||||
|         """ |         """ | ||||||
|         headers: List[Tuple[bytes, bytes]] = [] |         headers: List[Tuple[bytes, bytes]] = [] | ||||||
|         cookies: Dict[str, str] = {} |         cookies: Dict[str, str] = {} | ||||||
|  |         content_length: List[str] = [] | ||||||
|         try: |         try: | ||||||
|  |             content_length = response.headers.popall("content-length", []) | ||||||
|             cookies = { |             cookies = { | ||||||
|                 v.key: v |                 v.key: v | ||||||
|                 for _, v in list( |                 for _, v in list( | ||||||
| @@ -351,12 +357,22 @@ class ASGIApp: | |||||||
|             ] |             ] | ||||||
|  |  | ||||||
|         response.asgi = True |         response.asgi = True | ||||||
|  |         is_streaming = isinstance(response, StreamingHTTPResponse) | ||||||
|         if "content-length" not in response.headers and not isinstance( |         if is_streaming and getattr(response, "chunked", False): | ||||||
|             response, StreamingHTTPResponse |             # disable sanic chunking, this is done at the ASGI-server level | ||||||
|         ): |             setattr(response, "chunked", False) | ||||||
|  |             # content-length header is removed to signal to the ASGI-server | ||||||
|  |             # to use automatic-chunking if it supports it | ||||||
|  |         elif len(content_length) > 0: | ||||||
|             headers += [ |             headers += [ | ||||||
|                 (b"content-length", str(len(response.body)).encode("latin-1")) |                 (b"content-length", str(content_length[0]).encode("latin-1")) | ||||||
|  |             ] | ||||||
|  |         elif not is_streaming: | ||||||
|  |             headers += [ | ||||||
|  |                 ( | ||||||
|  |                     b"content-length", | ||||||
|  |                     str(len(getattr(response, "body", b""))).encode("latin-1"), | ||||||
|  |                 ) | ||||||
|             ] |             ] | ||||||
|  |  | ||||||
|         if "content-type" not in response.headers: |         if "content-type" not in response.headers: | ||||||
|   | |||||||
| @@ -179,8 +179,8 @@ def abort(status_code, message=None): | |||||||
|     message appropriate for the given status code, unless provided. |     message appropriate for the given status code, unless provided. | ||||||
|  |  | ||||||
|     :param status_code: The HTTP status code to return. |     :param status_code: The HTTP status code to return. | ||||||
|     :param message: The HTTP response body. Defaults to the messages |     :param message: The HTTP response body. Defaults to the messages in | ||||||
|                     in response.py for the given status code. |     STATUS_CODES from sanic.helpers for the given status code. | ||||||
|     """ |     """ | ||||||
|     if message is None: |     if message is None: | ||||||
|         message = STATUS_CODES.get(status_code) |         message = STATUS_CODES.get(status_code) | ||||||
|   | |||||||
							
								
								
									
										0
									
								
								sanic/py.typed
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								sanic/py.typed
									
									
									
									
									
										Normal file
									
								
							| @@ -100,6 +100,8 @@ class StreamingHTTPResponse(BaseHTTPResponse): | |||||||
|         """ |         """ | ||||||
|         data = self._encode_body(data) |         data = self._encode_body(data) | ||||||
|  |  | ||||||
|  |         # `chunked` will always be False in ASGI-mode, even if the underlying | ||||||
|  |         # ASGI Transport implements Chunked transport. That does it itself. | ||||||
|         if self.chunked: |         if self.chunked: | ||||||
|             await self.protocol.push_data(b"%x\r\n%b\r\n" % (len(data), data)) |             await self.protocol.push_data(b"%x\r\n%b\r\n" % (len(data), data)) | ||||||
|         else: |         else: | ||||||
|   | |||||||
| @@ -11,7 +11,16 @@ from sanic.views import CompositionView | |||||||
|  |  | ||||||
|  |  | ||||||
| Route = namedtuple( | Route = namedtuple( | ||||||
|     "Route", ["handler", "methods", "pattern", "parameters", "name", "uri"] |     "Route", | ||||||
|  |     [ | ||||||
|  |         "handler", | ||||||
|  |         "methods", | ||||||
|  |         "pattern", | ||||||
|  |         "parameters", | ||||||
|  |         "name", | ||||||
|  |         "uri", | ||||||
|  |         "endpoint", | ||||||
|  |     ], | ||||||
| ) | ) | ||||||
| Parameter = namedtuple("Parameter", ["name", "cast"]) | Parameter = namedtuple("Parameter", ["name", "cast"]) | ||||||
|  |  | ||||||
| @@ -79,7 +88,8 @@ class Router: | |||||||
|     routes_always_check = None |     routes_always_check = None | ||||||
|     parameter_pattern = re.compile(r"<(.+?)>") |     parameter_pattern = re.compile(r"<(.+?)>") | ||||||
|  |  | ||||||
|     def __init__(self): |     def __init__(self, app): | ||||||
|  |         self.app = app | ||||||
|         self.routes_all = {} |         self.routes_all = {} | ||||||
|         self.routes_names = {} |         self.routes_names = {} | ||||||
|         self.routes_static_files = {} |         self.routes_static_files = {} | ||||||
| @@ -299,11 +309,15 @@ class Router: | |||||||
|  |  | ||||||
|             handler_name = f"{bp_name}.{name or handler.__name__}" |             handler_name = f"{bp_name}.{name or handler.__name__}" | ||||||
|         else: |         else: | ||||||
|             handler_name = name or getattr(handler, "__name__", None) |             handler_name = name or getattr( | ||||||
|  |                 handler, "__name__", handler.__class__.__name__ | ||||||
|  |             ) | ||||||
|  |  | ||||||
|         if route: |         if route: | ||||||
|             route = merge_route(route, methods, handler) |             route = merge_route(route, methods, handler) | ||||||
|         else: |         else: | ||||||
|  |             endpoint = self.app._build_endpoint_name(handler_name) | ||||||
|  |  | ||||||
|             route = Route( |             route = Route( | ||||||
|                 handler=handler, |                 handler=handler, | ||||||
|                 methods=methods, |                 methods=methods, | ||||||
| @@ -311,6 +325,7 @@ class Router: | |||||||
|                 parameters=parameters, |                 parameters=parameters, | ||||||
|                 name=handler_name, |                 name=handler_name, | ||||||
|                 uri=uri, |                 uri=uri, | ||||||
|  |                 endpoint=endpoint, | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|         self.routes_all[uri] = route |         self.routes_all[uri] = route | ||||||
| @@ -449,7 +464,8 @@ class Router: | |||||||
|         route_handler = route.handler |         route_handler = route.handler | ||||||
|         if hasattr(route_handler, "handlers"): |         if hasattr(route_handler, "handlers"): | ||||||
|             route_handler = route_handler.handlers[method] |             route_handler = route_handler.handlers[method] | ||||||
|         return route_handler, [], kwargs, route.uri, route.name |  | ||||||
|  |         return route_handler, [], kwargs, route.uri, route.name, route.endpoint | ||||||
|  |  | ||||||
|     def is_stream_handler(self, request): |     def is_stream_handler(self, request): | ||||||
|         """Handler for request is stream or not. |         """Handler for request is stream or not. | ||||||
|   | |||||||
| @@ -90,6 +90,7 @@ class CompositionView: | |||||||
|  |  | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|         self.handlers = {} |         self.handlers = {} | ||||||
|  |         self.name = self.__class__.__name__ | ||||||
|  |  | ||||||
|     def add(self, methods, handler, stream=False): |     def add(self, methods, handler, stream=False): | ||||||
|         if stream: |         if stream: | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								setup.py
									
									
									
									
									
								
							| @@ -57,6 +57,7 @@ setup_kwargs = { | |||||||
|     ), |     ), | ||||||
|     "long_description": long_description, |     "long_description": long_description, | ||||||
|     "packages": ["sanic"], |     "packages": ["sanic"], | ||||||
|  |     "package_data": {"sanic": ["py.typed"]}, | ||||||
|     "platforms": "any", |     "platforms": "any", | ||||||
|     "python_requires": ">=3.6", |     "python_requires": ">=3.6", | ||||||
|     "classifiers": [ |     "classifiers": [ | ||||||
| @@ -79,15 +80,15 @@ requirements = [ | |||||||
|     "httptools>=0.0.10", |     "httptools>=0.0.10", | ||||||
|     uvloop, |     uvloop, | ||||||
|     ujson, |     ujson, | ||||||
|     "aiofiles>=0.3.0", |     "aiofiles>=0.6.0", | ||||||
|     "websockets>=8.1,<9.0", |     "websockets>=8.1,<9.0", | ||||||
|     "multidict==5.0.0", |     "multidict>=5.0,<6.0", | ||||||
|     "httpx==0.15.4", |     "httpx==0.15.4", | ||||||
| ] | ] | ||||||
|  |  | ||||||
| tests_require = [ | tests_require = [ | ||||||
|     "pytest==5.2.1", |     "pytest==5.2.1", | ||||||
|     "multidict==5.0.0", |     "multidict>=5.0,<6.0", | ||||||
|     "gunicorn", |     "gunicorn", | ||||||
|     "pytest-cov", |     "pytest-cov", | ||||||
|     "httpcore==0.3.0", |     "httpcore==0.3.0", | ||||||
| @@ -97,6 +98,7 @@ tests_require = [ | |||||||
|     "pytest-sanic", |     "pytest-sanic", | ||||||
|     "pytest-sugar", |     "pytest-sugar", | ||||||
|     "pytest-benchmark", |     "pytest-benchmark", | ||||||
|  |     "pytest-dependency", | ||||||
| ] | ] | ||||||
|  |  | ||||||
| docs_require = [ | docs_require = [ | ||||||
|   | |||||||
| @@ -95,10 +95,10 @@ class RouteStringGenerator: | |||||||
|  |  | ||||||
|  |  | ||||||
| @pytest.fixture(scope="function") | @pytest.fixture(scope="function") | ||||||
| def sanic_router(): | def sanic_router(app): | ||||||
|     # noinspection PyProtectedMember |     # noinspection PyProtectedMember | ||||||
|     def _setup(route_details: tuple) -> (Router, tuple): |     def _setup(route_details: tuple) -> (Router, tuple): | ||||||
|         router = Router() |         router = Router(app) | ||||||
|         added_router = [] |         added_router = [] | ||||||
|         for method, route in route_details: |         for method, route in route_details: | ||||||
|             try: |             try: | ||||||
|   | |||||||
| @@ -117,7 +117,7 @@ def test_app_route_raise_value_error(app): | |||||||
|  |  | ||||||
| def test_app_handle_request_handler_is_none(app, monkeypatch): | def test_app_handle_request_handler_is_none(app, monkeypatch): | ||||||
|     def mockreturn(*args, **kwargs): |     def mockreturn(*args, **kwargs): | ||||||
|         return None, [], {}, "", "" |         return None, [], {}, "", "", None | ||||||
|  |  | ||||||
|     # Not sure how to make app.router.get() return None, so use mock here. |     # Not sure how to make app.router.get() return None, so use mock here. | ||||||
|     monkeypatch.setattr(app.router, "get", mockreturn) |     monkeypatch.setattr(app.router, "get", mockreturn) | ||||||
|   | |||||||
| @@ -735,6 +735,7 @@ def test_static_blueprint_name(app: Sanic, static_file_directory, file_name): | |||||||
|     _, response = app.test_client.get("/static/test.file/") |     _, response = app.test_client.get("/static/test.file/") | ||||||
|     assert response.status == 200 |     assert response.status == 200 | ||||||
|  |  | ||||||
|  |  | ||||||
| @pytest.mark.parametrize("file_name", ["test.file"]) | @pytest.mark.parametrize("file_name", ["test.file"]) | ||||||
| def test_static_blueprintp_mw(app: Sanic, static_file_directory, file_name): | def test_static_blueprintp_mw(app: Sanic, static_file_directory, file_name): | ||||||
|     current_file = inspect.getfile(inspect.currentframe()) |     current_file = inspect.getfile(inspect.currentframe()) | ||||||
| @@ -745,7 +746,7 @@ def test_static_blueprintp_mw(app: Sanic, static_file_directory, file_name): | |||||||
|  |  | ||||||
|     bp = Blueprint(name="test_mw", url_prefix="") |     bp = Blueprint(name="test_mw", url_prefix="") | ||||||
|  |  | ||||||
|     @bp.middleware('request') |     @bp.middleware("request") | ||||||
|     def bp_mw1(request): |     def bp_mw1(request): | ||||||
|         nonlocal triggered |         nonlocal triggered | ||||||
|         triggered = True |         triggered = True | ||||||
| @@ -754,7 +755,7 @@ def test_static_blueprintp_mw(app: Sanic, static_file_directory, file_name): | |||||||
|         "/test.file", |         "/test.file", | ||||||
|         get_file_path(static_file_directory, file_name), |         get_file_path(static_file_directory, file_name), | ||||||
|         strict_slashes=True, |         strict_slashes=True, | ||||||
|         name="static" |         name="static", | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     app.blueprint(bp) |     app.blueprint(bp) | ||||||
|   | |||||||
| @@ -20,7 +20,9 @@ def test_load_module_from_file_location(loaded_module_from_file_location): | |||||||
|  |  | ||||||
|  |  | ||||||
| @pytest.mark.dependency(depends=["test_load_module_from_file_location"]) | @pytest.mark.dependency(depends=["test_load_module_from_file_location"]) | ||||||
| def test_loaded_module_from_file_location_name(loaded_module_from_file_location,): | def test_loaded_module_from_file_location_name( | ||||||
|  |     loaded_module_from_file_location, | ||||||
|  | ): | ||||||
|     name = loaded_module_from_file_location.__name__ |     name = loaded_module_from_file_location.__name__ | ||||||
|     if "C:\\" in name: |     if "C:\\" in name: | ||||||
|         name = name.split("\\")[-1] |         name = name.split("\\")[-1] | ||||||
|   | |||||||
| @@ -238,7 +238,7 @@ def test_chunked_streaming_returns_correct_content(streaming_app): | |||||||
| @pytest.mark.asyncio | @pytest.mark.asyncio | ||||||
| async def test_chunked_streaming_returns_correct_content_asgi(streaming_app): | async def test_chunked_streaming_returns_correct_content_asgi(streaming_app): | ||||||
|     request, response = await streaming_app.asgi_client.get("/") |     request, response = await streaming_app.asgi_client.get("/") | ||||||
|     assert response.text == "4\r\nfoo,\r\n3\r\nbar\r\n0\r\n\r\n" |     assert response.text == "foo,bar" | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_non_chunked_streaming_adds_correct_headers(non_chunked_streaming_app): | def test_non_chunked_streaming_adds_correct_headers(non_chunked_streaming_app): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Adam Hopkins
					Adam Hopkins