On Thu, Feb 6, 2014 at 2:37 PM, Antony Lee firstname.lastname@example.org wrote:
The recent discussion about lexical vs. dynamic scoping reminded me of the following issue, that plagues e.g. the new contextlib.redirect_stdout context manager: the standard file-like objects sys.std* are global instead of thread-local, making their manipulation unsafe in multithreaded programs (this issue is related to lexical vs dynamic scoping because in a language with (optional) dynamic scoping, these objects can be made dynamically scoped, thus solving the issue).
How much of a problem is this in practice? What's your specific use case? I can't say that's I've ever had such a need, but then I haven't used contextlib.redirect_stdout() in a multi-threaded context. At that point I'd probably opt for using Python's logging system rather than sys.std*.
Of course, changing sys.std* to being thread-local would be backwards incompatible, but perhaps some new objects, e.g. sys.thread_local_std*, could be added to sys, with print() and related functions using sys.thread_local_std* if it is set and sys.std* otherwise.
Regardless of the validity of the proposal, coming up with an API to support thread-local sys.std* should be doable in a backward-compatible way, as you imply. It's just a question of how much complexity we can justify in the underlying implementation and in changes to sys.std* (if any).
FYI, for 3.5 I plan on working on two things related to your proposal:
* restructuring the sys module (or something like it); * adding an API for managing thread-local contexts (a la decimal).
That's not to say that either will find enough support to actually land, but I will be working on them. :)