I am writing a test automation framework for a GUI application and I wanted to use decorators as a way to catch pop-ups that are generated by methods within the class (for example login)
I have a _BaseWindow class that keeps track of the elements of the GUI that are in every window (eg: menu bar, popups), which is inherited by a MainWindow class. The MainWindow class keeps track of buttons on the main menu, as well the dialog generated when one of the buttons is clicked. For example, if you click the login button on the main menu, the login dialog is loaded.
class _BaseWindow(object):
    def __init__(self):
        self.window = "windowName"
        self.popup = None
    def _catch_popups(self, method):
        from functools import wraps
        @wraps(method)
        def wrapper(*args, **kwargs):
            # get a list of the open windows before the method is run
            before = getwindowlist()
            retval = method(*args, **kwargs)
            # get a list of the open windows after the method is run
            after = getwindowlist()
            for window in after:
                if window not in before:
                    self.popup = window
                    break
            return retval
        return wrapper
class MainWindow(_BaseWindow):
    def __init__(self):
        self.dialog = None
        self.logged_in = False
        # buttons
        self.login_button = "btnLogin"
        super(MainWindow, self).__init__()
    def click_login(self):
        if not self.dialog:
            mouseclick(self.window, self.login_button)
            self.dialog = LoginDialog()
class LoginDialog(_BaseWindow):
    def __init__(self):
        # buttons
        self.button_ok = "btnLoginOK"
        self.button_cancel = "btnLoginCancel"
        # text input
        self.input_username = "txtLoginUsername"
        self.input_password = "txtLoginPassword"
        super(LoginDialog, self).__init__()
    @MainWindow._catch_popups
    def perform_login(self, username, password):
        input_text(self.input_username, username)
        input_text(self.input_password, password)
        mouseclick(self.window, self.button_ok)
When I try to test this I get:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "objects/gui.py", line 185, in <module>
    class LoginDialog(_BaseWindow):
  File "objects/gui.py", line 236, in LoginDialog
    @MainWindow._catch_popups
TypeError: unbound method _catch_popups() must be called with 
MainWindow instance as first argument (got function instance instead)
When I try to specify the MainWindow instance as:
@MainWindow._catch_popups(self)
I get:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "objects/gui.py", line 185, in <module>
    class LoginDialog(_BaseWindow):
  File "objects/gui.py", line 236, in LoginDialog
    @MainWindow._catch_popups(self)
NameError: name 'self' is not defined
Any help in understanding this would be most appreciated.
 
     
    