On 2018-05-15 18:36, Petr Viktorin wrote:
> What is your ultimate use case?
(I'll just answer this one question now and reply to the more technical
comments in another thread)
My ultimate use case is being able to implement functions and methods
(A) equally fast as the existing built-in function and methods
(B) and behave from a user's point of view like Python functions.
With objective (A) I want no compromises. CPython has many optimizations
for built-in functions and all of them should work for my new functions.
Objective (B) means more precisely:
1. Implementing __get__ to turn a function in a method.
2. Being recognized as "functions" by tools like Sphinx and IPython.
3. Introspection support such as inspect.signature() and
Hope this is an appropriate list to send this message to; if not,
please redirect me.
I am working on updating, fixing, or otherwise changing python's
configure.ac. This work is complex, lacks dedicated unit tests, and is
easy to miss corner cases. As these changes make it into master I'll
be watching the various build bots and be on the look out for related
failures. That said, I will miss things. Please feel free to tag me in
related PRs or bugs or emails over the next few weeks.
Subj is off topic for the ticket, so I guess this discussion is better
On 15.05.2018 18:20, Mark Roseman wrote:
> Mark Roseman <mark(a)markroseman.com> added the comment:
> Hi Ivan, thanks for your detailed response. The approach you're suggesting ("Since the sole offender is their threading model, the way is to show them how it's defective and work towards improving it.") is in the end not something I think is workable.
> Some historical context. Ousterhout had some specific ideas about how Tcl/Tk should be used, and that was well-reflected in his early control of the code base. He was certainly outspoken against threads. The main argument is that they're complicated if you don't know what you're doing, which included the "non-professional programmers" he considered the core audience. Enumerating how threads were used at the time, most of the uses could be handled (more simply) in other ways, such as event-driven and non-blocking timers and I/O (so what people today would refer to as the "node.js event model"). Threads (or separate communicating processes) were for long-running computations, things he always envisioned happening in C code (written by more "professional programmers"), not Tcl. His idea of how Tcl and C development would be split didn't match reality given faster machines, more memory, etc.
Very enlightening. Many thanks.
> The second thing is that Tcl had multiple interpreters baked in pretty much from the beginning at the C level and exposed fairly early on (1996?) at the Tcl level, akin to PEP 554. Code isolation and resource management were the key motivators, but of course others followed. Creating and using Tcl interpreters was quick, lightweight (fast startup, low memory overhead, etc.) and easy. So in other words, the notion of multiple interpreters in Tcl vs. Python is completely different. I had one large application I built around that time that often ended up with hundreds of interpreters running.
Not familiar with the concept so can't say atm if tkinter can make any
use of this. All tkinter-using code I've seen so far only ever uses a
single tkinter.Tk() -- thus a single interpreter.
> Which brings me to threads and how they were added to the language. Your guess ("My guess for the decision is it was the easiest way to migrate the code base") is incorrect. The idea of "one thread/one interpreter" was just not seen as a restriction, and was a very natural extension of what had come before. It fit the use cases well (AOLserver was another good example) and was still very understandable from the user level. Contrast with Python's GIL, etc.
I'm not actually suggesting any changes to Tcl as a language, only to
its C interface (details follow).
AFAIK Tcl also advertises itself as an embeddable language as its main
selling point, having been developed primarity as an interface to Tk
rather than a self-sufficient language (or, equivalently, this being its
primary use case now). Having to do an elaborate setup with lots of
custom logic to be able to embed it is a major roadblock. This can be
From C interface's standpoint, an interpreter is effectively a bunch of
data that can be passed to APIs. Currently, all Tcl_* calls with a
specific interpreter instance must be made from the same thread, and
this fact enforces sequential access. I'm suggesting to wrap all these
public APIs with an interpreter-specific lock -- so calls can be made
from any OS thread and the lock enforces sequential access. For Tcl's
execution model and existing code, nothing will change.
The downside (that will definitely be brought up) is the overhead, of
course. The question is thus whether the above-mentioned benefit
> With that all said, there would be very little motivation to change the Tcl/Tk side to allow multiple threads to access one interpreter, because in terms of the API and programming model that Tcl/Tk advertises, it's simply not a problem. Keep in mind, the people working on the Tcl/Tk core are very smart programmers, know threads very well, etc., so it's not an issue of "they should know better" or "it's old." In other words, "show them how it's defective" is a non-starter.
> The other, more practical matter in pushing for changes in the Tcl/Tk core, is that there are a fairly small number of people working on it, very part-time. Almost all of them are most interested in the Tcl side, not Tk. Changes made in Tk most often amount to bug fixes because someone's running into something in their own work. Expecting large-scale changes to happen to Tk without some way to get dedicated new resources put into it is not realistic.
> A final matter on the practical side. As you've carefully noted, certain Tcl/Tk calls now happen to work when called from different threads. Consider those a side-effect of present implementation, not a guarantee. Future core changes could change what can be called from different threads, making the situation better or worse. From the Tcl/Tk perspective, this is not a problem, and would not be caught by any testing, etc. Even if it were, it likely wouldn't be fixed. It would be considered an "abuse" of their API (I think correctly).
> My suggestion, given the philosophical and practical mismatch, is that Tkinter move towards operating as if the API Tk provides is inviolate. In other words, all calls into a Tcl interpreter happen from the same thread that created the Tcl interpreter. Tkinter acts as a bridge between Python and Tcl/Tk. It should present an API to Python programs compatible with the Python threading model. It's Tkinter's responsibility to map that onto Tcl/Tk's single threaded API through whatever internal mechanism is necessary (i.e. pass everything to main thread, block caller thread until get response, etc.)
That's exactly what Tkinter currently does, see the letter attached to
the ticket. Writing clean and correct code is Python's principal
standpoint, it doesn't use unsupported functions.
> I'd go so far as to suggest that all the Tkapp 'call' code (i.e. every place that Tkinter calls Tcl_Eval) check what thread it's in, and issue a warning or error (at least for testing purposes) if it's being called from the "wrong" thread. Having this available in the near future would help people who are debugging what are fairly inexplicable problems now.
> The approach of making Tkinter responsible also has the advantage of dealing with far more Tcl/Tk versions and builds.
> Given in practice that few people are really running into things, and that if they are, they know enough to be able to follow the instruction "all Tkinter calls from the same thread" for now, add the warnings/errors in via whatever "turn on debugging" mechanism makes sense. A future version of Python would include a fully thread-safe Tkinter that internally makes all Tcl/Tk calls from a single thread, as per above.
> Sorry this is so incredibly long-winded. I hope the context at least is useful information.
> Python tracker <report(a)bugs.python.org>
On 2018-05-14 22:38, Petr Viktorin wrote:
> Why are these flags added?
> They aren't free – the space of available flags is not infinite. If
> something (Cython?) needs eight of them, it would be nice to mention the
> use case, at least as an example.
> What should Python do with a m_methods entry that has METH_CUSTOM set?
> Again it would be nice to have an example or use case.
They have no specific use case. I just added this because it made sense
abstractly. I can remove this from my PEP to simplify it.
I have updated PEP 575 in response to some posts on this mailing list
and to some discussions in person with the core Cython developers.
The main differences with respect to the previous version are:
* "builtin_function" was renamed to "cfunction". Since we are changing
the name anyway, "cfunction" looked like a better choice because the
word "built-in" typically refers to things from the builtins module.
* defined_function now only defines an API (it must support all
attributes that a Python function has) without specifying the
* The "Two-phase Implementation" proposal for better backwards
compatibility has been expanded and now offers 100% backwards
compatibility for the classes and for the inspect functions.
The bottom line is: Tkinter is currently broken -- as in, it's not
thread-safe (in both Py2 and Py3) despite being designed and advertizing
itself as such.
All the fix options require some redesign of either `_tkinter', or some
of the core as well.
So, I'd like to get some kind of core team's feedback and/or approval
before pursuing any of them.
The options are outlined in https://bugs.python.org/issue33257#msg316087 .
If anyone of you is in Moscow, we can meet up and discuss this in a more