Opened 3 weeks ago

Last modified 2 weeks 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: Accepted
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 (9)

comment:1 by Jacob Walls, 3 weeks ago

Cc: Simon Charette added

comment:2 by Jacob Walls, 3 weeks ago

Owner: set to Django Sprints
Status: new → assigned

comment:3 by Simon Charette, 3 weeks ago

Setting F.__iter__ = None seems like a good way to go about this but I think we should use isinstance(expr, Iterable) instead of the getattr / hasattr call?

​https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable

comment:4 by Jacob Walls, 3 weeks ago

Good call, TIL that isinstance'ing the simpler container ABCs will check method presence (and not just MRO)!

comment:5 by Simon Charette, 3 weeks ago

yeah __subclasshook__ is quite powerful!

comment:6 by Natalia Bidart, 3 weeks ago

Triage Stage: Unreviewed → Accepted

TIL about __subclasshook__! Thanks both.

comment:7 by Vaibhav Pant, 3 weeks ago

Owner: changed from Django Sprints to Vaibhav Pant

comment:8 by Tim Schilling, 2 weeks ago

Owner: changed from Vaibhav Pant to Django Sprints

@Vaibhav Pant please leave the Django Sprints tickets for sprints or other contribution events. Those are reserved for mentorship opportunities within the community. When re-assigning a ticket to yourself that's assigned to someone else, it should be unmodified for the last 6 months. If it's sooner than that, it can be acceptable to comment, politely asking if they are still working on the issue. Do not reassign it to yourself though until they respond.

in reply to:  8 comment:9 by Vaibhav Pant, 2 weeks ago

Hi Tim, thanks for explaining, and apologies for the mix-up. I wasn't aware of the guideline about Django Sprints tickets. I'll leave this one for the sprints and look for unassigned tickets instead.

Note: See TracTickets for help on using tickets.
Back to Top