-
-
Notifications
You must be signed in to change notification settings - Fork 82
Description
Worker fails to start if I do not provide a kwargs argument when initializing the PsycopgConnector in the App.
If I do provide a kwargs object, everything works fine.
This leads to the following runtime error:
TypeError: AsyncConnection.connect() argument after ** must be a mapping, not NoneType
It appears that kwargs ends up as None, which later gets expanded using **kwargs inside psycopg_connector.py, causing the crash.
I am not sure whether this is due to a breaking change in psycopg or in procrastinate but I thought it should be reported.
Proposed fix:
A simple fix in the PsycopgConnector constructor prevents the error:
File: psycopg_connector.py
Line: ~95
self._pool_args = kwargs if kwargs else {}
This ensures kwargs is always a mapping, avoiding the TypeError.
Version:
Python 3.13.5
"procrastinate>=3.6.0"
"psycopg[binary,pool]>=3.3.2"
Platform: Windows
Steps to reproduce:
import asyncio
import logging
import sys
from procrastinate import App, PsycopgConnector
logging.basicConfig(level=logging.DEBUG)
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
app = App(
connector=PsycopgConnector(
conninfo="postgresql://postgres:secret@127.0.0.1:5432/postgres",
),
)
app.run_worker()uv run run.py
Traceback:
❯ uv run ./run.py
WARNING:procrastinate.blueprints:App is instantiated in the main Python module (./run.py). See https://procrastinate.readthedocs.io/en/stable/discussions.html#top-level-app
INFO:procrastinate.blueprints:Adding tasks from blueprint
DEBUG:asyncio:Using selector: SelectSelector
DEBUG:procrastinate.app:All tasks imported
DEBUG:procrastinate.worker:Pruning stalled workers with old heartbeats
DEBUG:procrastinate.worker:Registered worker 21 in the database
INFO:procrastinate.worker.worker:Starting worker on all queues
WARNING:procrastinate.signals:Skipping signal handling, does not work on Windows
DEBUG:procrastinate.worker:Waiting for 10.0s before updating worker heartbeat
INFO:procrastinate.periodic:No periodic task found, periodic deferrer will not run.
DEBUG:procrastinate.worker:waiting for 5.0s before querying jobs to abort
ERROR:procrastinate.worker.worker:Side task listener failed with exception: psycopg.connection_async.AsyncConnection.connect() argument after ** must be a mapping, not NoneType, stopping worker
Traceback (most recent call last):
File "...\.venv\Lib\site-packages\procrastinate\manager.py", line 566, in listen_for_jobs
await self.connector.listen_notify(
...<2 lines>...
)
File "...\AppData\Roaming\uv\python\cpython-3.13.5-windows-x86_64-none\Lib\contextlib.py", line 101, in inner
return await func(*args, **kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "...\.venv\Lib\site-packages\procrastinate\psycopg_connector.py", line 258, in listen_notify
async with self._get_standalone_connection() as connection:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "...\AppData\Roaming\uv\python\cpython-3.13.5-windows-x86_64-none\Lib\contextlib.py", line 214, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "...\.venv\Lib\site-packages\procrastinate\psycopg_connector.py", line 245, in _get_standalone_connection
async with await self.pool.connection_class.connect(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
self.pool.conninfo, **self.pool.kwargs, autocommit=True
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
) as connection:
^
TypeError: psycopg.connection_async.AsyncConnection.connect() argument after ** must be a mapping, not NoneType
INFO:procrastinate.worker.worker:Stop requested
DEBUG:procrastinate.utils:Cancelled task deferrer
ERROR:procrastinate.utils:listener error: TypeError('psycopg.connection_async.AsyncConnection.connect() argument after ** must be a mapping, not NoneType')
Traceback (most recent call last):
File "...\.venv\Lib\site-packages\procrastinate\manager.py", line 566, in listen_for_jobs
await self.connector.listen_notify(
...<2 lines>...
)
File "...\AppData\Roaming\uv\python\cpython-3.13.5-windows-x86_64-none\Lib\contextlib.py", line 101, in inner
return await func(*args, **kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "...\.venv\Lib\site-packages\procrastinate\psycopg_connector.py", line 258, in listen_notify
async with self._get_standalone_connection() as connection:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "...\AppData\Roaming\uv\python\cpython-3.13.5-windows-x86_64-none\Lib\contextlib.py", line 214, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "...\.venv\Lib\site-packages\procrastinate\psycopg_connector.py", line 245, in _get_standalone_connection
async with await self.pool.connection_class.connect(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
self.pool.conninfo, **self.pool.kwargs, autocommit=True
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
) as connection:
^
TypeError: psycopg.connection_async.AsyncConnection.connect() argument after ** must be a mapping, not NoneType
DEBUG:procrastinate.worker:Unregistered finished worker 21 from the database
INFO:procrastinate.worker.worker:Stopped worker on all queues