# Buggy code
def enable_dev_tools(
    self,
    debug=None,
    dev_tools_ui=None,
    dev_tools_props_check=None,
    dev_tools_serve_dev_bundles=None,
    dev_tools_hot_reload=None,
    dev_tools_hot_reload_interval=None,
    dev_tools_hot_reload_watch_interval=None,
    dev_tools_hot_reload_max_retry=None,
    dev_tools_silence_routes_logging=None,
    dev_tools_prune_errors=None,
):
    """Activate the dev tools, called by `run_server`. If your application
    is served by wsgi and you want to activate the dev tools, you can call
    this method out of `__main__`.

    All parameters can be set by environment variables as listed.
    Values provided here take precedence over environment variables.

    Available dev_tools environment variables:

        - DASH_DEBUG
        - DASH_UI
        - DASH_PROPS_CHECK
        - DASH_SERVE_DEV_BUNDLES
        - DASH_HOT_RELOAD
        - DASH_HOT_RELOAD_INTERVAL
        - DASH_HOT_RELOAD_WATCH_INTERVAL
        - DASH_HOT_RELOAD_MAX_RETRY
        - DASH_SILENCE_ROUTES_LOGGING
        - DASH_PRUNE_ERRORS

    :param debug: Enable/disable all the dev tools unless overridden by the
        arguments or environment variables. Default is ``True`` when
        ``enable_dev_tools`` is called directly, and ``False`` when called
        via ``run_server``. env: ``DASH_DEBUG``
    :type debug: bool

    :param dev_tools_ui: Show the dev tools UI. env: ``DASH_UI``
    :type dev_tools_ui: bool

    :param dev_tools_props_check: Validate the types and values of Dash
        component props. env: ``DASH_PROPS_CHECK``
    :type dev_tools_props_check: bool

    :param dev_tools_serve_dev_bundles: Serve the dev bundles. Production
        bundles do not necessarily include all the dev tools code.
        env: ``DASH_SERVE_DEV_BUNDLES``
    :type dev_tools_serve_dev_bundles: bool

    :param dev_tools_hot_reload: Activate hot reloading when app, assets,
        and component files change. env: ``DASH_HOT_RELOAD``
    :type dev_tools_hot_reload: bool

    :param dev_tools_hot_reload_interval: Interval in seconds for the
        client to request the reload hash. Default 3.
        env: ``DASH_HOT_RELOAD_INTERVAL``
    :type dev_tools_hot_reload_interval: float

    :param dev_tools_hot_reload_watch_interval: Interval in seconds for the
        server to check asset and component folders for changes.
        Default 0.5. env: ``DASH_HOT_RELOAD_WATCH_INTERVAL``
    :type dev_tools_hot_reload_watch_interval: float

    :param dev_tools_hot_reload_max_retry: Maximum number of failed reload
        hash requests before failing and displaying a pop up. Default 8.
        env: ``DASH_HOT_RELOAD_MAX_RETRY``
    :type dev_tools_hot_reload_max_retry: int

    :param dev_tools_silence_routes_logging: Silence the `werkzeug` logger,
        will remove all routes logging. Enabled with debugging by default
        because hot reload hash checks generate a lot of requests.
        env: ``DASH_SILENCE_ROUTES_LOGGING``
    :type dev_tools_silence_routes_logging: bool

    :param dev_tools_prune_errors: Reduce tracebacks to just user code,
        stripping out Flask and Dash pieces. Only available with debugging.
        `True` by default, set to `False` to see the complete traceback.
        env: ``DASH_PRUNE_ERRORS``
    :type dev_tools_prune_errors: bool

    :return: debug
    """
    if debug is None:
        debug = get_combined_config("debug", None, True)

    dev_tools = self._setup_dev_tools(
        debug=debug,
        ui=dev_tools_ui,
        props_check=dev_tools_props_check,
        serve_dev_bundles=dev_tools_serve_dev_bundles,
        hot_reload=dev_tools_hot_reload,
        hot_reload_interval=dev_tools_hot_reload_interval,
        hot_reload_watch_interval=dev_tools_hot_reload_watch_interval,
        hot_reload_max_retry=dev_tools_hot_reload_max_retry,
        silence_routes_logging=dev_tools_silence_routes_logging,
        prune_errors=dev_tools_prune_errors,
    )

    if dev_tools.silence_routes_logging:
        logging.getLogger("werkzeug").setLevel(logging.ERROR)
        self.logger.setLevel(logging.INFO)

    if dev_tools.hot_reload:
        _reload = self._hot_reload
        _reload.hash = generate_hash()

        component_packages_dist = [
            os.path.dirname(package.path)
            if hasattr(package, "path")
            else package.filename
            for package in (
                pkgutil.find_loader(x)
                for x in list(ComponentRegistry.registry) + ["dash_renderer"]
            )
        ]

        _reload.watch_thread = threading.Thread(
            target=lambda: _watch.watch(
                [self.config.assets_folder] + component_packages_dist,
                self._on_assets_change,
                sleep_time=dev_tools.hot_reload_watch_interval,
            )
        )
        _reload.watch_thread.daemon = True
        _reload.watch_thread.start()

    if debug and dev_tools.prune_errors:

        @self.server.errorhandler(Exception)
        def _wrap_errors(_):
            # find the callback invocation, if the error is from a callback
            # and skip the traceback up to that point
            # if the error didn't come from inside a callback, we won't
            # skip anything.
            tb = get_current_traceback()
            skip = 0
            for i, line in enumerate(tb.plaintext.splitlines()):
                if "%% callback invoked %%" in line:
                    skip = int((i + 1) / 2)
                    break
            return get_current_traceback(skip=skip).render_full(), 500

    if debug and dev_tools.serve_dev_bundles and not self.scripts.config.serve_locally:
        # Dev bundles only works locally.
        self.scripts.config.serve_locally = True
        print(
            "WARNING: dev bundles requested with serve_locally=False.\n"
            "This is not supported, switching to serve_locally=True"
        )

    return debug


# Traceback (ValueError)
Traceback (most recent call last):
File "C:\Users\gioxc\AppData\Local\Programs\Python\Python37\lib\pkgutil.py", line 493, in find_loader
spec = importlib.util.find_spec(fullname)
File "C:\Users\gioxc\AppData\Local\Programs\Python\Python37\lib\importlib\util.py", line 114, in find_spec
raise ValueError('{}.__spec__ is None'.format(name))
ValueError: __main__.__spec__ is None

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "apptest.py", line 108, in <module>
app.run_server(debug=True)
File "C:\Users\gioxc\AppData\Local\Programs\Python\Python37\lib\site-packages\dash\dash.py", line 1475, in run_server
dev_tools_prune_errors,
File "C:\Users\gioxc\AppData\Local\Programs\Python\Python37\lib\site-packages\dash\dash.py", line 1282, in enable_dev_tools
for x in list(ComponentRegistry.registry) + ["dash_renderer"]
File "C:\Users\gioxc\AppData\Local\Programs\Python\Python37\lib\site-packages\dash\dash.py", line 1277, in <listcomp>
os.path.dirname(package.path)
File "C:\Users\gioxc\AppData\Local\Programs\Python\Python37\lib\site-packages\dash\dash.py", line 1282, in <genexpr>
for x in list(ComponentRegistry.registry) + ["dash_renderer"]
File "C:\Users\gioxc\AppData\Local\Programs\Python\Python37\lib\pkgutil.py", line 499, in find_loader
raise ImportError(msg.format(fullname, type(ex), ex)) from ex
ImportError: Error while finding loader for '__main__' (<class 'ValueError'>: __main__.__spec__ is None)

# Fixed code
def enable_dev_tools(
    self,
    debug=None,
    dev_tools_ui=None,
    dev_tools_props_check=None,
    dev_tools_serve_dev_bundles=None,
    dev_tools_hot_reload=None,
    dev_tools_hot_reload_interval=None,
    dev_tools_hot_reload_watch_interval=None,
    dev_tools_hot_reload_max_retry=None,
    dev_tools_silence_routes_logging=None,
    dev_tools_prune_errors=None,
):
    """Activate the dev tools, called by `run_server`. If your application
    is served by wsgi and you want to activate the dev tools, you can call
    this method out of `__main__`.

    All parameters can be set by environment variables as listed.
    Values provided here take precedence over environment variables.

    Available dev_tools environment variables:

        - DASH_DEBUG
        - DASH_UI
        - DASH_PROPS_CHECK
        - DASH_SERVE_DEV_BUNDLES
        - DASH_HOT_RELOAD
        - DASH_HOT_RELOAD_INTERVAL
        - DASH_HOT_RELOAD_WATCH_INTERVAL
        - DASH_HOT_RELOAD_MAX_RETRY
        - DASH_SILENCE_ROUTES_LOGGING
        - DASH_PRUNE_ERRORS

    :param debug: Enable/disable all the dev tools unless overridden by the
        arguments or environment variables. Default is ``True`` when
        ``enable_dev_tools`` is called directly, and ``False`` when called
        via ``run_server``. env: ``DASH_DEBUG``
    :type debug: bool

    :param dev_tools_ui: Show the dev tools UI. env: ``DASH_UI``
    :type dev_tools_ui: bool

    :param dev_tools_props_check: Validate the types and values of Dash
        component props. env: ``DASH_PROPS_CHECK``
    :type dev_tools_props_check: bool

    :param dev_tools_serve_dev_bundles: Serve the dev bundles. Production
        bundles do not necessarily include all the dev tools code.
        env: ``DASH_SERVE_DEV_BUNDLES``
    :type dev_tools_serve_dev_bundles: bool

    :param dev_tools_hot_reload: Activate hot reloading when app, assets,
        and component files change. env: ``DASH_HOT_RELOAD``
    :type dev_tools_hot_reload: bool

    :param dev_tools_hot_reload_interval: Interval in seconds for the
        client to request the reload hash. Default 3.
        env: ``DASH_HOT_RELOAD_INTERVAL``
    :type dev_tools_hot_reload_interval: float

    :param dev_tools_hot_reload_watch_interval: Interval in seconds for the
        server to check asset and component folders for changes.
        Default 0.5. env: ``DASH_HOT_RELOAD_WATCH_INTERVAL``
    :type dev_tools_hot_reload_watch_interval: float

    :param dev_tools_hot_reload_max_retry: Maximum number of failed reload
        hash requests before failing and displaying a pop up. Default 8.
        env: ``DASH_HOT_RELOAD_MAX_RETRY``
    :type dev_tools_hot_reload_max_retry: int

    :param dev_tools_silence_routes_logging: Silence the `werkzeug` logger,
        will remove all routes logging. Enabled with debugging by default
        because hot reload hash checks generate a lot of requests.
        env: ``DASH_SILENCE_ROUTES_LOGGING``
    :type dev_tools_silence_routes_logging: bool

    :param dev_tools_prune_errors: Reduce tracebacks to just user code,
        stripping out Flask and Dash pieces. Only available with debugging.
        `True` by default, set to `False` to see the complete traceback.
        env: ``DASH_PRUNE_ERRORS``
    :type dev_tools_prune_errors: bool

    :return: debug
    """
    if debug is None:
        debug = get_combined_config("debug", None, True)

    dev_tools = self._setup_dev_tools(
        debug=debug,
        ui=dev_tools_ui,
        props_check=dev_tools_props_check,
        serve_dev_bundles=dev_tools_serve_dev_bundles,
        hot_reload=dev_tools_hot_reload,
        hot_reload_interval=dev_tools_hot_reload_interval,
        hot_reload_watch_interval=dev_tools_hot_reload_watch_interval,
        hot_reload_max_retry=dev_tools_hot_reload_max_retry,
        silence_routes_logging=dev_tools_silence_routes_logging,
        prune_errors=dev_tools_prune_errors,
    )

    if dev_tools.silence_routes_logging:
        logging.getLogger("werkzeug").setLevel(logging.ERROR)
        self.logger.setLevel(logging.INFO)

    if dev_tools.hot_reload:
        _reload = self._hot_reload
        _reload.hash = generate_hash()

        # find_loader should return None on __main__ but doesn't
        # on some python versions https://bugs.python.org/issue14710
        packages = [
            pkgutil.find_loader(x)
            for x in list(ComponentRegistry.registry) + ["dash_renderer"]
            if x != "__main__"
        ]

        component_packages_dist = [
            os.path.dirname(package.path)
            if hasattr(package, "path")
            else package.filename
            for package in packages
        ]

        _reload.watch_thread = threading.Thread(
            target=lambda: _watch.watch(
                [self.config.assets_folder] + component_packages_dist,
                self._on_assets_change,
                sleep_time=dev_tools.hot_reload_watch_interval,
            )
        )
        _reload.watch_thread.daemon = True
        _reload.watch_thread.start()

    if debug and dev_tools.prune_errors:

        @self.server.errorhandler(Exception)
        def _wrap_errors(_):
            # find the callback invocation, if the error is from a callback
            # and skip the traceback up to that point
            # if the error didn't come from inside a callback, we won't
            # skip anything.
            tb = get_current_traceback()
            skip = 0
            for i, line in enumerate(tb.plaintext.splitlines()):
                if "%% callback invoked %%" in line:
                    skip = int((i + 1) / 2)
                    break
            return get_current_traceback(skip=skip).render_full(), 500

    if debug and dev_tools.serve_dev_bundles and not self.scripts.config.serve_locally:
        # Dev bundles only works locally.
        self.scripts.config.serve_locally = True
        print(
            "WARNING: dev bundles requested with serve_locally=False.\n"
            "This is not supported, switching to serve_locally=True"
        )

    return debug