def _create_context_manager(group: str, entrypoint: pkg_resources.EntryPoint, working_set: pkg_resources.WorkingSet, scope: str): name = entrypoint.name # We need a Distribution to register our dynamic entrypoints within. # We have to always instantiate it to find our key, as key can be # different from the project_name dist = pkg_resources.Distribution(location=__file__, project_name=scope) # Prevent creating entrypoints in distributions not created by us, # otherwise we could remove the distributions when cleaning up. if (dist.key in working_set.by_key and working_set.by_key[dist.key].location != __file__): raise ValueError(f'scope {format_scope(scope, dist)} already ' f'exists in working set at location ' f'{working_set.by_key[dist.key].location}') if dist.key not in working_set.by_key: working_set.add(dist) # Reference the actual registered dist if we didn't just register it dist = working_set.by_key[dist.key] # Ensure the group exists in our distribution group_entries = dist.get_entry_map().setdefault(group, {}) # Create an entry for the specified entrypoint if name in group_entries: raise ValueError(f'{name!r} is already registered under {group!r} ' f'in scope {format_scope(scope, dist)}') assert entrypoint.dist is None entrypoint.dist = dist group_entries[name] = entrypoint # Wait for something to happen with the entrypoint... try: yield finally: # Tidy up del group_entries[name] # If we re-use this entrypoint (by re-entering the context) the # dist may well have changed (because it gets deleted from the # working set) so we shouldn't remember it. assert entrypoint.dist is dist entrypoint.dist = None if len(group_entries) == 0: del dist.get_entry_map()[group] if len(dist.get_entry_map()) == 0: del working_set.by_key[dist.key] working_set.entry_keys[__file__].remove(dist.key) if not working_set.entry_keys[__file__]: del working_set.entry_keys[__file__] working_set.entries.remove(__file__)