dinao 2.2.0.dev182__tar.gz → 2.2.0.dev185__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {dinao-2.2.0.dev182/dinao.egg-info → dinao-2.2.0.dev185}/PKG-INFO +1 -1
  2. dinao-2.2.0.dev185/dinao/__version__.py +2 -0
  3. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/binding/binders/async_.py +21 -1
  4. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185/dinao.egg-info}/PKG-INFO +1 -1
  5. dinao-2.2.0.dev182/dinao/__version__.py +0 -2
  6. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/AUTHORS +0 -0
  7. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/LICENSE +0 -0
  8. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/README.md +0 -0
  9. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/__init__.py +0 -0
  10. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/__init__.py +0 -0
  11. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/base.py +0 -0
  12. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/errors.py +0 -0
  13. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/mariadb.py +0 -0
  14. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/mysql.py +0 -0
  15. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/postgres/__init__.py +0 -0
  16. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/postgres/asyncpg.py +0 -0
  17. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/postgres/base.py +0 -0
  18. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/postgres/psycopg2.py +0 -0
  19. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/postgres/psycopg3.py +0 -0
  20. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/sqlite/__init__.py +0 -0
  21. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/sqlite/aiosqlite.py +0 -0
  22. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/sqlite/base.py +0 -0
  23. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/backend/sqlite/stdlib.py +0 -0
  24. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/binding/__init__.py +0 -0
  25. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/binding/binders/__init__.py +0 -0
  26. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/binding/binders/base.py +0 -0
  27. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/binding/binders/sync.py +0 -0
  28. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/binding/errors.py +0 -0
  29. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/binding/mappers.py +0 -0
  30. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/binding/templating.py +0 -0
  31. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao/mung.py +0 -0
  32. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao.egg-info/SOURCES.txt +0 -0
  33. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao.egg-info/dependency_links.txt +0 -0
  34. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao.egg-info/requires.txt +0 -0
  35. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/dinao.egg-info/top_level.txt +0 -0
  36. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/pyproject.toml +0 -0
  37. {dinao-2.2.0.dev182 → dinao-2.2.0.dev185}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dinao
3
- Version: 2.2.0.dev182
3
+ Version: 2.2.0.dev185
4
4
  Summary: A simple database API
5
5
  Author-email: Jim Carreer <jim.carreer+dinao@gmail.com>
6
6
  License-Expression: ISC
@@ -0,0 +1,2 @@
1
+ # noqa: D100
2
+ __version__ = "2.2.0.dev185"
@@ -175,8 +175,11 @@ class AsyncFunctionBinder(FunctionBinderBase):
175
175
  await cnx.rollback()
176
176
  raise
177
177
  finally:
178
- await self.pool.release(cnx)
178
+ # Clear the context var before releasing so that a failed
179
+ # release (e.g. asyncpg resetting a dirty connection) cannot
180
+ # leave a stale reference that poisons subsequent operations.
179
181
  self._context_store.set(None)
182
+ await self.pool.release(cnx)
180
183
 
181
184
 
182
185
  class AsyncBoundQuery(BoundQueryBase):
@@ -240,17 +243,34 @@ class AsyncBoundGeneratingQuery(BoundGeneratingQueryBase):
240
243
  async def __call__(self, *args, **kwargs):
241
244
  """Execute the templated SQL as an async query with results.
242
245
 
246
+ Clears the binder's context var before each yield and restores
247
+ it after resuming. When a consumer breaks out of ``async for``,
248
+ Python does **not** immediately close the async generator; the
249
+ finalizer runs later as a separate task. Without this guard the
250
+ context var would still reference the generator's leased
251
+ connection, causing subsequent operations on the same task to
252
+ reuse it while the deferred finalizer concurrently tries to
253
+ roll back and release the same connection — triggering the
254
+ asyncpg "cannot perform operation: another operation is in
255
+ progress" error.
256
+
243
257
  :param args: the positional arguments of the bound / decorated function
244
258
  :param kwargs: the keyword arguments of the bound / decorated function
245
259
  """
246
260
  bound = self._sig.bind(*args, **kwargs)
247
261
  bound.apply_defaults()
248
262
  sql, values = self._sql_template.render(self._binder.mung_symbol, bound.arguments)
263
+ # True when this generator leased the connection (not reusing a transaction's)
264
+ owns_cnx = self._binder._context_store.get() is None
249
265
  async with self._binder.connection() as cnx:
250
266
  async with cnx.query(sql, values) as results:
251
267
  row = await results.fetchone()
252
268
  while row:
269
+ if owns_cnx:
270
+ self._binder._context_store.set(None)
253
271
  yield self._row_mapper(row, results.description)
272
+ if owns_cnx:
273
+ self._binder._context_store.set(cnx)
254
274
  row = await results.fetchone()
255
275
 
256
276
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dinao
3
- Version: 2.2.0.dev182
3
+ Version: 2.2.0.dev185
4
4
  Summary: A simple database API
5
5
  Author-email: Jim Carreer <jim.carreer+dinao@gmail.com>
6
6
  License-Expression: ISC
@@ -1,2 +0,0 @@
1
- # noqa: D100
2
- __version__ = "2.2.0.dev182"
File without changes
File without changes
File without changes
File without changes
File without changes