feat: annotate HttpRequest as readable, HttpResponse as writable#3218
feat: annotate HttpRequest as readable, HttpResponse as writable#3218alexei wants to merge 3 commits into
Conversation
sobolevn
left a comment
There was a problem hiding this comment.
you don't have to inherit from a protocol to make use of it. HttpRequest already should be compatible with Readable and HttpResponse should be compatible with Writable.
If you want, you can submit a test case for that.
|
It's my fault for not explaining this. I found this while writing to a response with a function that accepted a writable file-thing i.e. |
|
@runtime_checkable
class Reader(Protocol[T_co]):
"""Protocol for simple I/O reader instances.
This protocol only supports blocking I/O.
"""
__slots__ = ()
@abc.abstractmethod
def read(self, size: int = ..., /) -> T_co:
"""Read data from the input stream and return it.
If *size* is specified, at most *size* items (bytes/characters) will be
read.
"""So, you don't need to modify django-stubs/django-stubs/http/request.pyi Line 117 in ca4389e Reader protocol.
As I said before you can add a test case to to_read: Reader = HttpRequest()And the same for |
|
I forgot about this -- sorry! Yes, but not in https://github.com/python/cpython/blob/b87590fd275b992364b716ea79341fd6069009c5/Lib/io.py#L107 or -- After writing this comment I realised I discovered this under Python 3.11, which makes it weird. I'll need to do some tests. |
|
The same code: from django.http import HttpRequest, HttpResponse
from typing_extensions import Writer
def write_to_response(output: Writer[str], contents: str) -> None:
output.write(contents)
def view(request: HttpRequest) -> HttpResponse:
resp = HttpResponse()
write_to_response(resp, "Hello, World!")
return respFails on Python 3.10-3.14: > uv run ty check
error[[invalid-argument-type](https://ty.dev/rules#invalid-argument-type)]: Argument to function `write_to_response` is incorrect
--> main.py:11:23
|
9 | def view(request: HttpRequest) -> HttpResponse:
10 | resp = HttpResponse()
11 | write_to_response(resp, "Hello, World!")
| ^^^^ Expected `Writer[str]`, found `HttpResponse`
12 | return resp
|
info: Function defined here
--> main.py:5:5
|
5 | def write_to_response(output: Writer[str], contents: str) -> None:
| ^^^^^^^^^^^^^^^^^ ------------------- Parameter declared here
6 | output.write(contents)
|
info: rule `invalid-argument-type` is enabled by default
Found 1 diagnostic... until I annotate While I think it should fail on Python 3.14 because it's an ABC, I must admit I'm confused about the earlier versions where they're |
|
And I just learned Django's |
sobolevn
left a comment
There was a problem hiding this comment.
Feel free to add a test case to https://github.com/typeddjango/django-stubs/tree/master/tests/assert_type
HttpRequests are readable, whileHttpResponses are writable. It's insufficient that they havereadandwritemethods respectively, as one would have to use aProtocol. HoweverReaderandWriterare already available in theiopackage and are better suited.