Skip to content

Commit

Permalink
Merge branch 'main' into request-method-properties
Browse files Browse the repository at this point in the history
  • Loading branch information
ahopkins authored Aug 10, 2022
2 parents 8dfc805 + 8e9342e commit e36a51e
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 29 deletions.
2 changes: 1 addition & 1 deletion CONDUCT.md → CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at [email protected]. All
reported by contacting the project team at [email protected]. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Expand Down
14 changes: 13 additions & 1 deletion sanic/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1184,7 +1184,7 @@ def add_task(
*,
name: Optional[str] = None,
register: bool = True,
) -> Optional[Task]:
) -> Optional[Task[Any]]:
"""
Schedule a task to run later, after the loop has started.
Different from asyncio.ensure_future in that it does not
Expand Down Expand Up @@ -1521,6 +1521,18 @@ async def _startup(self):
self.signalize(self.config.TOUCHUP)
self.finalize()

route_names = [route.name for route in self.router.routes]
duplicates = {
name for name in route_names if route_names.count(name) > 1
}
if duplicates:
names = ", ".join(duplicates)
deprecation(
f"Duplicate route names detected: {names}. In the future, "
"Sanic will enforce uniqueness in route naming.",
23.3,
)

# TODO: Replace in v22.6 to check against apps in app registry
if (
self.__class__._uvloop_setting is not None
Expand Down
8 changes: 4 additions & 4 deletions sanic/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,19 @@ def __init__(
self._check_error_format()
self._init = True

def __getattr__(self, attr):
def __getattr__(self, attr: Any):
try:
return self[attr]
except KeyError as ke:
raise AttributeError(f"Config has no '{ke.args[0]}'")

def __setattr__(self, attr, value) -> None:
def __setattr__(self, attr: str, value: Any) -> None:
self.update({attr: value})

def __setitem__(self, attr, value) -> None:
def __setitem__(self, attr: str, value: Any) -> None:
self.update({attr: value})

def update(self, *other, **kwargs) -> None:
def update(self, *other: Any, **kwargs: Any) -> None:
kwargs.update({k: v for item in other for k, v in dict(item).items()})
setters: Dict[str, Any] = {
k: kwargs.pop(k)
Expand Down
42 changes: 21 additions & 21 deletions sanic/mixins/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ def add_route(
stream: bool = False,
version_prefix: str = "/v",
error_format: Optional[str] = None,
**ctx_kwargs,
**ctx_kwargs: Any,
) -> RouteHandler:
"""A helper method to register class instance or
functions as a handler to the application url
Expand Down Expand Up @@ -286,7 +286,7 @@ def get(
ignore_body: bool = True,
version_prefix: str = "/v",
error_format: Optional[str] = None,
**ctx_kwargs,
**ctx_kwargs: Any,
) -> RouteHandler:
"""
Add an API URL under the **GET** *HTTP* method
Expand Down Expand Up @@ -329,7 +329,7 @@ def post(
name: Optional[str] = None,
version_prefix: str = "/v",
error_format: Optional[str] = None,
**ctx_kwargs,
**ctx_kwargs: Any,
) -> RouteHandler:
"""
Add an API URL under the **POST** *HTTP* method
Expand Down Expand Up @@ -372,7 +372,7 @@ def put(
name: Optional[str] = None,
version_prefix: str = "/v",
error_format: Optional[str] = None,
**ctx_kwargs,
**ctx_kwargs: Any,
) -> RouteHandler:
"""
Add an API URL under the **PUT** *HTTP* method
Expand Down Expand Up @@ -415,7 +415,7 @@ def head(
ignore_body: bool = True,
version_prefix: str = "/v",
error_format: Optional[str] = None,
**ctx_kwargs,
**ctx_kwargs: Any,
) -> RouteHandler:
"""
Add an API URL under the **HEAD** *HTTP* method
Expand Down Expand Up @@ -466,7 +466,7 @@ def options(
ignore_body: bool = True,
version_prefix: str = "/v",
error_format: Optional[str] = None,
**ctx_kwargs,
**ctx_kwargs: Any,
) -> RouteHandler:
"""
Add an API URL under the **OPTIONS** *HTTP* method
Expand Down Expand Up @@ -517,7 +517,7 @@ def patch(
name: Optional[str] = None,
version_prefix: str = "/v",
error_format: Optional[str] = None,
**ctx_kwargs,
**ctx_kwargs: Any,
) -> RouteHandler:
"""
Add an API URL under the **PATCH** *HTTP* method
Expand Down Expand Up @@ -570,7 +570,7 @@ def delete(
ignore_body: bool = True,
version_prefix: str = "/v",
error_format: Optional[str] = None,
**ctx_kwargs,
**ctx_kwargs: Any,
) -> RouteHandler:
"""
Add an API URL under the **DELETE** *HTTP* method
Expand Down Expand Up @@ -614,7 +614,7 @@ def websocket(
apply: bool = True,
version_prefix: str = "/v",
error_format: Optional[str] = None,
**ctx_kwargs,
**ctx_kwargs: Any,
):
"""
Decorate a function to be registered as a websocket route
Expand Down Expand Up @@ -658,7 +658,7 @@ def add_websocket_route(
name: Optional[str] = None,
version_prefix: str = "/v",
error_format: Optional[str] = None,
**ctx_kwargs,
**ctx_kwargs: Any,
):
"""
A helper method to register a function as a websocket route.
Expand Down Expand Up @@ -695,18 +695,18 @@ def add_websocket_route(

def static(
self,
uri,
uri: str,
file_or_directory: Union[str, bytes, PurePath],
pattern=r"/?.+",
use_modified_since=True,
use_content_range=False,
stream_large_files=False,
name="static",
host=None,
strict_slashes=None,
content_type=None,
apply=True,
resource_type=None,
pattern: str = r"/?.+",
use_modified_since: bool = True,
use_content_range: bool = False,
stream_large_files: bool = False,
name: str = "static",
host: Optional[str] = None,
strict_slashes: Optional[bool] = None,
content_type: Optional[bool] = None,
apply: bool = True,
resource_type: Optional[str] = None,
):
"""
Register a root to serve files from. The input can either be a
Expand Down
4 changes: 2 additions & 2 deletions sanic/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ async def __aexit__(self, *_):


def empty(
status=204, headers: Optional[Dict[str, str]] = None
status: int = 204, headers: Optional[Dict[str, str]] = None
) -> HTTPResponse:
"""
Returns an empty response to the client.
Expand All @@ -227,7 +227,7 @@ def json(
headers: Optional[Dict[str, str]] = None,
content_type: str = "application/json",
dumps: Optional[Callable[..., str]] = None,
**kwargs,
**kwargs: Any,
) -> HTTPResponse:
"""
Returns response object with body in json format.
Expand Down
19 changes: 19 additions & 0 deletions tests/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1266,3 +1266,22 @@ async def handler(request: Request):

assert request.route.ctx.foo() == "foo"
assert await request.route.ctx.bar() == 99


@pytest.mark.asyncio
async def test_duplicate_route_deprecation(app):
@app.route("/foo", name="duped")
async def handler_foo(request):
return text("...")

@app.route("/bar", name="duped")
async def handler_bar(request):
return text("...")

message = (
r"\[DEPRECATION v23\.3\] Duplicate route names detected: "
r"test_duplicate_route_deprecation\.duped\. In the future, "
r"Sanic will enforce uniqueness in route naming\."
)
with pytest.warns(DeprecationWarning, match=message):
await app._startup()

0 comments on commit e36a51e

Please sign in to comment.