Source code for dhcpkit.registry

"""
Base class for pkg_resources based registries
"""
import collections
import logging

import pkg_resources

from dhcpkit.utils import camelcase_to_dash

logger = logging.getLogger(__name__)


[docs]class Registry(collections.UserDict): """ Base class for registries """ entry_point = 'dhcpkit.NONE' """The name of the entry_point group""" def __init__(self): """ A custom dictionary that initialises itself with the entry points from pkg_resources """ super().__init__() # A name-based alternative self.by_name = {} """An alternative name-based mapping""" # Try all the entry points entry_points = pkg_resources.iter_entry_points(group=self.entry_point) for entry_point in entry_points: # If the name is a string with an integer then convert it to a real integer try: name = int(entry_point.name) except ValueError: name = entry_point.name if name in self.data: logger.warning("Multiple entry points found for {} {}, using {}".format( self.__class__.__name__, name, self.data[name])) continue try: # Load the entry point and store it loaded = entry_point.load() self.data[name] = loaded # Also store by name alternative_name = self.get_name(loaded) self.by_name[alternative_name] = loaded except pkg_resources.VersionConflict as e: # Wrong version, report logger.critical("Entry point {} for {} is not compatible: {}".format( entry_point, self.__class__.__name__, e)) continue except ImportError: # Ok, this one isn't working, skip it logger.exception("Entry point {} for {} could not be loaded".format( entry_point, self.__class__.__name__)) continue
[docs] def get_name(self, item: object) -> str: """ Get the name for the by_name mapping. :param item: The item to determine the name of :return: The name to use as key in the mapping """ return camelcase_to_dash(item.__name__)