{"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107862882", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107862882, "node_id": "IC_kwDOBm6k_c5CCKVi", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T15:23:56Z", "updated_at": "2022-04-24T15:23:56Z", "author_association": "OWNER", "body": "Found https://github.com/asottile/blacken-docs via\r\n- https://github.com/psf/black/issues/294", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107863365", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107863365, "node_id": "IC_kwDOBm6k_c5CCKdF", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T15:26:41Z", "updated_at": "2022-04-24T15:26:41Z", "author_association": "OWNER", "body": "Tried this:\r\n```\r\npip install blacken-docs\r\nblacken-docs docs/*.rst\r\ngit diff | pbcopy\r\n```\r\nGot this:\r\n```diff\r\n diff --git a/docs/authentication.rst b/docs/authentication.rst\r\nindex 0d98cf8..8008023 100644\r\n--- a/docs/authentication.rst\r\n+++ b/docs/authentication.rst\r\n@@ -381,11 +381,7 @@ Authentication plugins can set signed ``ds_actor`` cookies themselves like so:\r\n .. code-block:: python\r\n \r\n response = Response.redirect(\"/\")\r\n- response.set_cookie(\"ds_actor\", datasette.sign({\r\n- \"a\": {\r\n- \"id\": \"cleopaws\"\r\n- }\r\n- }, \"actor\"))\r\n+ response.set_cookie(\"ds_actor\", datasette.sign({\"a\": {\"id\": \"cleopaws\"}}, \"actor\"))\r\n \r\n Note that you need to pass ``\"actor\"`` as the namespace to :ref:`datasette_sign`.\r\n \r\n@@ -412,12 +408,16 @@ To include an expiry, add a ``\"e\"`` key to the cookie value containing a `base62\r\n expires_at = int(time.time()) + (24 * 60 * 60)\r\n \r\n response = Response.redirect(\"/\")\r\n- response.set_cookie(\"ds_actor\", datasette.sign({\r\n- \"a\": {\r\n- \"id\": \"cleopaws\"\r\n- },\r\n- \"e\": baseconv.base62.encode(expires_at),\r\n- }, \"actor\"))\r\n+ response.set_cookie(\r\n+ \"ds_actor\",\r\n+ datasette.sign(\r\n+ {\r\n+ \"a\": {\"id\": \"cleopaws\"},\r\n+ \"e\": baseconv.base62.encode(expires_at),\r\n+ },\r\n+ \"actor\",\r\n+ ),\r\n+ )\r\n \r\n The resulting cookie will encode data that looks something like this:\r\n \r\ndiff --git a/docs/spatialite.rst b/docs/spatialite.rst\r\nindex d1b300b..556bad8 100644\r\n--- a/docs/spatialite.rst\r\n+++ b/docs/spatialite.rst\r\n@@ -58,19 +58,22 @@ Here's a recipe for taking a table with existing latitude and longitude columns,\r\n .. code-block:: python\r\n \r\n import sqlite3\r\n- conn = sqlite3.connect('museums.db')\r\n+\r\n+ conn = sqlite3.connect(\"museums.db\")\r\n # Lead the spatialite extension:\r\n conn.enable_load_extension(True)\r\n- conn.load_extension('/usr/local/lib/mod_spatialite.dylib')\r\n+ conn.load_extension(\"/usr/local/lib/mod_spatialite.dylib\")\r\n # Initialize spatial metadata for this database:\r\n- conn.execute('select InitSpatialMetadata(1)')\r\n+ conn.execute(\"select InitSpatialMetadata(1)\")\r\n # Add a geometry column called point_geom to our museums table:\r\n conn.execute(\"SELECT AddGeometryColumn('museums', 'point_geom', 4326, 'POINT', 2);\")\r\n # Now update that geometry column with the lat/lon points\r\n- conn.execute('''\r\n+ conn.execute(\r\n+ \"\"\"\r\n UPDATE museums SET\r\n point_geom = GeomFromText('POINT('||\"longitude\"||' '||\"latitude\"||')',4326);\r\n- ''')\r\n+ \"\"\"\r\n+ )\r\n # Now add a spatial index to that column\r\n conn.execute('select CreateSpatialIndex(\"museums\", \"point_geom\");')\r\n # If you don't commit your changes will not be persisted:\r\n@@ -186,13 +189,14 @@ Here's Python code to create a SQLite database, enable SpatiaLite, create a plac\r\n .. code-block:: python\r\n \r\n import sqlite3\r\n- conn = sqlite3.connect('places.db')\r\n+\r\n+ conn = sqlite3.connect(\"places.db\")\r\n # Enable SpatialLite extension\r\n conn.enable_load_extension(True)\r\n- conn.load_extension('/usr/local/lib/mod_spatialite.dylib')\r\n+ conn.load_extension(\"/usr/local/lib/mod_spatialite.dylib\")\r\n # Create the masic countries table\r\n- conn.execute('select InitSpatialMetadata(1)')\r\n- conn.execute('create table places (id integer primary key, name text);')\r\n+ conn.execute(\"select InitSpatialMetadata(1)\")\r\n+ conn.execute(\"create table places (id integer primary key, name text);\")\r\n # Add a MULTIPOLYGON Geometry column\r\n conn.execute(\"SELECT AddGeometryColumn('places', 'geom', 4326, 'MULTIPOLYGON', 2);\")\r\n # Add a spatial index against the new column\r\n@@ -201,13 +205,17 @@ Here's Python code to create a SQLite database, enable SpatiaLite, create a plac\r\n from shapely.geometry.multipolygon import MultiPolygon\r\n from shapely.geometry import shape\r\n import requests\r\n- geojson = requests.get('https://data.whosonfirst.org/404/227/475/404227475.geojson').json()\r\n+\r\n+ geojson = requests.get(\r\n+ \"https://data.whosonfirst.org/404/227/475/404227475.geojson\"\r\n+ ).json()\r\n # Convert to \"Well Known Text\" format\r\n- wkt = shape(geojson['geometry']).wkt\r\n+ wkt = shape(geojson[\"geometry\"]).wkt\r\n # Insert and commit the record\r\n- conn.execute(\"INSERT INTO places (id, name, geom) VALUES(null, ?, GeomFromText(?, 4326))\", (\r\n- \"Wales\", wkt\r\n- ))\r\n+ conn.execute(\r\n+ \"INSERT INTO places (id, name, geom) VALUES(null, ?, GeomFromText(?, 4326))\",\r\n+ (\"Wales\", wkt),\r\n+ )\r\n conn.commit()\r\n \r\n Querying polygons using within()\r\ndiff --git a/docs/writing_plugins.rst b/docs/writing_plugins.rst\r\nindex bd60a4b..5af01f6 100644\r\n--- a/docs/writing_plugins.rst\r\n+++ b/docs/writing_plugins.rst\r\n@@ -18,9 +18,10 @@ The quickest way to start writing a plugin is to create a ``my_plugin.py`` file\r\n \r\n from datasette import hookimpl\r\n \r\n+\r\n @hookimpl\r\n def prepare_connection(conn):\r\n- conn.create_function('hello_world', 0, lambda: 'Hello world!')\r\n+ conn.create_function(\"hello_world\", 0, lambda: \"Hello world!\")\r\n \r\n If you save this in ``plugins/my_plugin.py`` you can then start Datasette like this::\r\n \r\n@@ -60,22 +61,18 @@ The example consists of two files: a ``setup.py`` file that defines the plugin:\r\n \r\n from setuptools import setup\r\n \r\n- VERSION = '0.1'\r\n+ VERSION = \"0.1\"\r\n \r\n setup(\r\n- name='datasette-plugin-demos',\r\n- description='Examples of plugins for Datasette',\r\n- author='Simon Willison',\r\n- url='https://github.com/simonw/datasette-plugin-demos',\r\n- license='Apache License, Version 2.0',\r\n+ name=\"datasette-plugin-demos\",\r\n+ description=\"Examples of plugins for Datasette\",\r\n+ author=\"Simon Willison\",\r\n+ url=\"https://github.com/simonw/datasette-plugin-demos\",\r\n+ license=\"Apache License, Version 2.0\",\r\n version=VERSION,\r\n- py_modules=['datasette_plugin_demos'],\r\n- entry_points={\r\n- 'datasette': [\r\n- 'plugin_demos = datasette_plugin_demos'\r\n- ]\r\n- },\r\n- install_requires=['datasette']\r\n+ py_modules=[\"datasette_plugin_demos\"],\r\n+ entry_points={\"datasette\": [\"plugin_demos = datasette_plugin_demos\"]},\r\n+ install_requires=[\"datasette\"],\r\n )\r\n \r\n And a Python module file, ``datasette_plugin_demos.py``, that implements the plugin:\r\n@@ -88,12 +85,12 @@ And a Python module file, ``datasette_plugin_demos.py``, that implements the plu\r\n \r\n @hookimpl\r\n def prepare_jinja2_environment(env):\r\n- env.filters['uppercase'] = lambda u: u.upper()\r\n+ env.filters[\"uppercase\"] = lambda u: u.upper()\r\n \r\n \r\n @hookimpl\r\n def prepare_connection(conn):\r\n- conn.create_function('random_integer', 2, random.randint)\r\n+ conn.create_function(\"random_integer\", 2, random.randint)\r\n \r\n \r\n Having built a plugin in this way you can turn it into an installable package using the following command::\r\n@@ -123,11 +120,13 @@ To bundle the static assets for a plugin in the package that you publish to PyPI\r\n \r\n .. code-block:: python\r\n \r\n- package_data={\r\n- 'datasette_plugin_name': [\r\n- 'static/plugin.js',\r\n- ],\r\n- },\r\n+ package_data = (\r\n+ {\r\n+ \"datasette_plugin_name\": [\r\n+ \"static/plugin.js\",\r\n+ ],\r\n+ },\r\n+ )\r\n \r\n Where ``datasette_plugin_name`` is the name of the plugin package (note that it uses underscores, not hyphens) and ``static/plugin.js`` is the path within that package to the static file.\r\n \r\n@@ -152,11 +151,13 @@ Templates should be bundled for distribution using the same ``package_data`` mec\r\n \r\n .. code-block:: python\r\n \r\n- package_data={\r\n- 'datasette_plugin_name': [\r\n- 'templates/my_template.html',\r\n- ],\r\n- },\r\n+ package_data = (\r\n+ {\r\n+ \"datasette_plugin_name\": [\r\n+ \"templates/my_template.html\",\r\n+ ],\r\n+ },\r\n+ )\r\n \r\n You can also use wildcards here such as ``templates/*.html``. See `datasette-edit-schema `__ for an example of this pattern.\r\n ```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107863924", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107863924, "node_id": "IC_kwDOBm6k_c5CCKl0", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T15:30:03Z", "updated_at": "2022-04-24T15:30:03Z", "author_association": "OWNER", "body": "On the one hand, I'm not crazy about some of the indentation decisions Black made here - in particular this one, which I had indented deliberately for readability:\r\n```diff\r\n diff --git a/docs/authentication.rst b/docs/authentication.rst\r\nindex 0d98cf8..8008023 100644\r\n--- a/docs/authentication.rst\r\n+++ b/docs/authentication.rst\r\n@@ -381,11 +381,7 @@ Authentication plugins can set signed ``ds_actor`` cookies themselves like so:\r\n .. code-block:: python\r\n \r\n response = Response.redirect(\"/\")\r\n- response.set_cookie(\"ds_actor\", datasette.sign({\r\n- \"a\": {\r\n- \"id\": \"cleopaws\"\r\n- }\r\n- }, \"actor\"))\r\n+ response.set_cookie(\"ds_actor\", datasette.sign({\"a\": {\"id\": \"cleopaws\"}}, \"actor\"))\r\n```\r\nBut... consistency is a virtue. Maybe I'm OK with just this one disagreement?\r\n\r\nAlso: I've been mentally trying to keep the line lengths a bit shorter to help them be more readable on mobile devices.\r\n\r\nI'll try a different line length using `blacken-docs -l 60 docs/*.rst` instead.\r\n\r\nI like this more - here's the result for that example:\r\n```diff\r\ndiff --git a/docs/authentication.rst b/docs/authentication.rst\r\nindex 0d98cf8..2496073 100644\r\n--- a/docs/authentication.rst\r\n+++ b/docs/authentication.rst\r\n@@ -381,11 +381,10 @@ Authentication plugins can set signed ``ds_actor`` cookies themselves like so:\r\n .. code-block:: python\r\n \r\n response = Response.redirect(\"/\")\r\n- response.set_cookie(\"ds_actor\", datasette.sign({\r\n- \"a\": {\r\n- \"id\": \"cleopaws\"\r\n- }\r\n- }, \"actor\"))\r\n+ response.set_cookie(\r\n+ \"ds_actor\",\r\n+ datasette.sign({\"a\": {\"id\": \"cleopaws\"}}, \"actor\"),\r\n+ )\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107865493", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107865493, "node_id": "IC_kwDOBm6k_c5CCK-V", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T15:39:02Z", "updated_at": "2022-04-24T15:39:02Z", "author_association": "OWNER", "body": "There's no `blacken-docs --check` option so I filed a feature request:\r\n- https://github.com/asottile/blacken-docs/issues/161", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107866013", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107866013, "node_id": "IC_kwDOBm6k_c5CCLGd", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T15:42:07Z", "updated_at": "2022-04-24T15:42:07Z", "author_association": "OWNER", "body": "In the absence of `--check` I can use this to detect if changes are applied:\r\n```zsh\r\n% git diff-index --quiet HEAD --\r\n% echo $? \r\n0\r\n% blacken-docs -l 60 docs/*.rst\r\ndocs/authentication.rst: Rewriting...\r\n...\r\n% git diff-index --quiet HEAD --\r\n% echo $? \r\n1\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107867281", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107867281, "node_id": "IC_kwDOBm6k_c5CCLaR", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T15:49:23Z", "updated_at": "2022-04-24T15:49:23Z", "author_association": "OWNER", "body": "I'm going to push the first commit with a deliberate missing formatting to check that the tests fail.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107868585", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107868585, "node_id": "IC_kwDOBm6k_c5CCLup", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T15:57:10Z", "updated_at": "2022-04-24T15:57:19Z", "author_association": "OWNER", "body": "The tests failed there because of what I thought were warnings but turn out to be treated as errors:\r\n```\r\n% blacken-docs -l 60 docs/*.rst \r\ndocs/internals.rst:196: code block parse error Cannot parse: 14:0: \r\ndocs/json_api.rst:449: code block parse error Cannot parse: 1:0: \r\ndocs/testing_plugins.rst:135: code block parse error Cannot parse: 5:0: \r\n% echo $?\r\n1\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107869556", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107869556, "node_id": "IC_kwDOBm6k_c5CCL90", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T16:02:27Z", "updated_at": "2022-04-24T16:02:27Z", "author_association": "OWNER", "body": "Looking at that first error it appears to be a place where I had deliberately omitted the body of the function:\r\n\r\nhttps://github.com/simonw/datasette/blob/36573638b0948174ae237d62e6369b7d55220d7f/docs/internals.rst#L196-L211\r\n\r\nI can use `...` as the function body here to get it to pass.\r\n\r\nFixing those warnings actually helped me spot a couple of bugs, so I'm glad this happened.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107869884", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107869884, "node_id": "IC_kwDOBm6k_c5CCMC8", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T16:04:03Z", "updated_at": "2022-04-24T16:04:03Z", "author_association": "OWNER", "body": "OK, I'm expecting this one to fail at the `git diff-index --quiet HEAD --` check.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107870788", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107870788, "node_id": "IC_kwDOBm6k_c5CCMRE", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T16:09:23Z", "updated_at": "2022-04-24T16:09:23Z", "author_association": "OWNER", "body": "One more attempt at testing the `git diff-index` trick.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107873271", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107873271, "node_id": "IC_kwDOBm6k_c5CCM33", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T16:23:57Z", "updated_at": "2022-04-24T16:23:57Z", "author_association": "OWNER", "body": "Turns out I didn't need that `git diff-index` trick after all - the `blacken-docs` command returns a non-zero exit code if it changes any files.\r\n\r\nSubmitted a documentation PR to that project instead:\r\n\r\n- https://github.com/asottile/blacken-docs/pull/162", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1718#issuecomment-1107873311", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1718", "id": 1107873311, "node_id": "IC_kwDOBm6k_c5CCM4f", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-04-24T16:24:14Z", "updated_at": "2022-04-24T16:24:14Z", "author_association": "OWNER", "body": "Wrote up what I learned in a TIL: https://til.simonwillison.net/sphinx/blacken-docs", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1213683988, "label": "Code examples in the documentation should be formatted with Black"}, "performed_via_github_app": null}