Skip to content

Grid.getFirstLocation still raises StopIteration on a grid with no locations #48

Description

@dmccoystephenson

Problem

Grid.getFirstLocation (src/grid.py:38) raises StopIteration on a grid with no locations. Reproduced against the current main:

Grid(0, 0).getFirstLocation()
# StopIteration

The method is return next(iter(self.locations.values())) with no default, so an empty dictionary propagates StopIteration to the caller — an exception with an empty message, which says nothing about what went wrong.

Why this matters

After PR #44 and PR #46, every other retrieval path on Grid degrades gracefully on the absent path: getEntity returns None, getLocation warns and returns None, getRandomLocation warns and returns None, and getLocationByCoordinates returns -1. getFirstLocation is now the last retrieval path that raises.

A zero-sized grid is constructible, and removeLocation can take a populated grid down to none, so the empty case is reachable in normal use rather than only through a degenerate constructor argument.

StopIteration is also a poor choice of signal specifically: inside a generator it is swallowed and converted to RuntimeError (PEP 479), so a caller iterating over grids would see a confusing failure some distance from the cause.

Suggested fix

An emptiness check in the style now used by getRandomLocation — a warning matching the existing wording convention and a None return. None is the sentinel already chosen for the by-ID and random retrieval paths in PR #46, so it is the consistent choice here too.

Acceptance criteria

  • Retrieving the first location of a grid with no locations does not raise.
  • The absent path is covered by a test, alongside a test that the populated path stays silent.

This issue body was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).


drafted by Claude on behalf of Daniel Stephenson

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions