{"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}