Hello @nik684,
Welcome to the Maxon developers forum and its community, it is great to have you with us!
Getting Started
Before creating your next postings, we would recommend making yourself accustomed with our forum and support procedures. You did not do anything wrong, we point all new users to these rules.
- Forum Overview: Provides a broad overview of the fundamental structure and rules of this forum, such as the purpose of the different sub-forums or the fact that we will ban users who engage in hate speech or harassment.
- Support Procedures: Provides a more in detail overview of how we provide technical support for APIs here. This topic will tell you how to ask good questions and limits of our technical support.
- Forum Features: Provides an overview of the technical features of this forum, such as Markdown markup or file uploads.
It is strongly recommended to read the first two topics carefully, especially the section Support Procedures: How to Ask Questions.
About your First Question
This has to be one of the most thorough bug reports I have ever seen. Well done! Maybe tell your agent next time to make it a bit shorter, I have a not too long attention span 
Could the Python wrappers of TakeData.SetCurrentTake() release the GIL while the native call runs ?
You were right, CPyTakeData::SetCurrentTake was missing the GIL release and acquire around its takeData->SetCurrentTake(take) call as it is customary for methods that write something. I have just pushed a build to the build server which changes that. I will then try to run your script there once I have that build. And even when the fix does not resolve your issue, I will submit it anyway, as the GIL should be released by convention around that call I would say.
Is there a supported way for a Python plugin to block or pause viewport redraws for the duration of a set of scene changes?
No, there is unfortunately not. You are in a more or less curated threading environment in Python. The Python VM calls your code at specific points in time and you are more or less at its mercy. There are c4d.StopAllThreads and c4d.threading.GeThreadLock but using them is rarely a good idea. And some drawing threads might even ignore them.
Is calling TakeData.SetCurrentTake() from a GeDialog.Timer() or a GeUserArea mouse handler supported, or should it be deferred to some other context?
That is indeed the main question. You can look at the all new Scene Excecution manual which I wrote for 2027 to get a better understanding of this. In short, changing the active take of a loaded scene is a scene modification and therefore must be main thread bound. Timer and Mouse/Keyboard IO functions usually run on the MT, but I would add an explicit check to such functions just to me sure. So, on paper, this is fine.
Where I can see a bit an issue is with your INTERVAL_MS in the demo script you gave us, it is set to 50ms. Quoting the warning I once added to GetTimer:
"Depending on the speed of the computer, the operating system, the complexity of the dialog and the threads running in the background, there is no guarantee that event messages will occur on a regular basis. Using a value of 500 ms should be no problem but if using a value of 1 ms one might get events with the following time spaces: 3 ms, 76 ms, 15 ms, 19 ms, 67 ms…"
With 50ms you are dangerously close to saturating the event system. Although it might not look like it, SetCurrentTake is a VERY expensive call. Doing this every 50ms with all Python shenanigans in between is not great. You would be better served with a value such as 100 or even 250ms.
I am like 66% confident that the GIL release I added will fix your issue. But all that event and timer stuff could also throw a wrench into things. But I will cross that bridge once I have a build of my fix, and your code still freezes, as that is probably not fun to debug. You should take as a lesson here that writing takes is not cheap. It can entail a lot of data copying and scene traversal to bring the current scene into its new state.
I will post here an update once I have a final answer.
Cheers,
Ferdinand