ITADN

google-cloud-ndb: DeprecationWarning from the three-arg generator.throw() in tasklets

#18158Openskippdot 创建于 11 天前
type: bugpriority: p2
S
skippdotcommented
#### Environment details - API: `google-cloud-ndb` - OS type and version: macOS 15 (Darwin 25.5.0); also reproduced on Ubuntu CI - Python version: 3.12, 3.13, 3.14 — any version since 3.12 - `google-cloud-ndb` version: 2.5.1 #### Steps to reproduce `_advance_tasklet` throws exceptions into the wrapped generator using the three-argument form of `generator.throw()`, [deprecated in Python 3.12](https://docs.python.org/3/reference/expressions.html#generator.throw): https://github.com/googleapis/google-cloud-python/blob/main/packages/google-cloud-ndb/google/cloud/ndb/tasklets.py#L318 ```python if error: traceback = error.__traceback__ yielded = self.generator.throw(type(error), error, traceback) ``` Every exception that crosses a tasklet boundary emits a `DeprecationWarning`. Any suite that exercises error paths fills up with them — ours emits 34 from 8 tests, which drowns out warnings that actually matter. #### Code example Needs only `google-cloud-ndb` and the standard library — no Datastore connection: ```python import warnings from unittest import mock from google.cloud.ndb import context as context_module, tasklets @tasklets.tasklet def inner(): raise ValueError("boom") yield @tasklets.tasklet def outer(): yield inner() client = mock.Mock( project="testing", database=None, namespace=None, spec=("project", "database", "namespace"), ) with context_module.Context(client).use(): with warnings.catch_warnings(record=True) as caught: warnings.simplefilter("always") try: outer().result() except ValueError: pass for w in caught: print(f"{w.category.__name__}: {w.message}") ``` #### Stack trace ``` DeprecationWarning: the (type, exc, tb) signature of throw() is deprecated, use the single-arg signature instead. google/cloud/ndb/tasklets.py:318: yielded = self.generator.throw(type(error), error, traceback) ``` #### Suggested fix The single-argument form reads the traceback off the exception itself, so the local becomes redundant: ```python if error: yielded = self.generator.throw(error) ``` I applied exactly this against 2.5.1 and verified that: - the `DeprecationWarning` is gone - the exception still reaches the caller unchanged - `__traceback__` is still populated on the delivered exception - a 50-test suite that drives ndb through a Datastore stub still passes Right now this is only noise, but the Python docs say the old signature "may be removed in a future version" — once it is, every exception crossing a tasklet boundary would raise `TypeError` instead of propagating, so the fix is worth landing before that. Happy to open a PR if it helps.
0 条评论