@autocommit.setter
def autocommit(self, value: bool) -> None:
+ self._set_autocommit(value)
+
+ def _set_autocommit(self, value: bool) -> None:
+ # Base implementation, not thread safe
+ # subclasses must call it holding a lock
status = self.pgconn.transaction_status
if status != TransactionStatus.IDLE:
raise e.ProgrammingError(
- "can't change autocommit state: connection in"
+ "couldn't change autocommit state: connection in"
f" transaction status {TransactionStatus(status).name}"
)
self._autocommit = value
yield None # for the send who stopped us
return
+ def _set_autocommit(self, value: bool) -> None:
+ with self.lock:
+ super()._set_autocommit(value)
+
class AsyncConnection(BaseConnection):
"""
if (yield n):
yield None
return
+
+ def _set_autocommit(self, value: bool) -> None:
+ raise AttributeError(
+ "autocommit is read-only on async connections:"
+ " please use await connection.set_autocommit() instead."
+ " Note that you can pass an 'autocommit' value to 'connect()'"
+ " if it doesn't need to change during the connection's lifetime."
+ )
+
+ async def set_autocommit(self, value: bool) -> None:
+ async with self.lock:
+ super()._set_autocommit(value)
async def test_autocommit(aconn):
assert aconn.autocommit is False
- aconn.autocommit = True
+ with pytest.raises(TypeError):
+ aconn.autocommit = True
+ assert not aconn.autocommit
+
+ await aconn.set_autocommit(True)
assert aconn.autocommit
cur = aconn.cursor()
await cur.execute("select 1")
assert await cur.fetchone() == (1,)
assert aconn.pgconn.transaction_status == aconn.TransactionStatus.INTRANS
with pytest.raises(psycopg3.ProgrammingError):
- aconn.autocommit = True
+ await aconn.set_autocommit(True)
assert not aconn.autocommit
await cur.execute("meh")
assert aconn.pgconn.transaction_status == aconn.TransactionStatus.INERROR
with pytest.raises(psycopg3.ProgrammingError):
- aconn.autocommit = True
+ await aconn.set_autocommit(True)
assert not aconn.autocommit
await aconn.close()
assert aconn.pgconn.transaction_status == aconn.TransactionStatus.UNKNOWN
with pytest.raises(psycopg3.ProgrammingError):
- aconn.autocommit = True
+ await aconn.set_autocommit(True)
assert not aconn.autocommit
aconn.add_notify_handler(cb1)
aconn.add_notify_handler(lambda n: nots2.append(n))
- aconn.autocommit = True
+ await aconn.set_autocommit(True)
cur = aconn.cursor()
await cur.execute("listen foo")
await cur.execute("notify foo, 'n1'")