Skip to content

Reduce assert-based type narrowing by restructuring data flow #19

Description

@bjmorgan

Summary

PR #18 added strict mypy type hints across the codebase, introducing ~20 assert statements to narrow X | None types. These asserts are a code smell — they indicate that the current two-phase initialisation pattern (construct object, then configure it later) leaves attributes as None longer than necessary.

Root cause

Several classes use a pattern where attributes are initialised as None and populated later:

  • Lattice.params is set to None in __init__, then assigned via Simulation.run()
  • Site.p_neighbours is set to None in __init__, then populated by Lattice.__init__
  • Simulation.lattice, Simulation.atoms, etc. are None until run() is called

This means methods that use these attributes need assert self.x is not None guards, even though in practice the attributes are always set by the time the methods are called.

Desired outcome

Restructure data flow so that objects receive their required data at construction time, eliminating the need for nullable attributes and assert guards. This likely involves:

  • Passing SimulationParameters to Lattice at construction (or to methods that need it)
  • Ensuring p_neighbours is always populated (possibly by making it a required constructor parameter)
  • Rethinking Simulation so that its properties don't depend on state set during run()

Related PRs

  • Add type hints and strict mypy #18 — introduced the asserts
  • Future PRs restructuring Options into a dataclass and refactoring mutable counters are natural places to address this

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions