Main function

def main():
    """Main function"""
    # **** For Pytest ****
    # We need to create MainWindow **here** to avoid passing pytest
    # options to Spyder
    if running_under_pytest():
        try:
            from unittest.mock import Mock
        except ImportError:
            from mock import Mock  # Python 2

        options = Mock()
        options.working_directory = None
        options.profile = False
        options.multithreaded = False
        options.new_instance = False
        options.project = None
        options.window_title = None
        options.opengl_implementation = None
        options.debug_info = None
        options.debug_output = None

        if CONF.get('main', 'opengl') != 'automatic':
            option = CONF.get('main', 'opengl')
            set_opengl_implementation(option)

        app = initialize()
        window = run_spyder(app, options, None)
        return window

    # **** Collect command line options ****
    # Note regarding Options:
    # It's important to collect options before monkey patching sys.exit,
    # otherwise, argparse won't be able to exit if --help option is passed
    options, args = get_options()

    # **** Set OpenGL implementation to use ****
    if options.opengl_implementation:
        option = options.opengl_implementation
        set_opengl_implementation(option)
    else:
        if CONF.get('main', 'opengl') != 'automatic':
            option = CONF.get('main', 'opengl')
            set_opengl_implementation(option)

    # **** Handle hide_console option ****
    if options.show_console:
        print("(Deprecated) --show console does nothing, now the default "
              " behavior is to show the console, use --hide-console if you "
              "want to hide it")

    if set_attached_console_visible is not None:
        set_attached_console_visible(not options.hide_console
                                     or options.reset_config_files
                                     or options.reset_to_defaults
                                     or options.optimize
                                     or bool(get_debug_level()))

    # **** Set debugging info ****
    setup_logging(options)

    # **** Create the application ****
    app = initialize()

    # **** Handle other options ****
    if options.reset_config_files:
        # <!> Remove all configuration files!
        reset_config_files()
        return
    elif options.reset_to_defaults:
        # Reset Spyder settings to defaults
        CONF.reset_to_defaults(save=True)
        return
    elif options.optimize:
        # Optimize the whole Spyder's source code directory
        import spyder
        programs.run_python_script(module="compileall",
                                   args=[spyder.__path__[0]], p_args=['-O'])
        return

    # **** Show crash dialog ****
    if CONF.get('main', 'crash', False) and not DEV:
        CONF.set('main', 'crash', False)
        if SPLASH is not None:
            SPLASH.hide()
        QMessageBox.information(
            None, "Spyder",
            "Spyder crashed during last session.<br><br>"
            "If Spyder does not start at all and <u>before submitting a "
            "bug report</u>, please try to reset settings to defaults by "
            "running Spyder with the command line option '--reset':<br>"
            "<span style=\'color: #555555\'><b>spyder --reset</b></span>"
            "<br><br>"
            "<span style=\'color: #ff5555\'><b>Warning:</b></span> "
            "this command will remove all your Spyder configuration files "
            "located in '%s').<br><br>"
            "If Spyder still fails to launch, you should consult our "
            "comprehensive <b><a href=\"%s\">Troubleshooting Guide</a></b>, "
            "which when followed carefully solves the vast majority of "
            "crashes; also, take "
            "the time to search for <a href=\"%s\">known bugs</a> or "
            "<a href=\"%s\">discussions</a> matching your situation before "
            "submitting a report to our <a href=\"%s\">issue tracker</a>. "
            "Your feedback will always be greatly appreciated."
            "" % (get_conf_path(), __trouble_url__, __project_url__,
                  __forum_url__, __project_url__))

    # **** Create main window ****
    mainwindow = None
    try:
        mainwindow = run_spyder(app, options, args)
    except FontError as fontError:
        QMessageBox.information(None, "Spyder",
                "Spyder was unable to load the <i>Spyder 3</i> "
                "icon theme. That's why it's going to fallback to the "
                "theme used in Spyder 2.<br><br>"
                "For that, please close this window and start Spyder again.")
        CONF.set('appearance', 'icon_theme', 'spyder 2')
    except BaseException:
        CONF.set('main', 'crash', True)
        import traceback
        traceback.print_exc(file=STDERR)
        traceback.print_exc(file=open('spyder_crash.log', 'w'))
    if mainwindow is None:
        # An exception occured
        if SPLASH is not None:
            SPLASH.hide()
        return

    ORIGINAL_SYS_EXIT()