Skip to content

v4: Driver registration system for user-defined and override drivers #226

@jtdub

Description

@jtdub

Description

Currently, users who need custom drivers must either subclass a built-in driver and manage their own constructor function, or dynamically mutate driver.rules after instantiation. There is no way to register a custom driver so that it works seamlessly with Platform enum lookup, get_hconfig(), and other constructor functions.

Additionally, users cannot override built-in drivers — if the Cisco IOS driver does not match their environment, they must bypass the standard API entirely.

Proposed Change

1. Expose HConfigDriverBase and HConfigDriverRules as public API

Ensure these are exported from hier_config (or hier_config.platforms) so users can subclass HConfigDriverBase without reaching into internal modules:

from hier_config import HConfigDriverBase, HConfigDriverRules

2. Add a driver registration function that extends Platform

from hier_config import register_driver, Platform, HConfigDriverBase, HConfigDriverRules

class MyNOSDriver(HConfigDriverBase):
    @staticmethod
    def _instantiate_rules() -> HConfigDriverRules:
        return HConfigDriverRules(...)

register_driver("MY_NOS", MyNOSDriver)

# Platform enum is now extended with the new value
config = get_hconfig(Platform.MY_NOS, config_text)

register_driver() adds a new member to the Platform enum and maps it to the given driver class. All constructors (get_hconfig(), get_hconfig_fast_load(), etc.) use the registered driver automatically.

3. Override built-in drivers

Passing an existing Platform value overrides the built-in driver:

register_driver("CISCO_IOS", MyCustomIOSDriver)

# Now uses MyCustomIOSDriver instead of the built-in
config = get_hconfig(Platform.CISCO_IOS, config_text)

4. Optional: unregister_driver() and get_registered_drivers()

unregister_driver(Platform.MY_NOS)     # removes custom platform
get_registered_drivers()                # returns dict of all registered drivers

Implementation Notes

The current driver lookup lives in constructors.py:get_hconfig_driver() with a hardcoded dict mapping Platform -> driver class. This would become a module-level registry dict that register_driver() writes to and get_hconfig_driver() reads from. Built-in drivers are registered at import time as defaults.

Extending a Python Enum at runtime requires care. Options include:

  • Use enum.extend_enum (aenum library) or a custom metaclass
  • Rebuild Platform with the new member via Platform = Enum("Platform", {**existing, name: auto()})
  • Use a registry that accepts both Platform members and registered string keys, with Platform extended via __getattr__ on the module

Benefits

  • Users can bring their own drivers without forking the library
  • Built-in drivers can be overridden for environments with non-standard behavior
  • Custom platforms are first-class Platform enum members — no separate enum needed
  • Eliminates the need for the custom get_custom_hconfig_driver() pattern documented in docs/drivers.md

Breaking Change

Yes — Platform enum becomes dynamically extensible. The get_hconfig_driver() internal lookup changes. Users who imported the hardcoded platform-to-driver mapping would need to update.

Metadata

Metadata

Assignees

No one assigned

    Labels

    v4-enhancementEnhancement planned for hier_config v4.0.0

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions