Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to keyword-only arguments for a bunch of internal methods #1822

Open
simonw opened this issue Sep 26, 2022 · 3 comments
Open

Switch to keyword-only arguments for a bunch of internal methods #1822

simonw opened this issue Sep 26, 2022 · 3 comments

Comments

@simonw
Copy link
Owner

simonw commented Sep 26, 2022

This is a good idea, and one that needs to happen before Datasette 1.0:

While you are adding features, would you be future-proofing your APIs if you switched over some arguments over to keyword-only arguments or would that be too disruptive?

Thinking out loud:

async def render_template( 
     self, templates, *, context=None, plugin_context=None, request=None, view_name=None 
): 

Originally posted by @jefftriplett in #1817 (comment)

@simonw
Copy link
Owner Author

simonw commented Sep 26, 2022

Everything on https://docs.datasette.io/en/stable/internals.html that uses keyword arguments should do this I think.

@simonw
Copy link
Owner Author

simonw commented Sep 26, 2022

A start:

diff --git a/datasette/utils/asgi.py b/datasette/utils/asgi.py
index 8a2fa060..41ade961 100644
--- a/datasette/utils/asgi.py
+++ b/datasette/utils/asgi.py
@@ -118,7 +118,7 @@ class Request:
         return dict(parse_qsl(body.decode("utf-8"), keep_blank_values=True))
 
     @classmethod
-    def fake(cls, path_with_query_string, method="GET", scheme="http", url_vars=None):
+    def fake(cls, path_with_query_string, *, method="GET", scheme="http", url_vars=None):
         """Useful for constructing Request objects for tests"""
         path, _, query_string = path_with_query_string.partition("?")
         scope = {
@@ -204,7 +204,7 @@ class AsgiWriter:
         )
 
 
-async def asgi_send_json(send, info, status=200, headers=None):
+async def asgi_send_json(send, info, *, status=200, headers=None):
     headers = headers or {}
     await asgi_send(
         send,
@@ -215,7 +215,7 @@ async def asgi_send_json(send, info, status=200, headers=None):
     )
 
 
-async def asgi_send_html(send, html, status=200, headers=None):
+async def asgi_send_html(send, html, *, status=200, headers=None):
     headers = headers or {}
     await asgi_send(
         send,
@@ -226,7 +226,7 @@ async def asgi_send_html(send, html, status=200, headers=None):
     )
 
 
-async def asgi_send_redirect(send, location, status=302):
+async def asgi_send_redirect(send, location, *, status=302):
     await asgi_send(
         send,
         "",
@@ -236,12 +236,12 @@ async def asgi_send_redirect(send, location, status=302):
     )
 
 
-async def asgi_send(send, content, status, headers=None, content_type="text/plain"):
+async def asgi_send(send, content, status, *, headers=None, content_type="text/plain"):
     await asgi_start(send, status, headers, content_type)
     await send({"type": "http.response.body", "body": content.encode("utf-8")})
 
 
-async def asgi_start(send, status, headers=None, content_type="text/plain"):
+async def asgi_start(send, status, *, headers=None, content_type="text/plain"):
     headers = headers or {}
     # Remove any existing content-type header
     headers = {k: v for k, v in headers.items() if k.lower() != "content-type"}
@@ -259,7 +259,7 @@ async def asgi_start(send, status, headers=None, content_type="text/plain"):
 
 
 async def asgi_send_file(
-    send, filepath, filename=None, content_type=None, chunk_size=4096, headers=None
+    send, filepath, filename=None, *, content_type=None, chunk_size=4096, headers=None
 ):
     headers = headers or {}
     if filename:
@@ -284,7 +284,7 @@ async def asgi_send_file(
             )
 
 
-def asgi_static(root_path, chunk_size=4096, headers=None, content_type=None):
+def asgi_static(root_path, *, chunk_size=4096, headers=None, content_type=None):
     root_path = Path(root_path)
 
     async def inner_static(request, send):
@@ -313,7 +313,7 @@ def asgi_static(root_path, chunk_size=4096, headers=None, content_type=None):
 
 
 class Response:
-    def __init__(self, body=None, status=200, headers=None, content_type="text/plain"):
+    def __init__(self, body=None, *, status=200, headers=None, content_type="text/plain"):
         self.body = body
         self.status = status
         self.headers = headers or {}
@@ -346,6 +346,7 @@ class Response:
         self,
         key,
         value="",
+        *,
         max_age=None,
         expires=None,
         path="/",
@@ -374,7 +375,7 @@ class Response:
         self._set_cookie_headers.append(cookie.output(header="").strip())
 
     @classmethod
-    def html(cls, body, status=200, headers=None):
+    def html(cls, body, *, status=200, headers=None):
         return cls(
             body,
             status=status,
@@ -383,7 +384,7 @@ class Response:
         )
 
     @classmethod
-    def text(cls, body, status=200, headers=None):
+    def text(cls, body, *, status=200, headers=None):
         return cls(
             str(body),
             status=status,
@@ -392,7 +393,7 @@ class Response:
         )
 
     @classmethod
-    def json(cls, body, status=200, headers=None, default=None):
+    def json(cls, body, *, status=200, headers=None, default=None):
         return cls(
             json.dumps(body, default=default),
             status=status,
@@ -401,7 +402,7 @@ class Response:
         )
 
     @classmethod
-    def redirect(cls, path, status=302, headers=None):
+    def redirect(cls, path, *, status=302, headers=None):
         headers = headers or {}
         headers["Location"] = path
         return cls("", status=status, headers=headers)
@@ -412,6 +413,7 @@ class AsgiFileDownload:
         self,
         filepath,
         filename=None,
+        *,
         content_type="application/octet-stream",
         headers=None,
     ):
diff --git a/datasette/app.py b/datasette/app.py
index 03d1dacc..4d4e5584 100644
--- a/datasette/app.py
+++ b/datasette/app.py
@@ -190,6 +190,7 @@ class Datasette:
     def __init__(
         self,
         files=None,
+        *,
         immutables=None,
         cache_headers=True,
         cors=False,

@simonw
Copy link
Owner Author

simonw commented Sep 27, 2022

I'll do this in a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant