# Path: sacred/utils.py
# def iter_prefixes(path):
#     """
#     Iterate through all (non-empty) prefixes of a dotted path.
# 
#     Example
#     -------
#     >>> list(iter_prefixes('foo.bar.baz'))
#     ['foo', 'foo.bar', 'foo.bar.baz']
#     """
#     split_path = path.split(".")
#     for i in range(1, len(split_path) + 1):
#         yield join_paths(*split_path[:i])
# 
# def join_paths(*parts):
#     """Join different parts together to a valid dotted path."""
#     return ".".join(str(p).strip(".") for p in parts if p)


from sacred.utils import iter_prefixes, join_paths
        self.modified |= {join_paths(path, u) for u in updated}
        self.typechanged.update(
            {join_paths(path, k): v for k, v in typechanged.items()}
        )
        self.ensure_coherence()
        for k, v in config_mod.docs.items():
            if not self.docs.get(k, ""):
                self.docs[k] = v

    def update_add(self, config_mod, path=""):
        added = config_mod.added
        updated = config_mod.modified
        typechanged = config_mod.typechanged
        self.added |= {join_paths(path, a) for a in added}
        self.modified |= {join_paths(path, u) for u in updated}
        self.typechanged.update(
            {join_paths(path, k): v for k, v in typechanged.items()}
        )
        self.docs.update(
            {
                join_paths(path, k): v
                for k, v in config_mod.docs.items()
                if path == "" or k != "seed"
            }
        )
        self.ensure_coherence()

    def ensure_coherence(self):
        # make sure parent paths show up as updated appropriately
        self.modified |= {p for a in self.added for p in iter_prefixes(a)}

# Path: sacred/utils.py
# def iter_prefixes(path):
#     """
#     Iterate through all (non-empty) prefixes of a dotted path.
# 
#     Example
#     -------
#     >>> list(iter_prefixes('foo.bar.baz'))
#     ['foo', 'foo.bar', 'foo.bar.baz']
#     """
#     split_path = path.split(".")
#     for i in range(1, len(split_path) + 1):
#         yield join_paths(*split_path[:i])
# 
# def join_paths(*parts):
#     """Join different parts together to a valid dotted path."""
#     return ".".join(str(p).strip(".") for p in parts if p)


# Path: sacred/config/config_summary.py
from sacred.utils import iter_prefixes, join_paths

        self.modified |= {join_paths(path, u) for u in updated}
        self.typechanged.update(
            {join_paths(path, k): v for k, v in typechanged.items()}
        )
        self.ensure_coherence()
        for k, v in config_mod.docs.items():
            if not self.docs.get(k, ""):
                self.docs[k] = v

    def update_add(self, config_mod, path=""):
        added = config_mod.added
        updated = config_mod.modified
        typechanged = config_mod.typechanged
        self.added |= {join_paths(path, a) for a in added}
        self.modified |= {join_paths(path, u) for u in updated}
        self.typechanged.update(
            {join_paths(path, k): v for k, v in typechanged.items()}
        )
        self.docs.update(
            {
                join_paths(path, k): v
                for k, v in config_mod.docs.items()
                if path == "" or k != "seed"
            }
        )
        self.ensure_coherence()

    def ensure_coherence(self):
        # make sure parent paths show up as updated appropriately
        self.modified |= {p for a in self.added for p in iter_prefixes(a)}

        self.modified |= {p for u in self.modified for p in iter_prefixes(u)}