0

Okay, I've been doing some tests, so I need to check the result every time I run a method. Because the test doesn't work properly.

I've made an example that works fine(not a test, but same behavior). In my test the result doesn't change, while in the example it changes.

EXAMPLE

def thread():

    global result
    import time
    time.sleep(0.5)
    result = 5/2
    Gtk.main_quit()


import threading
from gi.repository import Gtk
result = None
t = threading.Thread(target=thread, args=())
t.start()
Gtk.main()
print result

OUTPUT: 2

TEST

def testSi_Button_clicked(self):

        def thread(button=self.builder.get_object('Si_Button')):

            import time
            global result
            time.sleep(0.5)
            result = self.esci.Si_Button_clicked(button)
            print 'result ' + str(result)
            #Gtk.main_quit()


        import threading

        self.current_window = 'Home_Window' #DO NOT TRY WITH 'Azioni_Window'
        result = None
        t = threading.Thread(target=thread, args=())
        t.start()
        Gtk.main()
        print 'assert'
        print 'result ' + str(result)
        self.assertIsNotNone(result)

OUTPUT:
Home_Window
return true
result True
assert
result None
F
======================================================================
FAIL: testSi_Button_clicked (testC_Esci.tstEsci)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "testC_Esci.py", line 78, in testSi_Button_clicked
    self.assertIsNotNone(result)
AssertionError: unexpectedly None
FrancescoN
  • 2,146
  • 12
  • 34
  • 45

1 Answers1

0

In thread, global result refers to a module-level variable named result in the module where testSi_Button_clicked (or rather, the class that defines testSi_Button_clicked) is defined. It does not refer to the local variable of the same name that you define in testSi_Button_clicked.

To fix, make result a mutable object (such as a dict), drop the global result statement, and let thread be a closure over result. (In Python 3, you can use the nonlocal keyword to avoid this kind of wrapper trickery.)

def testSi_Button_clicked(self):

        def thread(button=self.builder.get_object('Si_Button')):
            import time
            time.sleep(0.5)
            result['result'] = self.esci.Si_Button_clicked(button)
            print 'result ' + str(result['result'])
            #Gtk.main_quit()


        import threading

        self.current_window = 'Home_Window' #DO NOT TRY WITH 'Azioni_Window'
        result = {'result': None}
        t = threading.Thread(target=thread, args=())
        t.start()
        Gtk.main()
        print 'assert'
        print 'result ' + str(result['result'])
        self.assertIsNotNone(result['result'])
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Ok I'll talk about the example. I've already tried that.. but cutting off _global result_ result will be None. And before this change the result was correct (2). The test after this change still doesn't work – FrancescoN Apr 23 '15 at 18:48
  • 1
    Sorry, I confused myself while writing this. Dropping the `global` will use the correct `result`, until you try to assign to it, at which point you are assigning to a local variable. I meant to make some mention of Python 3's `nonlocal`, which I think would be correct here (if you aren't using Python 2, anyway.) – chepner Apr 23 '15 at 18:52
  • Ok so by using 2.7 there is no chance.. I can't believe – FrancescoN Apr 23 '15 at 19:08
  • 1
    A workaround is to use something like `result_dict = {'result': None}` and pass `result_dict` as an argument to `thread`, and update the value in the dictionary. – chepner Apr 23 '15 at 19:10
  • It is very similar to something like "passing parameters by reference". So I have to use a mutable object and not changing the reference – FrancescoN Apr 23 '15 at 19:23
  • 1
    Exactly. Although come to think of it, once `result` is a mutable object, you can go back my original answer, because you'll never be assigning to `result`, just accessing the object it references. – chepner Apr 23 '15 at 19:36