Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion pylabrobot/resources/hamilton/hamilton_deck_tests.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import textwrap
import unittest

from pylabrobot.resources import TipRack
from pylabrobot.resources import Deck, TipRack
from pylabrobot.resources.corning import (
cor_96_wellplate_360uL_Fb,
)
Expand Down Expand Up @@ -94,6 +94,30 @@ def test_teaching_rack_excluded_by_nominal_volume_search(self):
self.assertEqual(len(matches), 5)
self.assertNotIn("teaching_tip_rack", {tr.name for tr in matches})

def test_get_trash_area96_survives_serialization_round_trip(self):
"""`serialize()` encodes the 96 trash as a child and sets `with_trash96=False`, so the
rebuilt deck's `__init__` leaves the cached `_trash96` pointer as None. `get_trash_area96()`
must still resolve it from the child tree rather than raising."""
deck = self.build_layout()
original_location = deck.get_trash_area96().get_location_wrt(deck)

deck2 = Deck.deserialize(deck.serialize())

self.assertIn("trash_core96", [child.name for child in deck2.children])
self.assertEqual(deck2.get_trash_area96().get_location_wrt(deck2), original_location)

def test_get_trash_area96_raises_after_clear_include_trash(self):
"""`clear(include_trash=True)` unassigns the 96 trash. `get_trash_area96()` must raise
rather than hand back the now-orphaned resource via the stale cached pointer."""
deck = self.build_layout()
deck.get_trash_area96() # populate the cache before invalidating it

deck.clear(include_trash=True)

self.assertNotIn("trash_core96", [child.name for child in deck.children])
with self.assertRaises(RuntimeError):
deck.get_trash_area96()

def test_assign_gigantic_resource(self):
stanley_cup = StanleyCup_QUENCHER_FLOWSTATE_TUMBLER(name="HUGE")
deck = STARLetDeck()
Expand Down
19 changes: 14 additions & 5 deletions pylabrobot/resources/hamilton/hamilton_decks.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,11 +548,20 @@ def rails_to_location(self, rails: int) -> Coordinate:
return Coordinate(x=x, y=63, z=100)

def get_trash_area96(self) -> Trash:
if self._trash96 is None:
raise RuntimeError(
"Trash area for 96-well plates was not created. Initialize with `with_trash96=True`."
)
return self._trash96
# `_trash96` is only set in `__init__`, so it is stale whenever the deck was rebuilt from a
# serialized layout (which encodes the trash as a child and passes `with_trash96=False`) or the
# trash was unassigned. Resolve against the child tree instead, and only trust the cached
# reference while it is still assigned to this deck.
if self._trash96 is not None and self._trash96.parent is self:
return self._trash96

if self.has_resource("trash_core96"):
self._trash96 = cast(Trash, self.get_resource("trash_core96"))
return self._trash96

raise RuntimeError(
"Trash area for 96-well plates was not created. Initialize with `with_trash96=True`."
)

def clear(self, include_trash: bool = False):
"""Clear the deck, removing all resources except the trash areas and the waste block."""
Expand Down