Opened 73 minutes ago
Last modified 64 minutes ago
#37384 assigned Bug
Iterating F("pk") can hang
| Reported by: | Jacob Walls | Owned by: | Django Sprints |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 5.2 |
| Severity: | Normal | Keywords: | |
| Cc: | Simon Charette | Triage Stage: | Unreviewed |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
#35603 solved one of the two scenarios that could lead to an infinite hang when F() expressions fall back to "old-style" iteration protocols via __getitem__(). It solved it for containment checks by throwing from __contains__. It didn't solve it for iteration, so we encountered an infinite hang in #37291.
When reviewing the fix for #37291, I began to suggest addressing the root cause by throwing an error from F.__iter__() until I realized that it would change the return value of hasattr(expr, "__iter__"). We have several uses in core like that.
What we should do, I think, is set F.__iter__ = None, and then update core (and add release notes) that code should update from:
if hasattr(expr, "__iter__"):
to:
if getattr(expr, "__iter__", None):
...so that the pythonic way of declaring no-iteration can be read statically.
Change History (3)
comment:1 by , 73 minutes ago
| Cc: | added |
|---|
comment:2 by , 72 minutes ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
Setting
F.__iter__ = Noneseems like a good way to go about this but I think we should useisinstance(expr, Iterable)instead of thegetattr/hasattrcall?https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable