> > > The stack is created on line 760 with os.lstat and entries are appended > > > on lines 677 (os.rmdir), 679 (os.close) and 689 (os.lstat). > > > > > > 'func' is popped off the stack on line 651 and check in the following > > > lines. > > > > > > I can't see anywhere else where something else is put onto the stack or > > > an entry is replaced.
But the _rmtree_safe_fd() compares func to a *dynamically* resolved reference: os.lstat. If the reference to os changed (or os object was modified to have new reference at lstat) between the time os.lstat was added to the stack and the time of comparison, then comparison would've failed. To illustrate my idea: os.lstat = lambda x: x # thread 1 stack.append((os.lstat, ...)) # thread 1 os.lstat = lambda x: x # thread 2 func, *_ = stack.pop() # thread 1 assert func is os.lstat # thread 1 (failure!) The only question is: is it possible to modify os.lstat like that, and if so, how? Other alternatives include a malfunctioning "is" operator, malfunctioning module cache... all those are a lot less likely. -- https://mail.python.org/mailman/listinfo/python-list