__builtins__ thread-safe / __builtins__ as function?

2012-10-11 Thread Juergen Bartholomae
Hello.
I have quite a peculiar problem.

A little overview of our situation:
Our program enables our users to write their own python code (which they
use extensively).
Unfortunately, (due to us actually encouraging this in an earlier release
(!stupid!)) this meant that, in several cases, there are modules which use
__builtins__ as a kind of global dictionary, where various variables are
inserted, changed and read.

Now, currently we are updating our program from a single-threaded to a
multithreaded architecture.
-> Of course, this means that the same module can now run in several
threads at the same time, and, since __builtins__ is pretty much global in
the system, they all share the same __builtins__.

Unfortunately, the obvious solution (use something else instead of abusing
__builtins__) won't do, because, like I said, there are various existing
modules out there that we cannot control and which must continue to run as
expected.

One possible solution  is to somehow redirect every __builtins__ to a
function that returns a different __builtins__ dictionary for each thread
(such a function already exists).

MY QUESTION:
How can I redirect __builtins__ to a built-in function?
My first idea was using __getattr__, but this won't work for most modules,
because __getattr__ only works with classes, and the customer .py-files
might not have any.
This means the customer modules are simply objects of the class ,
which is of course an unchangeable metaclass. (so, no way to add any
methods here)
I could do it if there was any way to load .py-files as any other class
than , maybe as a subclass, but I do not know how this could be
done.

So, I am really at a loss here.
Any help would be greatly appreciated.

Regards,
Juergen Bartholomae
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: __builtins__ thread-safe / __builtins__ as function?

2012-10-14 Thread Juergen Bartholomae
>> One possible solution  is to somehow redirect every __builtins__ to a
>> function that returns a different __builtins__ dictionary for each thread
>> (such a function already exists).

>How exactly does the code reference it? If they're simply referring to
>the name __builtins__ at module level, you ought to be able to import
>the module, then assign some_module.__builtins__ to your thread-local
>object, then call code in it as normal.

>An interesting problem, and one where monkeypatching is, imho, justified.

>ChrisA

Hello, and thanks for your answer.
Unfortunately, replacing __builtins__ at import time won't do, because
external modules (that is, .py) get imported only once when they are
accessed by the first thread, which includes (of course) setting up of
__dict__ and __builtins__. When a second thread later accesses this
module, it has the same variables in __builtins__ that were added by
the same module in first thread
And if the second thread then changes the values, I can see these
same changes in the first thread.
-> The problem is that __builtins__ are global, not thread-safe.

The only solution I can see is therfor redirecting __builtins__ to a
function which returns a different dictionary for each thread, e.g.
by intercepting __builtins__-calls with __readattr__.
To do this, I would need my own class to define __readattr__ in
since (as far as I know) I can't define __readattr__ in a module,
and I can't change metaclass  of course.

I really don't know how to get around this problem...
-- 
http://mail.python.org/mailman/listinfo/python-list