Repository: celery/celery
File: celery/app/base.py (Python)

Code before:
        ])

    def bugreport(self):
        """Return information useful in bug reports."""
        return bugreport(self)

    def _get_backend(self):
        backend, url = backends.by_url(
            self.backend_cls or self.conf.result_backend,
            self.loader)
        return backend(app=self, url=url)

    def _finalize_pending_conf(self):
        """Get config value by key and finalize loading the configuration.

        Note:
            This is used by PendingConfiguration:
                as soon as you access a key the configuration is read.
        """
        try:
            conf = self._conf = self._load_config()
        except AttributeError as e:
            # AttributeError is not propagated, it is "handled" by
            # PendingConfiguration parent class. This causes
            # confusing RecursionError.
            raise ModuleNotFoundError(*e.args)

        return conf

    def _load_config(self):
        if isinstance(self.on_configure, Signal):
            self.on_configure.send(sender=self)
        else:
            # used to be a method pre 4.0
            self.on_configure()
        if self._config_source:
            self.loader.config_from_object(self._config_source)
        self.configured = True
        settings = detect_settings(
            self.prepare_config(self.loader.conf), self._preconf,
            ignore_keys=self._preconf_set_by_auto, prefix=self.namespace,
        )
        if self._conf is not None:
            # replace in place, as someone may have referenced app.conf,
            # done some changes, accessed a key, and then try to make more
            # changes to the reference and not the finalized value.
            self._conf.swap_with(settings)
        else:
            self._conf = settings

        # load lazy config dict initializers.

Review comment (suggestion):
You can use `raise from` e.g raise Module..() from e

Code after:
        ])

    def bugreport(self):
        """Return information useful in bug reports."""
        return bugreport(self)

    def _get_backend(self):
        backend, url = backends.by_url(
            self.backend_cls or self.conf.result_backend,
            self.loader)
        return backend(app=self, url=url)

    def _finalize_pending_conf(self):
        """Get config value by key and finalize loading the configuration.

        Note:
            This is used by PendingConfiguration:
                as soon as you access a key the configuration is read.
        """
        try:
            conf = self._conf = self._load_config()
        except AttributeError as err:
            # AttributeError is not propagated, it is "handled" by
            # PendingConfiguration parent class. This causes
            # confusing RecursionError.
            raise ModuleNotFoundError(*err.args) from err

        return conf

    def _load_config(self):
        if isinstance(self.on_configure, Signal):
            self.on_configure.send(sender=self)
        else:
            # used to be a method pre 4.0
            self.on_configure()
        if self._config_source:
            self.loader.config_from_object(self._config_source)
        self.configured = True
        settings = detect_settings(
            self.prepare_config(self.loader.conf), self._preconf,
            ignore_keys=self._preconf_set_by_auto, prefix=self.namespace,
        )
        if self._conf is not None:
            # replace in place, as someone may have referenced app.conf,
            # done some changes, accessed a key, and then try to make more
            # changes to the reference and not the finalized value.
            self._conf.swap_with(settings)
        else:
            self._conf = settings

        # load lazy config dict initializers.