internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: sanic-org/sanic

Issue:
Goin' Fast URL IPv6 address is not bracketed
Sanic says:
```
sanic myprogram.app -H ::
Goin' Fast @ http://:::8000
```

The correct formatting for IPv6 would be:
```
Goin' Fast @ http://[::]:8000
```

Fixing the Goin' fast banner in `sanic/app.py` would be an easy enough task for someone wishing to start hacking Sanic. Existing code from `sanic/models/server_types.py` class `ConnInfo` could be useful, as there already is handling for adding brackets to IPv6 addresses.



Discussion:

Resolving patch:
diff --git a/sanic/app.py b/sanic/app.py
--- a/sanic/app.py
+++ b/sanic/app.py
@@ -1337,7 +1337,9 @@ def _helper(
             if unix:
                 logger.info(f"Goin' Fast @ {unix} {proto}://...")
             else:
-                logger.info(f"Goin' Fast @ {proto}://{host}:{port}")
+                # colon(:) is legal for a host only in an ipv6 address
+                display_host = f"[{host}]" if ":" in host else host
+                logger.info(f"Goin' Fast @ {proto}://{display_host}:{port}")
 
         debug_mode = "enabled" if self.debug else "disabled"
         reload_mode = "enabled" if auto_reload else "disabled"


Test patch:
diff --git a/tests/test_cli.py b/tests/test_cli.py
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -62,6 +62,57 @@ def test_host_port(cmd):
     assert firstline == b"Goin' Fast @ http://localhost:9999"
 
 
+@pytest.mark.parametrize(
+    "cmd",
+    (
+        ("--host=127.0.0.127", "--port=9999"),
+        ("-H", "127.0.0.127", "-p", "9999"),
+    ),
+)
+def test_host_port(cmd):
+    command = ["sanic", "fake.server.app", *cmd]
+    out, err, exitcode = capture(command)
+    lines = out.split(b"\n")
+    firstline = lines[6]
+
+    assert exitcode != 1
+    assert firstline == b"Goin' Fast @ http://127.0.0.127:9999"
+
+
+@pytest.mark.parametrize(
+    "cmd",
+    (
+        ("--host=::", "--port=9999"),
+        ("-H", "::", "-p", "9999"),
+    ),
+)
+def test_host_port(cmd):
+    command = ["sanic", "fake.server.app", *cmd]
+    out, err, exitcode = capture(command)
+    lines = out.split(b"\n")
+    firstline = lines[6]
+
+    assert exitcode != 1
+    assert firstline == b"Goin' Fast @ http://[::]:9999"
+
+
+@pytest.mark.parametrize(
+    "cmd",
+    (
+        ("--host=::1", "--port=9999"),
+        ("-H", "::1", "-p", "9999"),
+    ),
+)
+def test_host_port(cmd):
+    command = ["sanic", "fake.server.app", *cmd]
+    out, err, exitcode = capture(command)
+    lines = out.split(b"\n")
+    firstline = lines[6]
+
+    assert exitcode != 1
+    assert firstline == b"Goin' Fast @ http://[::1]:9999"
+
+
 @pytest.mark.parametrize(
     "num,cmd",
     (
Repository: sanic-org/sanic

Issue:
http.lifecycle.response should be dispatched in exception handler
Currently the `http.lifecycle.response` is only dispatched from `handle_request`. It also should be dispatched from `handle_exception`.


Discussion:

Resolving patch:
diff --git a/sanic/app.py b/sanic/app.py
--- a/sanic/app.py
+++ b/sanic/app.py
@@ -775,6 +775,14 @@ async def handle_exception(
             if request.stream:
                 response = request.stream.response
         if isinstance(response, BaseHTTPResponse):
+            await self.dispatch(
+                "http.lifecycle.response",
+                inline=True,
+                context={
+                    "request": request,
+                    "response": response,
+                },
+            )
             await response.send(end_stream=True)
         else:
             raise ServerError(


Test patch:
Repository: sanic-org/sanic

Issue:
Websocket logger uses sanic.log.error_logger
Hey there,

Why do we see:

    sanic.error - INFO - connection open

via stderr when getting new websocket connections. Shouldn't this go to stdout?

Also, is it possible to add "middleware" so we can properly log websocket connections and disconnects?  Is it possible to get a callback on websocket disconnects? 

Thanks!


Discussion:
:thinking: What version of Sanic and websockets are you using? I do not see that log in our codebase at all.
@vgoklani I tracked it down. It is indeed a log from `websockets`. It is because of this:

[`logger=error_logger`](https://github.com/sanic-org/sanic/blob/8dfa49b6483d4730ee8e525764b764b2ee33f897/sanic/server/protocols/websocket_protocol.py#L107)

Would you be willing to make a PR for us to switch to the regular logger?

```python
from sanic.log import logger
```
thanks @ahopkins ! 

I've never done a PR before, so that may end up being a disaster... 
@vgoklani There's no time like now to start :sunglasses: 

To be honest, this one would be simple to do from the GitHub UI. Click the "fork" in the top right. Find the file and hit "edit", then just follow the prompts. Happy to help if you have questions.

Resolving patch:
diff --git a/sanic/server/protocols/websocket_protocol.py b/sanic/server/protocols/websocket_protocol.py
--- a/sanic/server/protocols/websocket_protocol.py
+++ b/sanic/server/protocols/websocket_protocol.py
@@ -5,7 +5,7 @@
 from websockets.typing import Subprotocol
 
 from sanic.exceptions import ServerError
-from sanic.log import error_logger
+from sanic.log import logger
 from sanic.server import HttpProtocol
 
 from ..websockets.impl import WebsocketImplProtocol
@@ -104,7 +104,7 @@ async def websocket_handshake(
                 max_size=self.websocket_max_size,
                 subprotocols=subprotocols,
                 state=OPEN,
-                logger=error_logger,
+                logger=logger,
             )
             resp: "http11.Response" = ws_conn.accept(request)
         except Exception:


Test patch:
Repository: sanic-org/sanic

Issue:
Update websockets implementation for 3.11
To make the websocket implementation 3.11 compat, we need to remove the deprecated usage of `asyncio.wait` here:  https://github.com/sanic-org/sanic/blob/4a416e177aa5037ba9436e53f531631707e87ea7/sanic/server/websockets/impl.py#L521


---

thank you both 

@ahopkins - We also get this warning in the error logs when using websockets:

    DeprecationWarning: The explicit passing of coroutine objects to asyncio.wait() is deprecated since Python 3.8, and scheduled for removal in Python 3.11.  done, pending = await asyncio.wait(

Is this from the websockets package?

_Originally posted by @vgoklani in https://github.com/sanic-org/sanic/issues/2371#issuecomment-1013105803_

@vgoklani 

> Is this from the websockets package?

This is separate and should probably be opened as a new issue. It should be a simple fix:

```python
            self.recv_cancel = asyncio.Future()
            tasks = (
                self.recv_cancel,
                # NEXT LINE IS THE CHANGE NEEDED
                # TO EXPLICITLY CREATE THE TASK
                asyncio.create_task(self.assembler.get(timeout)),
            )
            done, pending = await asyncio.wait(
                tasks,
                return_when=asyncio.FIRST_COMPLETED,
            )
```

_Originally posted by @ahopkins in https://github.com/sanic-org/sanic/issues/2371#issuecomment-1013822496_


Discussion:
Can i have this?
Done

Resolving patch:
diff --git a/sanic/server/websockets/impl.py b/sanic/server/websockets/impl.py
--- a/sanic/server/websockets/impl.py
+++ b/sanic/server/websockets/impl.py
@@ -518,8 +518,12 @@ async def recv(self, timeout: Optional[float] = None) -> Optional[Data]:
             )
         try:
             self.recv_cancel = asyncio.Future()
+            tasks = (
+                self.recv_cancel,
+                asyncio.ensure_future(self.assembler.get(timeout)),
+            )
             done, pending = await asyncio.wait(
-                (self.recv_cancel, self.assembler.get(timeout)),
+                tasks,
                 return_when=asyncio.FIRST_COMPLETED,
             )
             done_task = next(iter(done))
@@ -570,8 +574,12 @@ async def recv_burst(self, max_recv=256) -> Sequence[Data]:
             self.can_pause = False
             self.recv_cancel = asyncio.Future()
             while True:
+                tasks = (
+                    self.recv_cancel,
+                    asyncio.ensure_future(self.assembler.get(timeout=0)),
+                )
                 done, pending = await asyncio.wait(
-                    (self.recv_cancel, self.assembler.get(timeout=0)),
+                    tasks,
                     return_when=asyncio.FIRST_COMPLETED,
                 )
                 done_task = next(iter(done))


Test patch:
Repository: sanic-org/sanic

Issue:
URL parse needs better error
a weird stacktrace popped into my log out of nowhere and i have no idea waht triggered it or what it means

paste of the code cause githubs "code" removes formatting https://pastebin.com/uFgw9hyk


Discussion:
As discussed with @sjsadowski on Discord, we should wrap the httptools parsing with an exception with a nicer error message.
**Is your feature request related to a problem? Please describe.**
Problem: when httptools parses a url with an incomplete or invalid schema, the server returns a 500 error instead of a 400 BAD REQUEST

**Describe the solution you'd like**
properly return 400 BAD REQUEST


Resolving patch:
diff --git a/sanic/exceptions.py b/sanic/exceptions.py
--- a/sanic/exceptions.py
+++ b/sanic/exceptions.py
@@ -51,6 +51,10 @@ class InvalidUsage(SanicException):
     quiet = True
 
 
+class BadURL(InvalidUsage):
+    ...
+
+
 class MethodNotSupported(SanicException):
     """
     **Status**: 405 Method Not Allowed
diff --git a/sanic/request.py b/sanic/request.py
--- a/sanic/request.py
+++ b/sanic/request.py
@@ -30,10 +30,11 @@
 from urllib.parse import parse_qs, parse_qsl, unquote, urlunparse
 
 from httptools import parse_url  # type: ignore
+from httptools.parser.errors import HttpParserInvalidURLError  # type: ignore
 
 from sanic.compat import CancelledErrors, Header
 from sanic.constants import DEFAULT_HTTP_CONTENT_TYPE
-from sanic.exceptions import InvalidUsage, ServerError
+from sanic.exceptions import BadURL, InvalidUsage, ServerError
 from sanic.headers import (
     AcceptContainer,
     Options,
@@ -129,8 +130,10 @@ def __init__(
     ):
 
         self.raw_url = url_bytes
-        # TODO: Content-Encoding detection
-        self._parsed_url = parse_url(url_bytes)
+        try:
+            self._parsed_url = parse_url(url_bytes)
+        except HttpParserInvalidURLError:
+            raise BadURL(f"Bad URL: {url_bytes.decode()}")
         self._id: Optional[Union[uuid.UUID, str, int]] = None
         self._name: Optional[str] = None
         self.app = app


Test patch:
diff --git a/tests/test_request.py b/tests/test_request.py
--- a/tests/test_request.py
+++ b/tests/test_request.py
@@ -4,6 +4,7 @@
 import pytest
 
 from sanic import Sanic, response
+from sanic.exceptions import BadURL
 from sanic.request import Request, uuid
 from sanic.server import HttpProtocol
 
@@ -176,3 +177,17 @@ async def get(request):
         "text/x-dvi; q=0.8",
         "text/plain; q=0.5",
     ]
+
+
+def test_bad_url_parse():
+    message = "Bad URL: my.redacted-domain.com:443"
+    with pytest.raises(BadURL, match=message):
+        Request(
+            b"my.redacted-domain.com:443",
+            Mock(),
+            Mock(),
+            Mock(),
+            Mock(),
+            Mock(),
+            Mock(),
+        )
Repository: sanic-org/sanic

Issue:
Cancel tasks with a message where appropriate
[cancel()](https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancel) also accepts a "msg" argument, might it be a good idea for this "message" to be added to places like https://github.com/sanic-org/sanic/blob/f7abf3db1bd4e79cd5121327359fc9021fab7ff3/sanic/server/protocols/http_protocol.py#L172 that are otherwise calling cancel() with no explanatory message?    if this is the CancelledError this user is getting, a simple message there would save everyone a lot of time.

_Originally posted by @zzzeek in https://github.com/sanic-org/sanic/issues/2296#issuecomment-983881945_

---

Where we are able to in Py3.9, we should add a message to `cancel()`.


Discussion:
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If this  is incorrect, please respond with an update. Thank you for your contributions.

...
Can i have this?
Sold. 👌

Resolving patch:
diff --git a/sanic/server/protocols/http_protocol.py b/sanic/server/protocols/http_protocol.py
--- a/sanic/server/protocols/http_protocol.py
+++ b/sanic/server/protocols/http_protocol.py
@@ -8,6 +8,8 @@
 if TYPE_CHECKING:  # no cov
     from sanic.app import Sanic
 
+import sys
+
 from asyncio import CancelledError
 from time import monotonic as current_time
 
@@ -169,7 +171,10 @@ def check_timeouts(self):
                 )
                 self.loop.call_later(max(0.1, interval), self.check_timeouts)
                 return
-            self._task.cancel()
+            cancel_msg_args = ()
+            if sys.version_info >= (3, 9):
+                cancel_msg_args = ("Cancel connection task with a timeout",)
+            self._task.cancel(*cancel_msg_args)
         except Exception:
             error_logger.exception("protocol.check_timeouts")
 


Test patch:
Repository: sanic-org/sanic

Issue:
Easier websocket interface annotation
Right now, to properly annotate a websocket endpoint you need to do this:

```python
from sanic.server.websockets.impl import WebsocketImplProtocol
from sanic import Request

@app.websocket("")
async def handler(request: Request, ws: WebsocketImplProtocol):
    ...
```

That is not easy or intuitive.

This would be much nicer:

```python
from sanic import Request, Websocket

@app.websocket("")
async def handler(request: Request, ws: Websocket):
    ...
```

We should just alias and put it inside `__init__.py` for convenience.


Discussion:

Resolving patch:
diff --git a/sanic/__init__.py b/sanic/__init__.py
--- a/sanic/__init__.py
+++ b/sanic/__init__.py
@@ -4,6 +4,7 @@
 from sanic.constants import HTTPMethod
 from sanic.request import Request
 from sanic.response import HTTPResponse, html, json, text
+from sanic.server.websockets.impl import WebsocketImplProtocol as Websocket
 
 
 __all__ = (
@@ -13,6 +14,7 @@
     "HTTPMethod",
     "HTTPResponse",
     "Request",
+    "Websocket",
     "html",
     "json",
     "text",


Test patch:
Repository: sanic-org/sanic

Issue:
Error Handler mismatch warning
The warning for error handler mismatch is triggering on v22.3 accidentally when setting `FALLBACK_ERROR_FORMAT`.

```python
app.config.FALLBACK_ERROR_FORMAT = "text"


@app.get("/")
async def handler(request: Request):
    1 / 0
```

This can be resolved as follows:

```python
    @classmethod
    def _get_fallback_value(cls, error_handler: ErrorHandler, config: Config):
        if error_handler._fallback is not _default:
            if config._FALLBACK_ERROR_FORMAT == error_handler._fallback:  # <<<<< This line needs this change
                return error_handler.fallback

            error_logger.warning(
                "Conflicting error fallback values were found in the "
                "error handler and in the app.config while handling an "
                "exception. Using the value from app.config."
            )
        return config.FALLBACK_ERROR_FORMAT
```

https://github.com/sanic-org/sanic/blob/5d683c6ea4b615e80c51d80189436437b824cce6/sanic/handlers.py#L79


Discussion:

Resolving patch:
diff --git a/sanic/handlers.py b/sanic/handlers.py
--- a/sanic/handlers.py
+++ b/sanic/handlers.py
@@ -78,7 +78,7 @@ def _warn_fallback_deprecation():
     @classmethod
     def _get_fallback_value(cls, error_handler: ErrorHandler, config: Config):
         if error_handler._fallback is not _default:
-            if config._FALLBACK_ERROR_FORMAT is _default:
+            if config._FALLBACK_ERROR_FORMAT == error_handler._fallback:
                 return error_handler.fallback
 
             error_logger.warning(


Test patch:
Repository: sanic-org/sanic

Issue:
In multiworker mode better error message if no apps
If a developer does not define their app so that a worker process can access it, they will receive a `KeyError` when Sanic tries to access it from the registry.

For example, that would happen if an app only was instantiated on the main process:

```python
if __name__ == "__main__":
    app = Sanic(...)
    app.run()
```

The solution to this is usually either to move the instantiation outside that block, or to use an [`AppLoader`](https://sanic.dev/en/guide/deployment/app-loader.html).

We should provide a better error message from within a worker process if an app cannot be found in a registry.


Discussion:
I want to take it🙂
All yours 😛 

Resolving patch:
diff --git a/sanic/app.py b/sanic/app.py
--- a/sanic/app.py
+++ b/sanic/app.py
@@ -1453,7 +1453,14 @@ def get_app(
                 return cls.get_app("__mp_main__", force_create=force_create)
             if force_create:
                 return cls(name)
-            raise SanicException(f'Sanic app name "{name}" not found.')
+            raise SanicException(
+                f"Sanic app name '{name}' not found.\n"
+                "App instantiation must occur outside "
+                "if __name__ == '__main__' "
+                "block or by using an AppLoader.\nSee "
+                "https://sanic.dev/en/guide/deployment/app-loader.html"
+                " for more details."
+            )
 
     @classmethod
     def _check_uvloop_conflict(cls) -> None:


Test patch:
diff --git a/tests/test_app.py b/tests/test_app.py
--- a/tests/test_app.py
+++ b/tests/test_app.py
@@ -347,7 +347,13 @@ def test_app_registry_retrieval_from_multiple():
 
 def test_get_app_does_not_exist():
     with pytest.raises(
-        SanicException, match='Sanic app name "does-not-exist" not found.'
+        SanicException,
+        match="Sanic app name 'does-not-exist' not found.\n"
+            "App instantiation must occur outside "
+            "if __name__ == '__main__' "
+            "block or by using an AppLoader.\nSee "
+            "https://sanic.dev/en/guide/deployment/app-loader.html"
+            " for more details."
     ):
         Sanic.get_app("does-not-exist")
Repository: sanic-org/sanic

Issue:
Auto reloader consumes full CPU core
**Describe the bug**

Enabling the auto reloader (`auto_reload=True` or `--auto-reload`) will consume a full CPU core, because it is looping over all files in all loaded modules and `stat`-ing every file. 100% usage on a single core is observed on macOS and Linux.

The problematic loop is here:

https://github.com/sanic-org/sanic/blob/f891995b487f01ff1207afcd241ae359725a8e3c/sanic/worker/reloader.py#L46-L64

**Code snippet**

Run the following minimal example with `python3 test.py` or `sanic test:app --auto-reload` and watch CPU usage

```python
from sanic import Sanic, text

app = Sanic("test")


@app.route("/")
def hello_world(request):
    return text("hello, world")


if __name__ == "__main__":
    app.run(auto_reload=True)
```


**Expected behavior**

The reloader should not consume a full CPU core, but should watch the file system for changes more intelligently, using platform-specific methods (inotify, FSEvents, kqueue, etc). See the [watchdog](https://github.com/gorakhargosh/watchdog/) project for inspiration. Maybe `watchdog` could be included as an optional dependency and used if available?

For instance, [another popular framework has implemented two reloader loops](https://github.com/pallets/werkzeug/blob/2.2.2/src/werkzeug/_reloader.py) and will select the `watchdog` loop if the package is available.

Alternatively, simply add a short sleep step to the reloader loop. I think a one second delay in reloading is acceptable.

**Environment (please complete the following information):**
 - OS: macOS 12.6, Ubuntu Linux 22.04 (likely also Windows, but not tested)
 - Sanic Version: 22.9.0



Discussion:
I noticed the `Reloader` class already had an `interval` property which is unused. I made a pull request #2567 to actually make use of this interval to sleep in the main loop.
This issue has been mentioned on **Sanic Community Discussion**. There might be relevant details there:

https://community.sanicframework.org/t/on-intel-mac-the-sanic-dev-mode-uses-99-cpu/1077/2


Resolving patch:
diff --git a/sanic/worker/reloader.py b/sanic/worker/reloader.py
--- a/sanic/worker/reloader.py
+++ b/sanic/worker/reloader.py
@@ -9,6 +9,7 @@
 from pathlib import Path
 from signal import SIGINT, SIGTERM
 from signal import signal as signal_func
+from time import sleep
 from typing import Dict, Set
 
 from sanic.server.events import trigger_events
@@ -62,6 +63,7 @@ def __call__(self) -> None:
                 self.reload(",".join(changed) if changed else "unknown")
                 if after_trigger:
                     trigger_events(after_trigger, loop, app)
+            sleep(self.interval)
         else:
             if reloader_stop:
                 trigger_events(reloader_stop, loop, app)


Test patch:
Repository: sanic-org/sanic

Issue:
ASGI websocket must pass thru bytes as is


_Originally posted by @Tronic in https://github.com/sanic-org/sanic/pull/2640#discussion_r1058027028_
      


Discussion:

If no one else is working on this issue by next week, I will work this issue. :D
it's yours 

Resolving patch:
diff --git a/sanic/server/websockets/connection.py b/sanic/server/websockets/connection.py
--- a/sanic/server/websockets/connection.py
+++ b/sanic/server/websockets/connection.py
@@ -45,7 +45,7 @@ async def send(self, data: Union[str, bytes], *args, **kwargs) -> None:
 
         await self._send(message)
 
-    async def recv(self, *args, **kwargs) -> Optional[str]:
+    async def recv(self, *args, **kwargs) -> Optional[Union[str, bytes]]:
         message = await self._receive()
 
         if message["type"] == "websocket.receive":
@@ -53,7 +53,7 @@ async def recv(self, *args, **kwargs) -> Optional[str]:
                 return message["text"]
             except KeyError:
                 try:
-                    return message["bytes"].decode()
+                    return message["bytes"]
                 except KeyError:
                     raise InvalidUsage("Bad ASGI message received")
         elif message["type"] == "websocket.disconnect":


Test patch:
diff --git a/tests/test_asgi.py b/tests/test_asgi.py
--- a/tests/test_asgi.py
+++ b/tests/test_asgi.py
@@ -342,7 +342,7 @@ async def test_websocket_send(send, receive, message_stack):
 
 
 @pytest.mark.asyncio
-async def test_websocket_receive(send, receive, message_stack):
+async def test_websocket_text_receive(send, receive, message_stack):
     msg = {"text": "hello", "type": "websocket.receive"}
     message_stack.append(msg)
 
@@ -351,6 +351,15 @@ async def test_websocket_receive(send, receive, message_stack):
 
     assert text == msg["text"]
 
+@pytest.mark.asyncio
+async def test_websocket_bytes_receive(send, receive, message_stack):
+    msg = {"bytes": b"hello", "type": "websocket.receive"}
+    message_stack.append(msg)
+
+    ws = WebSocketConnection(send, receive)
+    data = await ws.receive()
+
+    assert data == msg["bytes"]
 
 @pytest.mark.asyncio
 async def test_websocket_accept_with_no_subprotocols(