Skip to content

Make Agent hashability requirement explicit in type system #3101

@EwoutH

Description

@EwoutH

Summary

The Agent class should explicitly inherit from collections.abc.Hashable to document that agents must be hashable, since AgentSet uses WeakKeyDictionary which requires hashable keys.

Background

From the Python documentation:

hashable

An object is hashable if it has a hash value which never changes during its lifetime (it needs a __hash__() method), and can be compared to other objects (it needs an __eq__() method). Hashable objects which compare equal must have the same hash value.

Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.

Most of Python’s immutable built-in objects are hashable; mutable containers (such as lists or dictionaries) are not; immutable containers (such as tuples and frozensets) are only hashable if their elements are hashable. Objects which are instances of user-defined classes are hashable by default. They all compare unequal (except with themselves), and their hash value is derived from their id().

Current Behavior

AgentSet stores agents in a WeakKeyDictionary, which requires agents to be hashable. The base Agent class relies on Python’s default hashability (based on object id()), but this requirement is not explicit in the type signature.

Proposed Change

from collections.abc import Hashable

class Agent[M: Model](Hashable):
    """Base class for a model agent in Mesa.
    
    Notes:
        Agents must be hashable to be stored in AgentSets. If you override
        __eq__(), you must also implement __hash__() to maintain hashability.
    """

Benefits

  • Makes the hashability requirement explicit for type checkers and developers
  • Helps prevent bugs where users override __eq__() without __hash__(), breaking AgentSet functionality
  • Improves API documentation through the type system
  • No runtime behavior change since Agent is already hashable by default​​​​​​​​​​​​​​​​

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsRelease notes label

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions