{"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-938141121", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 938141121, "node_id": "IC_kwDOBm6k_c436uXB", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2021-10-07T20:42:37Z", "updated_at": "2021-10-24T22:19:28Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/1481?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report\n> Merging [#1481](https://codecov.io/gh/simonw/datasette/pull/1481?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (77542e7) into [main](https://codecov.io/gh/simonw/datasette/commit/63886178a649586b403966a27a45881709d2b868?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (6388617) will **decrease** coverage by `0.01%`.\n> The diff coverage is `n/a`.\n\n> :exclamation: Current head 77542e7 differs from pull request most recent head 50005bd. Consider uploading reports for the commit 50005bd to get more accurate results\n[![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1481/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)](https://codecov.io/gh/simonw/datasette/pull/1481?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)\n\n```diff\n@@ Coverage Diff @@\n## main #1481 +/- ##\n==========================================\n- Coverage 91.83% 91.82% -0.02% \n==========================================\n Files 34 34 \n Lines 4421 4426 +5 \n==========================================\n+ Hits 4060 4064 +4 \n- Misses 361 362 +1 \n```\n\n\n| [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/1481?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage \u0394 | |\n|---|---|---|\n| [datasette/app.py](https://codecov.io/gh/simonw/datasette/pull/1481/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `95.36% <0.00%> (-0.14%)` | :arrow_down: |\n| [datasette/views/base.py](https://codecov.io/gh/simonw/datasette/pull/1481/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL2Jhc2UucHk=) | `95.41% <0.00%> (\u00f8)` | |\n| [datasette/views/database.py](https://codecov.io/gh/simonw/datasette/pull/1481/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL2RhdGFiYXNlLnB5) | `97.56% <0.00%> (\u00f8)` | |\n| [datasette/views/table.py](https://codecov.io/gh/simonw/datasette/pull/1481/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL3RhYmxlLnB5) | `96.00% <0.00%> (+<0.01%)` | :arrow_up: |\n| [datasette/utils/\\_\\_init\\_\\_.py](https://codecov.io/gh/simonw/datasette/pull/1481/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3V0aWxzL19faW5pdF9fLnB5) | `94.78% <0.00%> (+0.02%)` | :arrow_up: |\n\n------\n\n[Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1481?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)\n> `\u0394 = absolute (impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/1481?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Last update [6388617...50005bd](https://codecov.io/gh/simonw/datasette/pull/1481?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-945020210", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 945020210, "node_id": "IC_kwDOBm6k_c44U90y", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-16T23:19:51Z", "updated_at": "2021-10-16T23:19:51Z", "author_association": "OWNER", "body": "Since that Janus PR hasn't been merged yet, one temporary option for a fix would be to entirely vendor the fixed Janus - https://github.com/aio-libs/janus/blob/9e13d3fb74e2c93d7501443b370a455d1b302b1f/janus/__init__.py - since it's only a single module.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-944986367", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 944986367, "node_id": "IC_kwDOBm6k_c44U1j_", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-16T19:07:38Z", "updated_at": "2021-10-16T19:09:02Z", "author_association": "OWNER", "body": "This is blocking an upgrade for the Homebrew Datasette package: https://github.com/Homebrew/homebrew-core/pull/86932", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-939185319", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 939185319, "node_id": "IC_kwDOBm6k_c43-tSn", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-09T00:04:54Z", "updated_at": "2021-10-09T00:04:54Z", "author_association": "OWNER", "body": "I applied my PR against Janus to my local copy of Datasette like so:\r\n\r\n pip uninstall janus\r\n pip install https://github.com/aio-libs/janus/archive/9e13d3fb74e2c93d7501443b370a455d1b302b1f.zip\r\n\r\nThen I ran the Datasette tests and got a much happier pass rate.\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": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-939180313", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 939180313, "node_id": "IC_kwDOBm6k_c43-sEZ", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-08T23:41:39Z", "updated_at": "2021-10-08T23:41:39Z", "author_association": "OWNER", "body": "I submitted a PR to Janus with a workaround for this: https://github.com/aio-libs/janus/pull/359", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-939100803", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 939100803, "node_id": "IC_kwDOBm6k_c43-YqD", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-08T20:33:42Z", "updated_at": "2021-10-08T20:33:42Z", "author_association": "OWNER", "body": "There's a tiny chance this could be a bug in Python 3.10 itself - I filed an issue here: https://bugs.python.org/issue45416 - in which I said:\r\n\r\n> In Python 3.10 it is not possible to instantiate an asyncio.Condition that wraps an asyncio.Lock without raising a \"loop argument must agree with lock\" exception.\r\n> \r\n> This code raises that exception:\r\n> \r\n> asyncio.Condition(asyncio.Lock())\r\n> \r\n> This worked in previous Python versions.\r\n> \r\n> Note that the error only occurs if an event loop is running. Here's a simple script that replicates the problem:\r\n> \r\n> import asyncio\r\n> \r\n> # This runs without an exception:\r\n> print(asyncio.Condition(asyncio.Lock()))\r\n> \r\n> # This does not work:\r\n> async def example():\r\n> print(asyncio.Condition(asyncio.Lock()))\r\n> \r\n> # This raises \"ValueError: loop argument must agree with lock\":\r\n> asyncio.run(example())", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-939079727", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 939079727, "node_id": "IC_kwDOBm6k_c43-Tgv", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-08T19:50:52Z", "updated_at": "2021-10-08T19:50:52Z", "author_association": "OWNER", "body": "And here's the relevant Janus code: https://github.com/aio-libs/janus/blob/d7970f8b76bcac2e087067ca4575ac845e481874/janus/__init__.py#L24-L42\r\n\r\n```python\r\nclass Queue(Generic[T]):\r\n def __init__(self, maxsize: int = 0) -> None:\r\n self._loop = current_loop()\r\n self._maxsize = maxsize\r\n\r\n self._init(maxsize)\r\n\r\n self._unfinished_tasks = 0\r\n\r\n self._sync_mutex = threading.Lock()\r\n self._sync_not_empty = threading.Condition(self._sync_mutex)\r\n self._sync_not_full = threading.Condition(self._sync_mutex)\r\n self._all_tasks_done = threading.Condition(self._sync_mutex)\r\n\r\n self._async_mutex = asyncio.Lock()\r\n # \"loop argument must agree with lock\" exception is raised here:\r\n self._async_not_empty = asyncio.Condition(self._async_mutex)\r\n self._async_not_full = asyncio.Condition(self._async_mutex)\r\n self._finished = asyncio.Event()\r\n self._finished.set()\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-939078872", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 939078872, "node_id": "IC_kwDOBm6k_c43-TTY", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-08T19:49:08Z", "updated_at": "2021-10-08T19:49:08Z", "author_association": "OWNER", "body": "Here's the code that raises that error: https://github.com/python/cpython/blob/bb3e0c240bc60fe08d332ff5955d54197f79751c/Lib/asyncio/locks.py#L219-L234\r\n\r\n```python\r\nclass Condition(_ContextManagerMixin, mixins._LoopBoundMixin):\r\n \"\"\"Asynchronous equivalent to threading.Condition.\r\n This class implements condition variable objects. A condition variable\r\n allows one or more coroutines to wait until they are notified by another\r\n coroutine.\r\n A new Lock object is created and used as the underlying lock.\r\n \"\"\"\r\n\r\n def __init__(self, lock=None, *, loop=mixins._marker):\r\n super().__init__(loop=loop)\r\n if lock is None:\r\n lock = Lock()\r\n elif lock._loop is not self._get_loop():\r\n raise ValueError(\"loop argument must agree with lock\")\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": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-939078095", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 939078095, "node_id": "IC_kwDOBm6k_c43-THP", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-08T19:47:29Z", "updated_at": "2021-10-08T19:47:29Z", "author_association": "OWNER", "body": "Only mention I can find of that \"loop argument must agree with lock\" error is here - which doesn't have any tips for a workaround yet: https://giters.com/django/channels_redis/issues/278", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-939076399", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 939076399, "node_id": "IC_kwDOBm6k_c43-Ssv", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-08T19:43:33Z", "updated_at": "2021-10-08T19:43:33Z", "author_association": "OWNER", "body": "So maybe this is an issue with Janus? I'm using https://pypi.org/project/janus/ 0.6.1 which is the latest release, from October 2020.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-939075686", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 939075686, "node_id": "IC_kwDOBm6k_c43-Shm", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-08T19:42:00Z", "updated_at": "2021-10-08T19:42:00Z", "author_association": "OWNER", "body": "Running `pytest -x --pdb` helped me see this error:\r\n\r\n```\r\n File \"/Users/simon/Dropbox/Development/datasette/datasette/views/base.py\", line 122, in dispatch_request\r\n await self.ds.refresh_schemas()\r\n File \"/Users/simon/Dropbox/Development/datasette/datasette/app.py\", line 344, in refresh_schemas\r\n await self._refresh_schemas()\r\n File \"/Users/simon/Dropbox/Development/datasette/datasette/app.py\", line 349, in _refresh_schemas\r\n await init_internal_db(internal_db)\r\n File \"/Users/simon/Dropbox/Development/datasette/datasette/utils/internal_db.py\", line 5, in init_internal_db\r\n await db.execute_write(\r\n File \"/Users/simon/Dropbox/Development/datasette/datasette/database.py\", line 102, in execute_write\r\n return await self.execute_write_fn(_inner, block=block)\r\n File \"/Users/simon/Dropbox/Development/datasette/datasette/database.py\", line 113, in execute_write_fn\r\n reply_queue = janus.Queue()\r\n File \"/Users/simon/.local/share/virtualenvs/py310-Z8fTATkJ/lib/python3.10/site-packages/janus/__init__.py\", line 39, in __init__\r\n self._async_not_empty = asyncio.Condition(self._async_mutex)\r\n File \"/Users/simon/.pyenv/versions/3.10.0/lib/python3.10/asyncio/locks.py\", line 234, in __init__\r\n raise ValueError(\"loop argument must agree with lock\")\r\nValueError: loop argument must agree with lock\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-939074818", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 939074818, "node_id": "IC_kwDOBm6k_c43-SUC", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-08T19:40:23Z", "updated_at": "2021-10-08T19:40:23Z", "author_association": "OWNER", "body": "Then I created myself a temporary 3.10 environment using `pipenv` like so:\r\n\r\n cd /tmp\r\n mkdir py310\r\n cd py310\r\n pipenv shell --python /Users/simon/.pyenv/versions/3.10.0/bin/python\r\n\r\nAnd used that with my Datasette checkout like so:\r\n\r\n cd ~/.../datasette\r\n pip install -e '.[test]'\r\n pytest\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1481#issuecomment-938142436", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1481", "id": 938142436, "node_id": "IC_kwDOBm6k_c436urk", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-10-07T20:44:43Z", "updated_at": "2021-10-07T20:44:43Z", "author_association": "OWNER", "body": "The 3.10 tests failed a lot. Trying to run this locally:\r\n\r\n```\r\n/tmp % pyenv install 3.10\r\npython-build: definition not found: 3.10\r\n\r\nThe following versions contain `3.10' in the name:\r\n 3.10.0a6\r\n 3.10-dev\r\n miniconda-3.10.1\r\n miniconda3-3.10.1\r\n\r\nSee all available versions with `pyenv install --list'.\r\n\r\nIf the version you need is missing, try upgrading pyenv:\r\n\r\n brew update && brew upgrade pyenv\r\n```\r\nSo trying:\r\n\r\n brew update && brew upgrade pyenv\r\n\r\nThen did this:\r\n\r\n```\r\n/tmp % brew upgrade pyenv \r\n==> Upgrading 1 outdated package:\r\npyenv 1.2.24.1 -> 2.1.0\r\n```\r\nThis decided to upgrade everything by downloaded everything on the internet. Aah, Homebrew.\r\n\r\nBut it looks like I have `3.10.0` available to `pyenv` now.\r\n\r\n```\r\n/tmp % pyenv install 3.10.0\r\npython-build: use openssl@1.1 from homebrew\r\npython-build: use readline from homebrew\r\nDownloading Python-3.10.0.tar.xz...\r\n-> https://www.python.org/ftp/python/3.10.0/Python-3.10.0.tar.xz\r\nInstalling Python-3.10.0...\r\n...\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": 1020436713, "label": "Fix compatibility with Python 3.10"}, "performed_via_github_app": null}