Hash Functionality
NSHConfig provides automatic hash functionality for Config
classes, making them usable as dictionary keys and in sets.
Overview
By default, all Config
classes are made hashable through a mechanism that automatically adds a __hash__
method to the class. This allows you to:
Use
hash()
on a config instanceUse config instances as dictionary keys
Add config instances to sets
Deduplicate configs easily using
dict.fromkeys
or sets
This is particularly useful when you need to store and retrieve configs in dictionaries or sets.
How It Works
The hash function is automatically added to your Config
class during class initialization. It computes a hash based on the values of all fields in the config, ensuring that:
Equal configs (those with identical field values) produce identical hash values
Different configs produce different hash values (with high probability)
Example Usage
from typing import ClassVar
import nshconfig as C
class MyConfig(C.Config):
name: str = "default"
value: int = 0
# Creating configs
config1 = MyConfig(name="example", value=42)
config2 = MyConfig(name="example", value=42)
config3 = MyConfig(name="different", value=100)
# Configs with identical values have identical hashes
assert hash(config1) == hash(config2)
assert hash(config1) != hash(config3)
# Using configs as dictionary keys
config_map = {
config1: "First config",
config3: "Third config"
}
# Retrieving values
assert config_map[config1] == "First config"
# Since config2 is equal to config1, it has the same hash and can retrieve the same value
assert config_map[config2] == "First config"
# Deduplicating configs using sets
configs = [config1, config2, config3, MyConfig(name="example", value=42)]
unique_configs = list(set(configs))
assert len(unique_configs) == 2 # Only 2 unique configs (config1/config2 and config3)
Controlling Hash Functionality
You can disable the automatic hash generation for a specific Config
class by setting set_default_hash
to False
in the model_config
:
from typing import ClassVar
import nshconfig as C
class NonHashableConfig(C.Config):
model_config: ClassVar[C.ConfigDict] = {"set_default_hash": False}
name: str = "default"
value: int = 0
With this configuration, attempting to hash an instance of NonHashableConfig
will raise a TypeError
.
Limitations
Mutability Warning: Since
Config
objects are mutable, you should be careful when using them as dictionary keys. If you modify a config after using it as a key, you may not be able to retrieve its associated value anymore, as the hash will change.Nested Configs: For configs containing other configs, all nested configs must also be hashable for the parent config to be hashable.
Implementation Details
The hash function is implemented using Pydantic’s internal set_default_hash_func
mechanism. It computes a hash based on the model’s representation, which includes all field values.