On 09/12/2018 05:17 AM, Steven D'Aprano wrote: > Indeed. Each time you call locals(), it returns a new dict with a
snapshot of the current local namespace. Because it all happens inside the same function call, no external thread can poke inside your current call to mess with your local variables.But that's different from setting function.__params__ to passed in arguments. By definition, each external caller is passing in its own set of arguments. If you have three calls to the function: function(a=1, b=2) # called by A function(a=5, b=8) # called by B function(a=3, b=4) # called by C In single-threaded code, there's no problem here: A makes the first call; the interpreter sets function.__params__ to A's arguments; the function runs with A's arguments and returns; only then can B make its call; the interpreter sets function.__params__ to B's arguments; the function runs with B's arguments and returns; only then can C make its call; the interpreter sets function.__params__ to C's arguments; the function runs with C's arguments and returns but in multi-threaded code, unless there's some form of locking, the three sets can interleave in any unpredictable order, e.g.: A makes its call; B makes its call; the interpreter sets function.__params__ to B's arguments; the interpreter sets function.__params__ to A's arguments; the function runs with B's arguments and returns; C make its call; the interpreter sets function.__params__ to C's arguments; the function runs with A's arguments and returns; the function runs with C's arguments and returns. We could solve this race condition with locking, or by making the pair of steps: the interpreter sets function.__params__ the function runs and returns a single atomic step. But that introduces a deadlock: once A calls function(), threads B and C will pause (potentially for a very long time) waiting for A's call to complete, before they can call the same function. I'm not an expert on threaded code, so it is possible I've missed some non-obvious fix for this, but I expect not. In general, solving race conditions without deadlocks is a hard problem.
I believe the solution is `threading.local()`, and Python would automatically use it in these situations.
-- ~Ethan~ _______________________________________________ Python-ideas mailing list [email protected] https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
