classification
Title: I need to import the module in the same thread
Type: behavior Stage:
Components: None, Library (Lib) Versions: Python 2.5
process
Status: closed Resolution: works for me
Dependencies: Superseder:
Assigned To: Nosy List: amaury.forgeotdarc, tyoc
Priority: normal Keywords:

Created on 2009-05-02 19:49 by tyoc, last changed 2009-05-09 14:10 by amaury.forgeotdarc. This issue is now closed.

Messages (3)
msg86975 - (view) Author: (tyoc) Date: 2009-05-02 19:49
Hi there, my problem is the following I dont know if this is a python 
error, spected behaviour or what, so here I go.

I'm using pyatspi in a console application for retrieve focus events
(you need to enable accessibility if want to check... that is at-spi-
registryd in 'top'):


Example 1: works correctly (focus events printed to stdout).
NOTE: See that the import is inside of 'run' and all the calls to the 
module are inside this thread.
FREEZE: No, correct behaviour.

[code start]--------------------------------------------
def cb(eve):
    print eve

import threading
class THRE4D(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        import pyatspi
        print 'spot 0'
        pyatspi.Registry.registerEventListener(cb, 'focus')
        import gobject
        print 'spot 1'
        gobject.timeout_add(5000, pyatspi.Registry.stop)
        print 'spot 2'
        pyatspi.Registry.start()
        print 'spot 3'

t = THRE4D()
t.start()
t.join(15000)
print 'joined'
[code end]--------------------------------------------

Example 2: it prints the first event and freeze quit because the 
timeout_add.
NOTE:See that I have moved the import and the register to __init__ the 
loop is in the new thread.
FREEZE: Yes. Print first event, dont know where it freeze (function), 
but has passed 'registerEventListener' and it has entered 
'Registry.start()'.

[code start]--------------------------------------------
def cb(eve):
    print eve

import threading
class THRE4D(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        import pyatspi
        pyatspi.Registry.registerEventListener(cb, 'focus')
    def run(self):
        import pyatspi
        print 'spot 0'
        import gobject
        print 'spot 1'
        gobject.timeout_add(5000, pyatspi.Registry.stop)
        print 'spot 2'
        pyatspi.Registry.start()
        print 'spot 3'

t = THRE4D()
t.start()
t.join(15000)
print 'joined'
[code end]--------------------------------------------

Example 3: It does not print any event at all and it freezes. It only 
prints 'spot 0'. The freeze is hard even that timeout_add doest end it 
in the time.
NOTE: See that I have only imported pyatspi in '__init__' all the calls 
are inside the thread.
FREEZE: Yes. No print of events, freeze inside inside 'accessible.py of 
pyatspi' in '_inner' where 'try: return func(self, *args, **kwargs)'.

[code start]--------------------------------------------
def cb(eve):
    print eve

import threading
class THRE4D(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        import pyatspi
    def run(self):
        import pyatspi
        print 'spot 0'
        pyatspi.Registry.registerEventListener(cb, 'focus')
        import gobject
        print 'spot 1'
        gobject.timeout_add(5000, pyatspi.Registry.stop)
        print 'spot 2'
        pyatspi.Registry.start()
        print 'spot 3'

t = THRE4D()
t.start()
t.join(15000)
print 'joined'
[code end]--------------------------------------------



actual conclusions

 * I dont know why importing it 2 times (pyatspi) in different context 
of threads launch this problem.

 * for a 'quick' solution: The import and the calls should be in the 
same thread "specially" 'registerEventListener'.
msg86993 - (view) Author: (tyoc) Date: 2009-05-03 01:20
OK, here is a resume of the anterior.

I see clearly that it matter where I import the library (dont know if 
is a problem of the library or python). This time the thread doesnt 
end, will end when you hit CTRL+C in the terminal, for test this you 
need enabled accessibility.

Steps

1) run the code as is and see that it prints spot 0, 1 end is not wrote
2) uncomment the line of import pyatspi # import in the main thread and 
run again, see that it only print 0, it app is stuck inside 
pyatspi.Registry.registerEventListener(cb, 'focus')


[code start]---------------------------
import threading 
class thr(threading.Thread): 
    def __init__(self): 
        threading.Thread.__init__(self) 
#        import pyatspi # import in the main thread 
    def run(self): 
        def cb(eve): 
            print eve 
        import pyatspi # import here in the new thread 
        print 'spot 0' 
        pyatspi.Registry.registerEventListener(cb, 'focus') 
        print 'spot 1'
        pyatspi.Registry.start() 
        print 'End' 
  
t = thr() 
t.start() 
t.join() 
[code end]---------------------------



So at less for this library, it matter where you import the thing.
msg87498 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2009-05-09 14:10
With python, the first "import" of a library runs its initialization
code. Subsequent imports only retrieves the module object from the memory.

> for this library, it matter where you import the thing.

More precisely: it matters where you *first* import the thing. the
pyatspi import function probably runs some code that depends on the
running thread.
This is a common issue for event-driven libraries, often resolved by
splitting the initialization into two phases, the "import" phase and an
"init" function that performs thread-sensitive things.
You should forward your problem to the pyatspi team.

Since your first example works correctly, I close this issue as "works
for me".
History
Date User Action Args
2009-05-09 14:10:11amaury.forgeotdarcsetstatus: open -> closed

nosy: + amaury.forgeotdarc
messages: + msg87498

resolution: works for me
2009-05-03 07:36:39tyocsettitle: I need to import the module in the same thread? -> I need to import the module in the same thread
2009-05-03 01:20:51tyocsetmessages: + msg86993
2009-05-02 19:49:55tyoccreate