Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(api): remove fixed trash restriction from PAPI deck conflict check #14136

Merged
Merged
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
21 changes: 2 additions & 19 deletions api/src/opentrons/motion_planning/deck_conflict.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,21 +146,11 @@ def is_allowed(self, item: DeckItem) -> bool:
return not isinstance(item, HeaterShakerModule)


class _FixedTrashOnly(NamedTuple):
"""Only fixed-trash labware is allowed in this slot."""

location: DeckSlotName

def is_allowed(self, item: DeckItem) -> bool:
return _is_fixed_trash(item)


_DeckRestriction = Union[
_NothingAllowed,
_MaxHeight,
_NoModule,
_NoHeaterShakerModule,
_FixedTrashOnly,
]
"""A restriction on what is allowed in a given slot."""

Expand Down Expand Up @@ -189,11 +179,7 @@ def check(
Raises:
DeckConflictError: Adding this item should not be allowed.
"""
restrictions: List[_DeckRestriction] = [
_FixedTrashOnly(
location=DeckSlotName.FIXED_TRASH.to_equivalent_for_robot_type(robot_type)
)
]
restrictions: List[_DeckRestriction] = []
# build restrictions driven by existing items
for location, item in existing_items.items():
restrictions += _create_restrictions(
Expand Down Expand Up @@ -333,10 +319,7 @@ def _create_deck_conflict_error_message(
new_item is not None or existing_item is not None
), "Conflict error expects either new_item or existing_item"

if isinstance(restriction, _FixedTrashOnly):
message = f"Only fixed-trash is allowed in slot {restriction.location}"

elif new_item is not None:
if new_item is not None:
message = (
f"{restriction.source_item.name_for_errors}"
f" in slot {restriction.source_location}"
Expand Down
124 changes: 5 additions & 119 deletions api/tests/opentrons/motion_planning/test_deck_conflict.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

@pytest.mark.parametrize(
"robot_type, slot_name",
[("OT-2 Standard", DeckSlotName.SLOT_1), ("OT-3 Standard", DeckSlotName.SLOT_A1)],
[
("OT-2 Standard", DeckSlotName.SLOT_1),
("OT-3 Standard", DeckSlotName.SLOT_A1),
("OT-3 Standard", DeckSlotName.SLOT_A3),
],
)
def test_empty_no_conflict(robot_type: RobotType, slot_name: DeckSlotName) -> None:
"""It should not raise on empty input."""
Expand Down Expand Up @@ -53,124 +57,6 @@ def test_no_multiple_locations(robot_type: RobotType, slot_name: DeckSlotName) -
)


@pytest.mark.parametrize(
"slot_name, robot_type",
[
(DeckSlotName.FIXED_TRASH, "OT-2 Standard"),
(DeckSlotName.SLOT_A3, "OT-3 Standard"),
],
)
def test_only_trash_in_fixed_slot(
slot_name: DeckSlotName, robot_type: RobotType
) -> None:
"""It should only allow trash labware in slot 12."""
trash_labware = deck_conflict.Labware(
uri=LabwareUri("trash_labware_uri"),
highest_z=123,
is_fixed_trash=True,
name_for_errors="trash_labware",
)
not_trash_labware = deck_conflict.Labware(
uri=LabwareUri("not_trash_labware_uri"),
highest_z=123,
is_fixed_trash=False,
name_for_errors="not_trash_labware",
)
not_trash_module = deck_conflict.OtherModule(
highest_z_including_labware=123, name_for_errors="not_trash_module"
)

deck_conflict.check(
existing_items={},
new_item=trash_labware,
new_location=slot_name,
robot_type=robot_type,
)

with pytest.raises(
deck_conflict.DeckConflictError,
match=f"Only fixed-trash is allowed in slot {slot_name}",
):
deck_conflict.check(
existing_items={},
new_item=not_trash_labware,
new_location=slot_name,
robot_type=robot_type,
)

with pytest.raises(
deck_conflict.DeckConflictError,
match=f"Only fixed-trash is allowed in slot {slot_name}",
):
deck_conflict.check(
existing_items={},
new_item=not_trash_module,
new_location=slot_name,
robot_type=robot_type,
)


@pytest.mark.parametrize(
"slot_name, robot_type",
[
(DeckSlotName.FIXED_TRASH, "OT-2 Standard"),
(DeckSlotName.SLOT_A3, "OT-3 Standard"),
],
)
def test_trash_override(slot_name: DeckSlotName, robot_type: RobotType) -> None:
"""It should allow the trash labware to be replaced with another trash labware."""
trash_labware_1 = deck_conflict.Labware(
uri=LabwareUri("trash_labware_1_uri"),
highest_z=123,
is_fixed_trash=True,
name_for_errors="trash_labware_1",
)
trash_labware_2 = deck_conflict.Labware(
uri=LabwareUri("trash_labware_2_uri"),
highest_z=123,
is_fixed_trash=True,
name_for_errors="trash_labware_2",
)
not_trash_labware = deck_conflict.Labware(
uri=LabwareUri("not_trash_labware_uri"),
highest_z=123,
is_fixed_trash=False,
name_for_errors="not_trash_labware",
)
not_trash_module = deck_conflict.OtherModule(
highest_z_including_labware=123, name_for_errors="not_trash_module"
)

deck_conflict.check(
existing_items={slot_name: trash_labware_1},
new_item=trash_labware_2,
new_location=slot_name,
robot_type=robot_type,
)

with pytest.raises(
deck_conflict.DeckConflictError,
match=f"Only fixed-trash is allowed in slot {slot_name}",
):
deck_conflict.check(
existing_items={slot_name: trash_labware_1},
new_item=not_trash_labware,
new_location=slot_name,
robot_type=robot_type,
)

with pytest.raises(
deck_conflict.DeckConflictError,
match=f"Only fixed-trash is allowed in slot {slot_name}",
):
deck_conflict.check(
existing_items={slot_name: trash_labware_1},
new_item=not_trash_module,
new_location=slot_name,
robot_type=robot_type,
)


@pytest.mark.parametrize(
("thermocycler_is_semi", "labware_location", "labware_should_be_allowed"),
[
Expand Down