def traverse_ingredients(self):
        """Recursively traverse this ingredient and its sub-ingredients.

        Yields
        ------
        ingredient: sacred.Ingredient
            The ingredient as traversed in preorder.
        depth: int
            The depth of the ingredient starting from 0.

        Raises
        ------
        CircularDependencyError:
            If a circular structure among ingredients was detected.
        """
        if self._is_traversing:
            raise CircularDependencyError(ingredients=[self])
        else:
            self._is_traversing = True
        yield self, 0
        with CircularDependencyError.track(self):
            for ingredient in self.ingredients:
                for ingred, depth in ingredient.traverse_ingredients():
                    yield ingred, depth + 1
        self._is_traversing = False