opentrons 8.6.0a12__py3-none-any.whl → 8.7.0a0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of opentrons might be problematic. Click here for more details.

Files changed (25) hide show
  1. opentrons/_version.py +2 -2
  2. opentrons/hardware_control/backends/ot3controller.py +22 -13
  3. opentrons/hardware_control/backends/ot3simulator.py +1 -1
  4. opentrons/hardware_control/ot3api.py +1 -1
  5. opentrons/protocol_api/core/engine/_default_liquid_class_versions.py +54 -0
  6. opentrons/protocol_api/core/engine/protocol.py +11 -2
  7. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +1 -1
  8. opentrons/protocol_api/core/protocol.py +1 -1
  9. opentrons/protocol_api/labware.py +36 -2
  10. opentrons/protocol_api/module_contexts.py +100 -13
  11. opentrons/protocol_api/protocol_context.py +162 -12
  12. opentrons/protocol_api/validation.py +4 -0
  13. opentrons/protocol_engine/commands/command_unions.py +2 -0
  14. opentrons/protocol_engine/commands/flex_stacker/common.py +13 -0
  15. opentrons/protocol_engine/commands/flex_stacker/store.py +20 -2
  16. opentrons/protocol_engine/execution/labware_movement.py +5 -11
  17. opentrons/protocol_engine/state/labware.py +66 -0
  18. opentrons/protocol_engine/types/__init__.py +2 -0
  19. opentrons/protocol_engine/types/labware.py +9 -0
  20. opentrons/protocols/api_support/definitions.py +1 -1
  21. {opentrons-8.6.0a12.dist-info → opentrons-8.7.0a0.dist-info}/METADATA +4 -4
  22. {opentrons-8.6.0a12.dist-info → opentrons-8.7.0a0.dist-info}/RECORD +25 -24
  23. {opentrons-8.6.0a12.dist-info → opentrons-8.7.0a0.dist-info}/WHEEL +0 -0
  24. {opentrons-8.6.0a12.dist-info → opentrons-8.7.0a0.dist-info}/entry_points.txt +0 -0
  25. {opentrons-8.6.0a12.dist-info → opentrons-8.7.0a0.dist-info}/licenses/LICENSE +0 -0
opentrons/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '8.6.0a12'
32
- __version_tuple__ = version_tuple = (8, 6, 0, 'a12')
31
+ __version__ = version = '8.7.0a0'
32
+ __version_tuple__ = version_tuple = (8, 7, 0, 'a0')
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -686,9 +686,9 @@ class OT3Controller(FlexBackend):
686
686
  return (
687
687
  MoveGroupRunner(
688
688
  move_groups=[move_group],
689
- ignore_stalls=True
690
- if not self._feature_flags.stall_detection_enabled
691
- else False,
689
+ ignore_stalls=(
690
+ True if not self._feature_flags.stall_detection_enabled else False
691
+ ),
692
692
  ),
693
693
  False,
694
694
  )
@@ -712,9 +712,9 @@ class OT3Controller(FlexBackend):
712
712
  return (
713
713
  MoveGroupRunner(
714
714
  move_groups=[tip_motor_move_group],
715
- ignore_stalls=True
716
- if not self._feature_flags.stall_detection_enabled
717
- else False,
715
+ ignore_stalls=(
716
+ True if not self._feature_flags.stall_detection_enabled else False
717
+ ),
718
718
  ),
719
719
  True,
720
720
  )
@@ -939,9 +939,9 @@ class OT3Controller(FlexBackend):
939
939
 
940
940
  runner = MoveGroupRunner(
941
941
  move_groups=[move_group],
942
- ignore_stalls=True
943
- if not self._feature_flags.stall_detection_enabled
944
- else False,
942
+ ignore_stalls=(
943
+ True if not self._feature_flags.stall_detection_enabled else False
944
+ ),
945
945
  )
946
946
  try:
947
947
  positions = await runner.run(can_messenger=self._messenger)
@@ -976,9 +976,9 @@ class OT3Controller(FlexBackend):
976
976
  move_group = self._build_tip_action_group(origin, targets)
977
977
  runner = MoveGroupRunner(
978
978
  move_groups=[move_group],
979
- ignore_stalls=True
980
- if not self._feature_flags.stall_detection_enabled
981
- else False,
979
+ ignore_stalls=(
980
+ True if not self._feature_flags.stall_detection_enabled else False
981
+ ),
982
982
  )
983
983
  try:
984
984
  positions = await runner.run(can_messenger=self._messenger)
@@ -1777,7 +1777,16 @@ class OT3Controller(FlexBackend):
1777
1777
  expected_grip_width + grip_width_uncertainty_wider
1778
1778
  )
1779
1779
  current_gripper_position = jaw_width
1780
- if isclose(current_gripper_position, hard_limit_lower):
1780
+ log.info(
1781
+ f"Checking gripper position: current {jaw_width}; max error {max_allowed_grip_error}; hard limits {hard_limit_lower}, {hard_limit_upper}; expected {expected_gripper_position_min}, {expected_grip_width}, {expected_gripper_position_max}; uncertainty {grip_width_uncertainty_narrower}, {grip_width_uncertainty_wider}"
1782
+ )
1783
+ if (
1784
+ isclose(current_gripper_position, hard_limit_lower)
1785
+ # this odd check handles internal backlash that can lead the position to read as if
1786
+ # the gripper has overshot its lower bound; this is physically impossible and an
1787
+ # artifact of the gearing, so it always indicates a hard stop
1788
+ or current_gripper_position < hard_limit_lower
1789
+ ):
1781
1790
  raise FailedGripperPickupError(
1782
1791
  message="Failed to grip: jaws all the way closed",
1783
1792
  details={
@@ -781,7 +781,7 @@ class OT3Simulator(FlexBackend):
781
781
  next_fw_version=1,
782
782
  fw_update_needed=False,
783
783
  current_fw_sha="simulated",
784
- pcba_revision="A1",
784
+ pcba_revision="A1.0",
785
785
  update_state=None,
786
786
  )
787
787
  for axis in self._present_axes
@@ -1480,8 +1480,8 @@ class OT3API(
1480
1480
  grip_width_uncertainty_narrower,
1481
1481
  gripper.jaw_width,
1482
1482
  gripper.max_allowed_grip_error,
1483
- gripper.max_jaw_width,
1484
1483
  gripper.min_jaw_width,
1484
+ gripper.max_jaw_width,
1485
1485
  )
1486
1486
 
1487
1487
  def gripper_jaw_can_home(self) -> bool:
@@ -0,0 +1,54 @@
1
+ """The versions of standard liquid classes that the Protocol API should load by default."""
2
+
3
+ from typing import TypeAlias
4
+ from opentrons.protocols.api_support.types import APIVersion
5
+
6
+
7
+ DefaultLiquidClassVersions: TypeAlias = dict[APIVersion, dict[str, int]]
8
+
9
+
10
+ # This:
11
+ #
12
+ # {
13
+ # APIVersion(2, 100): {
14
+ # "foo_liquid": 3,
15
+ # },
16
+ # APIVersion(2, 105): {
17
+ # "foo_liquid": 7
18
+ # }
19
+ # }
20
+ #
21
+ # Means this:
22
+ #
23
+ # apiLevels name Default liquid class version
24
+ # ---------------------------------------------------------------
25
+ # <2.100 foo_liquid 1
26
+ # >=2.100,<2.105 foo_liquid 3
27
+ # >=2.105 foo_liquid 7
28
+ # [any] [anything else] 1
29
+ DEFAULT_LIQUID_CLASS_VERSIONS: DefaultLiquidClassVersions = {
30
+ APIVersion(2, 26): {
31
+ "water": 2,
32
+ },
33
+ }
34
+
35
+
36
+ def get_liquid_class_version(
37
+ api_version: APIVersion,
38
+ liquid_class_name: str,
39
+ ) -> int:
40
+ """Return what version of a liquid class the Protocol API should load by default."""
41
+ default_lc_versions_newest_to_oldest = sorted(
42
+ DEFAULT_LIQUID_CLASS_VERSIONS.items(), key=lambda kv: kv[0], reverse=True
43
+ )
44
+ for (
45
+ breakpoint_api_version,
46
+ breakpoint_liquid_class_versions,
47
+ ) in default_lc_versions_newest_to_oldest:
48
+ if (
49
+ api_version >= breakpoint_api_version
50
+ and liquid_class_name in breakpoint_liquid_class_versions
51
+ ):
52
+ return breakpoint_liquid_class_versions[liquid_class_name]
53
+
54
+ return 1
@@ -78,7 +78,12 @@ from .module_core import (
78
78
  FlexStackerCore,
79
79
  )
80
80
  from .exceptions import InvalidModuleLocationError
81
- from . import load_labware_params, deck_conflict, overlap_versions
81
+ from . import (
82
+ load_labware_params,
83
+ deck_conflict,
84
+ overlap_versions,
85
+ _default_liquid_class_versions,
86
+ )
82
87
  from opentrons.protocol_engine.resources import labware_validation
83
88
 
84
89
  if TYPE_CHECKING:
@@ -1068,8 +1073,12 @@ class ProtocolCore(
1068
1073
  display_color=(liquid.displayColor.root if liquid.displayColor else None),
1069
1074
  )
1070
1075
 
1071
- def get_liquid_class(self, name: str, version: int) -> LiquidClass:
1076
+ def get_liquid_class(self, name: str, version: Optional[int]) -> LiquidClass:
1072
1077
  """Get an instance of a built-in liquid class."""
1078
+ if version is None:
1079
+ version = _default_liquid_class_versions.get_liquid_class_version(
1080
+ self._api_version, name
1081
+ )
1073
1082
  try:
1074
1083
  # Check if we have already loaded this liquid class' definition
1075
1084
  liquid_class_def = self._liquid_class_def_cache[(name, version)]
@@ -599,7 +599,7 @@ class LegacyProtocolCore(
599
599
  """Define a liquid to load into a well."""
600
600
  assert False, "define_liquid only supported on engine core"
601
601
 
602
- def get_liquid_class(self, name: str, version: int) -> LiquidClass:
602
+ def get_liquid_class(self, name: str, version: Optional[int]) -> LiquidClass:
603
603
  """Get an instance of a built-in liquid class."""
604
604
  assert False, "define_liquid_class is only supported on engine core"
605
605
 
@@ -297,7 +297,7 @@ class AbstractProtocol(
297
297
  """Define a liquid to load into a well."""
298
298
 
299
299
  @abstractmethod
300
- def get_liquid_class(self, name: str, version: int) -> LiquidClass:
300
+ def get_liquid_class(self, name: str, version: Optional[int]) -> LiquidClass:
301
301
  """Get an instance of a built-in liquid class."""
302
302
 
303
303
  @abstractmethod
@@ -640,6 +640,9 @@ class Labware:
640
640
  lid: Optional[str] = None,
641
641
  namespace: Optional[str] = None,
642
642
  version: Optional[int] = None,
643
+ *,
644
+ lid_namespace: Optional[str] = None,
645
+ lid_version: Optional[int] = None,
643
646
  ) -> Labware:
644
647
  """Load a compatible labware onto the labware using its load parameters.
645
648
 
@@ -650,6 +653,24 @@ class Labware:
650
653
 
651
654
  :returns: The initialized and loaded labware object.
652
655
  """
656
+ if self._api_version < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE:
657
+ if lid_namespace is not None:
658
+ raise APIVersionError(
659
+ api_element="The `lid_namespace` parameter",
660
+ until_version=str(
661
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
662
+ ),
663
+ current_version=str(self._api_version),
664
+ )
665
+ if lid_version is not None:
666
+ raise APIVersionError(
667
+ api_element="The `lid_version` parameter",
668
+ until_version=str(
669
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
670
+ ),
671
+ current_version=str(self._api_version),
672
+ )
673
+
653
674
  labware_core = self._protocol_core.load_labware(
654
675
  load_name=name,
655
676
  label=label,
@@ -674,11 +695,24 @@ class Labware:
674
695
  until_version="2.23",
675
696
  current_version=f"{self._api_version}",
676
697
  )
698
+ if (
699
+ self._api_version
700
+ < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
701
+ ):
702
+ checked_lid_namespace = namespace
703
+ checked_lid_version = version
704
+ else:
705
+ # This is currently impossible to reach because of the
706
+ # `if self._api_version < validation.validation.LID_STACK_VERSION_GATE`
707
+ # check above. This is here for now in case that check is removed in
708
+ # the future, and for symmetry with the other labware load methods.
709
+ checked_lid_namespace = lid_namespace
710
+ checked_lid_version = lid_version
677
711
  self._protocol_core.load_lid(
678
712
  load_name=lid,
679
713
  location=labware_core,
680
- namespace=namespace,
681
- version=version,
714
+ namespace=checked_lid_namespace,
715
+ version=checked_lid_version,
682
716
  )
683
717
 
684
718
  return labware
@@ -123,7 +123,7 @@ class ModuleContext(CommandPublisher):
123
123
 
124
124
  return core.geometry.add_labware(labware)
125
125
 
126
- def load_labware(
126
+ def load_labware( # noqa: C901
127
127
  self,
128
128
  name: str,
129
129
  label: Optional[str] = None,
@@ -131,6 +131,11 @@ class ModuleContext(CommandPublisher):
131
131
  version: Optional[int] = None,
132
132
  adapter: Optional[str] = None,
133
133
  lid: Optional[str] = None,
134
+ *,
135
+ adapter_namespace: Optional[str] = None,
136
+ adapter_version: Optional[int] = None,
137
+ lid_namespace: Optional[str] = None,
138
+ lid_version: Optional[int] = None,
134
139
  ) -> Labware:
135
140
  """Load a labware onto the module using its load parameters.
136
141
 
@@ -142,7 +147,11 @@ class ModuleContext(CommandPublisher):
142
147
  :returns: The initialized and loaded labware object.
143
148
 
144
149
  .. versionadded:: 2.1
145
- The *label,* *namespace,* and *version* parameters.
150
+ The ``label``, ``namespace``, and ``version`` parameters.
151
+
152
+ .. versionadded:: 2.26
153
+ The ``adapter_namespace``, ``adapter_version``,
154
+ ``lid_namespace``, and ``lid_version`` parameters.
146
155
  """
147
156
  if self._api_version < APIVersion(2, 1) and (
148
157
  label is not None or namespace is not None or version != 1
@@ -152,6 +161,40 @@ class ModuleContext(CommandPublisher):
152
161
  "are trying to utilize new load_labware parameters in 2.1"
153
162
  )
154
163
 
164
+ if self._api_version < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE:
165
+ if adapter_namespace is not None:
166
+ raise APIVersionError(
167
+ api_element="The `adapter_namespace` parameter",
168
+ until_version=str(
169
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
170
+ ),
171
+ current_version=str(self._api_version),
172
+ )
173
+ if adapter_version is not None:
174
+ raise APIVersionError(
175
+ api_element="The `adapter_version` parameter",
176
+ until_version=str(
177
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
178
+ ),
179
+ current_version=str(self._api_version),
180
+ )
181
+ if lid_namespace is not None:
182
+ raise APIVersionError(
183
+ api_element="The `lid_namespace` parameter",
184
+ until_version=str(
185
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
186
+ ),
187
+ current_version=str(self._api_version),
188
+ )
189
+ if lid_version is not None:
190
+ raise APIVersionError(
191
+ api_element="The `lid_version` parameter",
192
+ until_version=str(
193
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
194
+ ),
195
+ current_version=str(self._api_version),
196
+ )
197
+
155
198
  load_location: Union[ModuleCore, LabwareCore]
156
199
  if adapter is not None:
157
200
  if self._api_version < APIVersion(2, 15):
@@ -160,9 +203,21 @@ class ModuleContext(CommandPublisher):
160
203
  until_version="2.15",
161
204
  current_version=f"{self._api_version}",
162
205
  )
206
+
207
+ if (
208
+ self._api_version
209
+ < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
210
+ ):
211
+ checked_adapter_namespace = namespace
212
+ checked_adapter_version = None
213
+ else:
214
+ checked_adapter_namespace = adapter_namespace
215
+ checked_adapter_version = adapter_version
216
+
163
217
  loaded_adapter = self.load_adapter(
164
218
  name=adapter,
165
- namespace=namespace,
219
+ namespace=checked_adapter_namespace,
220
+ version=checked_adapter_version,
166
221
  )
167
222
  load_location = loaded_adapter._core
168
223
  else:
@@ -193,11 +248,22 @@ class ModuleContext(CommandPublisher):
193
248
  until_version="2.23",
194
249
  current_version=f"{self._api_version}",
195
250
  )
251
+
252
+ if (
253
+ self._api_version
254
+ < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
255
+ ):
256
+ checked_lid_namespace = namespace
257
+ checked_lid_version = None
258
+ else:
259
+ checked_lid_namespace = lid_namespace
260
+ checked_lid_version = lid_version
261
+
196
262
  self._protocol_core.load_lid(
197
263
  load_name=lid,
198
264
  location=labware_core,
199
- namespace=namespace,
200
- version=version,
265
+ namespace=checked_lid_namespace,
266
+ version=checked_lid_version,
201
267
  )
202
268
 
203
269
  if isinstance(self._core, LegacyModuleCore):
@@ -1330,6 +1396,11 @@ class FlexStackerContext(ModuleContext):
1330
1396
  lid: str | None = None,
1331
1397
  count: int | None = None,
1332
1398
  stacking_offset_z: float | None = None,
1399
+ *,
1400
+ adapter_namespace: str | None = None,
1401
+ adapter_version: int | None = None,
1402
+ lid_namespace: str | None = None,
1403
+ lid_version: int | None = None,
1333
1404
  ) -> None:
1334
1405
  """Configure the type and starting quantity of labware the Flex Stacker will store during a protocol. This is the only type of labware you'll be able to store in the Stacker until it's reconfigured.
1335
1406
 
@@ -1338,6 +1409,7 @@ class FlexStackerContext(ModuleContext):
1338
1409
  :param str load_name: A string to use for looking up a labware definition.
1339
1410
  You can find the ``load_name`` for any Opentrons-verified labware on the
1340
1411
  `Labware Library <https://labware.opentrons.com>`__.
1412
+
1341
1413
  :param str namespace: The namespace that the labware definition belongs to.
1342
1414
  If unspecified, the API will automatically search two namespaces:
1343
1415
 
@@ -1348,19 +1420,34 @@ class FlexStackerContext(ModuleContext):
1348
1420
  You might need to specify an explicit ``namespace`` if you have a custom
1349
1421
  definition whose ``load_name`` is the same as an Opentrons-verified
1350
1422
  definition, and you want to explicitly choose one or the other.
1423
+
1351
1424
  :param version: The version of the labware definition. You should normally
1352
1425
  leave this unspecified to let the method choose a version
1353
1426
  automatically.
1427
+
1354
1428
  :param adapter: An adapter to load the labware on top of. Accepts the same
1355
- values as the ``load_name`` parameter of :py:meth:`.load_adapter`. The
1356
- adapter will use the same namespace as the labware, and the API will
1357
- choose the adapter's version automatically.
1429
+ values as the ``load_name`` parameter of :py:meth:`.load_adapter`.
1430
+
1431
+ :param adapter_namespace: Applies to ``adapter`` the same way that ``namespace``
1432
+ applies to ``load_name``.
1433
+
1434
+ :param adapter_version: Applies to ``adapter`` the same way that ``version``
1435
+ applies to ``load_name``.
1436
+
1358
1437
  :param lid: A lid to load the on top of the main labware. Accepts the same
1359
1438
  values as the ``load_name`` parameter of :py:meth:`~.ProtocolContext.load_lid_stack`. The
1360
1439
  lid will use the same namespace as the labware, and the API will
1361
1440
  choose the lid's version automatically.
1441
+
1442
+ :param lid_namespace: Applies to ``lid`` the same way that ``namespace``
1443
+ applies to ``load_name``.
1444
+
1445
+ :param lid_version: Applies to ``lid`` the same way that ``version``
1446
+ applies to ``load_name``.
1447
+
1362
1448
  :param count: The number of labware that the Flex Stacker should store. If not specified, this will be the maximum amount of this kind of
1363
1449
  labware that the Flex Stacker is capable of storing.
1450
+
1364
1451
  :param stacking_offset_z: Stacking ``z`` offset in mm of stored labware. If specified, this overrides the
1365
1452
  calculated value in the labware definition.
1366
1453
 
@@ -1378,18 +1465,18 @@ class FlexStackerContext(ModuleContext):
1378
1465
  - Labware on adapter: the adapter (bottom side) of the upper labware unit overlaps with the top side of the labware below.
1379
1466
  - Labware with lid: the labware (bottom side) of the upper labware unit overlaps with the lid (top side) of the unit below.
1380
1467
  - Labware with lid and adapter: the adapter (bottom side) of the upper labware unit overlaps with the lid (top side) of the unit below.
1381
-
1382
1468
  """
1469
+
1383
1470
  self._core.set_stored_labware(
1384
1471
  main_load_name=load_name,
1385
1472
  main_namespace=namespace,
1386
1473
  main_version=version,
1387
1474
  lid_load_name=lid,
1388
- lid_namespace=namespace,
1389
- lid_version=version,
1475
+ lid_namespace=lid_namespace,
1476
+ lid_version=lid_version,
1390
1477
  adapter_load_name=adapter,
1391
- adapter_namespace=namespace,
1392
- adapter_version=version,
1478
+ adapter_namespace=adapter_namespace,
1479
+ adapter_version=adapter_version,
1393
1480
  count=count,
1394
1481
  stacking_offset_z=stacking_offset_z,
1395
1482
  )
@@ -405,7 +405,7 @@ class ProtocolContext(CommandPublisher):
405
405
  )
406
406
 
407
407
  @requires_version(2, 0)
408
- def load_labware(
408
+ def load_labware( # noqa: C901
409
409
  self,
410
410
  load_name: str,
411
411
  location: Union[DeckLocation, OffDeckType],
@@ -414,6 +414,11 @@ class ProtocolContext(CommandPublisher):
414
414
  version: Optional[int] = None,
415
415
  adapter: Optional[str] = None,
416
416
  lid: Optional[str] = None,
417
+ *,
418
+ adapter_namespace: Optional[str] = None,
419
+ adapter_version: Optional[int] = None,
420
+ lid_namespace: Optional[str] = None,
421
+ lid_version: Optional[int] = None,
417
422
  ) -> Labware:
418
423
  """Load a labware onto a location.
419
424
 
@@ -454,18 +459,52 @@ class ProtocolContext(CommandPublisher):
454
459
  :param version: The version of the labware definition. You should normally
455
460
  leave this unspecified to let ``load_labware()`` choose a version
456
461
  automatically.
457
- :param adapter: An adapter to load the labware on top of. Accepts the same
458
- values as the ``load_name`` parameter of :py:meth:`.load_adapter`. The
459
- adapter will use the same namespace as the labware, and the API will
460
- choose the adapter's version automatically.
461
462
 
462
- .. versionadded:: 2.15
463
+ :param adapter: The load name of an adapter to load the labware on top of. Accepts
464
+ the same values as the ``load_name`` parameter of :py:meth:`.load_adapter`.
465
+
466
+ .. versionadded:: 2.15
467
+
468
+ :param adapter_namespace: The namespace of the adapter being loaded.
469
+ Applies to ``adapter`` the same way that ``namespace`` applies to ``load_name``.
470
+
471
+ .. versionchanged:: 2.26
472
+ ``adapter_namespace`` may now be specified explicitly.
473
+ Also, when you've specified ``namespace`` but not ``adapter_namespace``,
474
+ ``adapter_namespace`` will now independently follow the same search rules
475
+ described in ``namespace``. Formerly, it took ``namespace``'s exact value.
476
+
477
+ :param adapter_version: The version of the adapter being loaded.
478
+ Applies to ``adapter`` the same way that ``version`` applies to ``load_name``.
479
+
480
+ .. versionchanged:: 2.26
481
+ ``adapter_version`` may now be specified explicitly. Also, when it's unspecified,
482
+ the algorithm to select a version automatically has improved to avoid
483
+ selecting versions that do not exist.
484
+
463
485
  :param lid: A lid to load on the top of the main labware. Accepts the same
464
486
  values as the ``load_name`` parameter of :py:meth:`.load_lid_stack`. The
465
487
  lid will use the same namespace as the labware, and the API will
466
488
  choose the lid's version automatically.
467
489
 
468
- .. versionadded:: 2.23
490
+ .. versionadded:: 2.23
491
+
492
+ :param lid_namespace: The namespace of the lid being loaded.
493
+ Applies to ``lid`` the same way that ``namespace`` applies to ``load_name``.
494
+
495
+ .. versionchanged:: 2.26
496
+ ``lid_namespace`` may now be specified explicitly.
497
+ Also, when you've specified ``namespace`` but not ``lid_namespace``,
498
+ ``lid_namespace`` will now independently follow the same search rules
499
+ described in ``namespace``. Formerly, it took ``namespace``'s exact value.
500
+
501
+ :param lid_version: The version of the adapter being loaded.
502
+ Applies to ``lid`` the same way that ``version`` applies to ``load_name``.
503
+
504
+ .. versionchanged:: 2.26
505
+ ``lid_version`` may now be specified explicitly. Also, when it's unspecified,
506
+ the algorithm to select a version automatically has improved to avoid
507
+ selecting versions that do not exist.
469
508
  """
470
509
 
471
510
  if isinstance(location, OffDeckType) and self._api_version < APIVersion(2, 15):
@@ -475,6 +514,40 @@ class ProtocolContext(CommandPublisher):
475
514
  current_version=f"{self._api_version}",
476
515
  )
477
516
 
517
+ if self._api_version < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE:
518
+ if adapter_namespace is not None:
519
+ raise APIVersionError(
520
+ api_element="The `adapter_namespace` parameter",
521
+ until_version=str(
522
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
523
+ ),
524
+ current_version=str(self._api_version),
525
+ )
526
+ if adapter_version is not None:
527
+ raise APIVersionError(
528
+ api_element="The `adapter_version` parameter",
529
+ until_version=str(
530
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
531
+ ),
532
+ current_version=str(self._api_version),
533
+ )
534
+ if lid_namespace is not None:
535
+ raise APIVersionError(
536
+ api_element="The `lid_namespace` parameter",
537
+ until_version=str(
538
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
539
+ ),
540
+ current_version=str(self._api_version),
541
+ )
542
+ if lid_version is not None:
543
+ raise APIVersionError(
544
+ api_element="The `lid_version` parameter",
545
+ until_version=str(
546
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
547
+ ),
548
+ current_version=str(self._api_version),
549
+ )
550
+
478
551
  load_name = validation.ensure_lowercase_name(load_name)
479
552
  load_location: Union[OffDeckType, DeckSlotName, StagingSlotName, LabwareCore]
480
553
  if adapter is not None:
@@ -484,10 +557,22 @@ class ProtocolContext(CommandPublisher):
484
557
  until_version="2.15",
485
558
  current_version=f"{self._api_version}",
486
559
  )
560
+
561
+ if (
562
+ self._api_version
563
+ < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
564
+ ):
565
+ checked_adapter_namespace = namespace
566
+ checked_adapter_version = None
567
+ else:
568
+ checked_adapter_namespace = adapter_namespace
569
+ checked_adapter_version = adapter_version
570
+
487
571
  loaded_adapter = self.load_adapter(
488
572
  load_name=adapter,
489
573
  location=location,
490
- namespace=namespace,
574
+ namespace=checked_adapter_namespace,
575
+ version=checked_adapter_version,
491
576
  )
492
577
  load_location = loaded_adapter._core
493
578
  elif isinstance(location, OffDeckType):
@@ -512,11 +597,22 @@ class ProtocolContext(CommandPublisher):
512
597
  until_version=f"{validation.LID_STACK_VERSION_GATE}",
513
598
  current_version=f"{self._api_version}",
514
599
  )
600
+
601
+ if (
602
+ self._api_version
603
+ < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
604
+ ):
605
+ checked_lid_namespace = namespace
606
+ checked_lid_version = version
607
+ else:
608
+ checked_lid_namespace = lid_namespace
609
+ checked_lid_version = lid_version
610
+
515
611
  self._core.load_lid(
516
612
  load_name=lid,
517
613
  location=labware_core,
518
- namespace=namespace,
519
- version=version,
614
+ namespace=checked_lid_namespace,
615
+ version=checked_lid_version,
520
616
  )
521
617
 
522
618
  labware = Labware(
@@ -1377,6 +1473,7 @@ class ProtocolContext(CommandPublisher):
1377
1473
  def get_liquid_class(
1378
1474
  self,
1379
1475
  name: str,
1476
+ version: Optional[int] = None,
1380
1477
  ) -> LiquidClass:
1381
1478
  """
1382
1479
  Get an instance of an Opentrons-verified liquid class for use in a Flex protocol.
@@ -1386,12 +1483,14 @@ class ProtocolContext(CommandPublisher):
1386
1483
  - ``"water"``: an Opentrons-verified liquid class based on deionized water.
1387
1484
  - ``"glycerol_50"``: an Opentrons-verified liquid class for viscous liquid. Based on 50% glycerol.
1388
1485
  - ``"ethanol_80"``: an Opentrons-verified liquid class for volatile liquid. Based on 80% ethanol.
1486
+ :param version: The version of the liquid class to retrieve. If left unspecified, the latest definition for the
1487
+ protocol's API version will be loaded.
1389
1488
 
1390
1489
  :raises: ``LiquidClassDefinitionDoesNotExist``: if the specified liquid class does not exist.
1391
1490
 
1392
1491
  :returns: A new LiquidClass object.
1393
1492
  """
1394
- return self._core.get_liquid_class(name=name, version=DEFAULT_LC_VERSION)
1493
+ return self._core.get_liquid_class(name=name, version=version)
1395
1494
 
1396
1495
  @requires_version(2, 24)
1397
1496
  def define_liquid_class(
@@ -1461,6 +1560,9 @@ class ProtocolContext(CommandPublisher):
1461
1560
  adapter: Optional[str] = None,
1462
1561
  namespace: Optional[str] = None,
1463
1562
  version: Optional[int] = None,
1563
+ *,
1564
+ adapter_namespace: Optional[str] = None,
1565
+ adapter_version: Optional[int] = None,
1464
1566
  ) -> Labware:
1465
1567
  """
1466
1568
  Load a stack of Opentrons Tough Auto-Sealing Lids onto a valid deck location or adapter.
@@ -1468,13 +1570,17 @@ class ProtocolContext(CommandPublisher):
1468
1570
  :param str load_name: A string to use for looking up a lid definition.
1469
1571
  You can find the ``load_name`` for any compatible lid on the Opentrons
1470
1572
  `Labware Library <https://labware.opentrons.com>`_.
1573
+
1471
1574
  :param location: Either a :ref:`deck slot <deck-slots>`,
1472
1575
  like ``1``, ``"1"``, or ``"D1"``, or a valid Opentrons Adapter.
1576
+
1473
1577
  :param int quantity: The quantity of lids to be loaded in the stack.
1578
+
1474
1579
  :param adapter: An adapter to load the lid stack on top of. Accepts the same
1475
1580
  values as the ``load_name`` parameter of :py:meth:`.load_adapter`. The
1476
1581
  adapter will use the same namespace as the lid labware, and the API will
1477
1582
  choose the adapter's version automatically.
1583
+
1478
1584
  :param str namespace: The namespace that the lid labware definition belongs to.
1479
1585
  If unspecified, the API will automatically search two namespaces:
1480
1586
 
@@ -1490,6 +1596,21 @@ class ProtocolContext(CommandPublisher):
1490
1596
  leave this unspecified to let ``load_lid_stack()`` choose a version
1491
1597
  automatically.
1492
1598
 
1599
+ :param adapter_namespace: The namespace of the adapter being loaded.
1600
+ Applies to ``adapter`` the same way that ``namespace`` applies to ``load_name``.
1601
+
1602
+ .. versionchanged:: 2.26
1603
+ ``adapter_namespace`` may now be specified explicitly.
1604
+ Also, when you've specified ``namespace`` but not ``adapter_namespace``,
1605
+ ``adapter_namespace`` will now independently follow the same search rules
1606
+ described in ``namespace``. Formerly, it took ``namespace``'s exact value.
1607
+
1608
+ :param adapter_version: The version of the adapter being loaded.
1609
+ Applies to ``adapter`` the same way that ``version`` applies to ``load_name``.
1610
+
1611
+ .. versionadded:: 2.26
1612
+ ``adapter_version`` may now be specified explicitly.
1613
+
1493
1614
  :return: The initialized and loaded labware object representing the lid stack.
1494
1615
 
1495
1616
  .. versionadded:: 2.23
@@ -1502,6 +1623,24 @@ class ProtocolContext(CommandPublisher):
1502
1623
  current_version=f"{self._api_version}",
1503
1624
  )
1504
1625
 
1626
+ if self._api_version < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE:
1627
+ if adapter_namespace is not None:
1628
+ raise APIVersionError(
1629
+ api_element="The `adapter_namespace` parameter",
1630
+ until_version=str(
1631
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
1632
+ ),
1633
+ current_version=str(self._api_version),
1634
+ )
1635
+ if adapter_version is not None:
1636
+ raise APIVersionError(
1637
+ api_element="The `adapter_version` parameter",
1638
+ until_version=str(
1639
+ validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
1640
+ ),
1641
+ current_version=str(self._api_version),
1642
+ )
1643
+
1505
1644
  load_location: Union[DeckSlotName, StagingSlotName, LabwareCore]
1506
1645
  if isinstance(location, Labware):
1507
1646
  load_location = location._core
@@ -1514,10 +1653,21 @@ class ProtocolContext(CommandPublisher):
1514
1653
  if isinstance(load_location, DeckSlotName) or isinstance(
1515
1654
  load_location, StagingSlotName
1516
1655
  ):
1656
+ if (
1657
+ self._api_version
1658
+ < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
1659
+ ):
1660
+ checked_adapter_namespace = namespace
1661
+ checked_adapter_version = None
1662
+ else:
1663
+ checked_adapter_namespace = adapter_namespace
1664
+ checked_adapter_version = adapter_version
1665
+
1517
1666
  loaded_adapter = self.load_adapter(
1518
1667
  load_name=adapter,
1519
1668
  location=load_location.value,
1520
- namespace=namespace,
1669
+ namespace=checked_adapter_namespace,
1670
+ version=checked_adapter_version,
1521
1671
  )
1522
1672
  load_location = loaded_adapter._core
1523
1673
  else:
@@ -62,6 +62,10 @@ LID_STACK_VERSION_GATE = APIVersion(2, 23)
62
62
  # The first APIVersion where Python protocols can use the Flex Stacker module.
63
63
  FLEX_STACKER_VERSION_GATE = APIVersion(2, 23)
64
64
 
65
+ # The first APIVersion where various "multi labware load" methods allow you to specify
66
+ # the namespace and version of adapters and lids separately from the main labware.
67
+ NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE = APIVersion(2, 26)
68
+
65
69
 
66
70
  class InvalidPipetteMountError(ValueError):
67
71
  """An error raised when attempting to load pipettes on an invalid mount."""
@@ -20,6 +20,7 @@ from .flex_stacker.common import (
20
20
  FlexStackerHopperError,
21
21
  FlexStackerLabwareRetrieveError,
22
22
  FlexStackerShuttleOccupiedError,
23
+ FlexStackerLabwareStoreError,
23
24
  )
24
25
 
25
26
  from . import absorbance_reader
@@ -948,6 +949,7 @@ CommandDefinedErrorData = Union[
948
949
  DefinedErrorData[FlexStackerHopperError],
949
950
  DefinedErrorData[FlexStackerLabwareRetrieveError],
950
951
  DefinedErrorData[FlexStackerShuttleOccupiedError],
952
+ DefinedErrorData[FlexStackerLabwareStoreError],
951
953
  ]
952
954
 
953
955
 
@@ -148,6 +148,19 @@ class FlexStackerLabwareRetrieveError(ErrorOccurrence):
148
148
  errorInfo: FailedLabware
149
149
 
150
150
 
151
+ class FlexStackerLabwareStoreError(ErrorOccurrence):
152
+ """Returned when the labware was not able to get to the shuttle."""
153
+
154
+ isDefined: bool = True
155
+ errorType: Literal[
156
+ "flexStackerLabwareStoreFailed"
157
+ ] = "flexStackerLabwareStoreFailed"
158
+
159
+ errorCode: str = ErrorCodes.STACKER_SHUTTLE_LABWARE_FAILED.value.code
160
+ detail: str = ErrorCodes.STACKER_SHUTTLE_LABWARE_FAILED.value.detail
161
+ errorInfo: FailedLabware
162
+
163
+
151
164
  class FlexStackerShuttleOccupiedError(ErrorOccurrence):
152
165
  """Returned when the Flex Stacker Shuttle is occupied when it shouldn't be."""
153
166
 
@@ -10,6 +10,7 @@ from opentrons_shared_data.labware.labware_definition import LabwareDefinition
10
10
  from opentrons_shared_data.errors.exceptions import (
11
11
  FlexStackerStallError,
12
12
  FlexStackerShuttleMissingError,
13
+ FlexStackerShuttleLabwareError,
13
14
  )
14
15
 
15
16
  from ..command import (
@@ -22,6 +23,7 @@ from ..command import (
22
23
  from ..flex_stacker.common import (
23
24
  FlexStackerStallOrCollisionError,
24
25
  FlexStackerShuttleError,
26
+ FlexStackerLabwareStoreError,
25
27
  labware_locations_for_group,
26
28
  labware_location_base_sequence,
27
29
  primary_location_sequence,
@@ -115,7 +117,8 @@ class StoreResult(BaseModel):
115
117
  _ExecuteReturn = Union[
116
118
  SuccessData[StoreResult],
117
119
  DefinedErrorData[FlexStackerStallOrCollisionError]
118
- | DefinedErrorData[FlexStackerShuttleError],
120
+ | DefinedErrorData[FlexStackerShuttleError]
121
+ | DefinedErrorData[FlexStackerLabwareStoreError],
119
122
  ]
120
123
 
121
124
 
@@ -180,7 +183,7 @@ class StoreImpl(AbstractCommandImpl[StoreParams, _ExecuteReturn]):
180
183
  )
181
184
  return labware_ids[0], None, lid_id
182
185
 
183
- async def execute(self, params: StoreParams) -> _ExecuteReturn:
186
+ async def execute(self, params: StoreParams) -> _ExecuteReturn: # noqa: C901
184
187
  """Execute the labware storage command."""
185
188
  stacker_state = self._state_view.modules.get_flex_stacker_substate(
186
189
  params.moduleId
@@ -250,6 +253,21 @@ class StoreImpl(AbstractCommandImpl[StoreParams, _ExecuteReturn]):
250
253
  errorInfo={"labwareId": primary_id},
251
254
  ),
252
255
  )
256
+ except FlexStackerShuttleLabwareError as e:
257
+ return DefinedErrorData(
258
+ public=FlexStackerLabwareStoreError(
259
+ id=self._model_utils.generate_id(),
260
+ createdAt=self._model_utils.get_timestamp(),
261
+ wrappedErrors=[
262
+ ErrorOccurrence.from_failed(
263
+ id=self._model_utils.generate_id(),
264
+ createdAt=self._model_utils.get_timestamp(),
265
+ error=e,
266
+ )
267
+ ],
268
+ errorInfo={"labwareId": primary_id},
269
+ ),
270
+ )
253
271
 
254
272
  id_list = [
255
273
  id for id in (primary_id, maybe_adapter_id, maybe_lid_id) if id is not None
@@ -234,23 +234,17 @@ class LabwareMovementHandler:
234
234
  # we only want to check position after the gripper has opened and
235
235
  # should be holding labware
236
236
  if holding_labware:
237
- labware_bbox = self._state_store.labware.get_dimensions(
238
- labware_definition=labware_definition
239
- )
240
- well_bbox = self._state_store.labware.get_well_bbox(
237
+ grip_specs = self._state_store.labware.get_gripper_width_specs(
241
238
  labware_definition=labware_definition
242
239
  )
240
+
243
241
  # todo(mm, 2024-09-26): This currently raises a lower-level 2015 FailedGripperPickupError.
244
242
  # Convert this to a higher-level 3001 LabwareDroppedError or 3002 LabwareNotPickedUpError,
245
243
  # depending on what waypoint we're at, to propagate a more specific error code to users.
246
244
  ot3api.raise_error_if_gripper_pickup_failed(
247
- expected_grip_width=labware_bbox.y,
248
- grip_width_uncertainty_wider=abs(
249
- max(well_bbox.y - labware_bbox.y, 0)
250
- ),
251
- grip_width_uncertainty_narrower=abs(
252
- min(well_bbox.y - labware_bbox.y, 0)
253
- ),
245
+ expected_grip_width=grip_specs.targetY,
246
+ grip_width_uncertainty_wider=grip_specs.uncertaintyWider,
247
+ grip_width_uncertainty_narrower=grip_specs.uncertaintyNarrower,
254
248
  )
255
249
  await ot3api.move_to(
256
250
  mount=gripper_mount, abs_position=waypoint_data.position
@@ -46,6 +46,7 @@ from ..types import (
46
46
  AddressableAreaLocation,
47
47
  NonStackedLocation,
48
48
  Dimensions,
49
+ GripSpecs,
49
50
  LabwareOffset,
50
51
  LabwareOffsetVector,
51
52
  LabwareOffsetLocationSequence,
@@ -1430,3 +1431,68 @@ class LabwareView:
1430
1431
  ):
1431
1432
  return Dimensions(0, 0, 0)
1432
1433
  return Dimensions(max_x - min_x, max_y - min_y, max_z)
1434
+
1435
+ def _gripper_uncertainty_narrower(
1436
+ self, labware_bbox: Dimensions, well_bbox: Dimensions, target_grip_width: float
1437
+ ) -> float:
1438
+ """Most narrower the gripper can be than the target while still likely gripping successfully.
1439
+
1440
+ This number can't just be the 0, because that is not going to be accurate if the labware is
1441
+ skirted - the dimensions are a full bounding box including the skirt, and the labware is
1442
+ narrower than that at the point where it is gripped. The general heuristic is that we can't
1443
+ get to the wells; but some labware don't have wells, so we need alternate values.
1444
+
1445
+ The number will be interpreted relative to the target width, which is (for now) the labware
1446
+ outer bounding box.
1447
+
1448
+ TODO: This should be a number looked up from the definition.
1449
+ """
1450
+ if well_bbox.y == 0:
1451
+ # This labware has no wells; use a fixed minimum
1452
+ return 5
1453
+ if well_bbox.y > labware_bbox.y:
1454
+ # This labware has a very odd definition with wells outside its dimensions.
1455
+ # Return the smaller value.
1456
+ return 0
1457
+ # An ok heuristic for successful grip is if we don't get all the way to the wells.
1458
+ return target_grip_width - well_bbox.y
1459
+
1460
+ def _gripper_uncertainty_wider(
1461
+ self, labware_bbox: Dimensions, well_bbox: Dimensions, target_grip_width: float
1462
+ ) -> float:
1463
+ """Most wider the gripper can be than the target while still likely gripping successfully.
1464
+
1465
+ This can be a lot closer to 0, since the bounding box of the labware will certainly be the
1466
+ widest point (if it's defined without error), but since there might be error in the
1467
+ definition we allow some slop.
1468
+
1469
+ The number will be interpreted relative to the target width, which is (for now) the labware
1470
+ outer bounding box.
1471
+
1472
+ TODO: This should be a number looked up from the definition.
1473
+ """
1474
+ # This will be 0 unless the wells are wider than the labware
1475
+ return max(well_bbox.y - target_grip_width, 0)
1476
+
1477
+ def get_gripper_width_specs(
1478
+ self, labware_definition: LabwareDefinition
1479
+ ) -> GripSpecs:
1480
+ """Get the target and bounds for a successful grip of this labware."""
1481
+ outer_bounds = self.get_dimensions(labware_definition=labware_definition)
1482
+ well_bounds = self.get_well_bbox(labware_definition=labware_definition)
1483
+ narrower = self._gripper_uncertainty_narrower(
1484
+ labware_bbox=outer_bounds,
1485
+ well_bbox=well_bounds,
1486
+ target_grip_width=outer_bounds.y,
1487
+ )
1488
+ wider = self._gripper_uncertainty_wider(
1489
+ labware_bbox=outer_bounds,
1490
+ well_bbox=well_bounds,
1491
+ target_grip_width=outer_bounds.y,
1492
+ )
1493
+ return GripSpecs(
1494
+ # TODO: This should be a number looked up from the definition.
1495
+ targetY=outer_bounds.y,
1496
+ uncertaintyNarrower=narrower,
1497
+ uncertaintyWider=wider,
1498
+ )
@@ -102,6 +102,7 @@ from .labware import (
102
102
  LoadedLabware,
103
103
  LabwareParentDefinition,
104
104
  LabwareWellId,
105
+ GripSpecs,
105
106
  )
106
107
  from .liquid import HexColor, EmptyLiquidId, LiquidId, Liquid, FluidKind, AspiratedFluid
107
108
  from .labware_offset_location import (
@@ -257,6 +258,7 @@ __all__ = [
257
258
  "LabwareOffsetVector",
258
259
  "LabwareParentDefinition",
259
260
  "LabwareWellId",
261
+ "GripSpecs",
260
262
  # Liquids
261
263
  "HexColor",
262
264
  "EmptyLiquidId",
@@ -23,6 +23,15 @@ from .module import ModuleDefinition
23
23
  from .deck_configuration import DeckLocationDefinition
24
24
 
25
25
 
26
+ @dataclass(frozen=True)
27
+ class GripSpecs:
28
+ """Data for how a labware should be gripped."""
29
+
30
+ uncertaintyWider: float
31
+ uncertaintyNarrower: float
32
+ targetY: float
33
+
34
+
26
35
  class OverlapOffset(Vec3f):
27
36
  """Offset representing overlap space of one labware on top of another labware or module."""
28
37
 
@@ -1,6 +1,6 @@
1
1
  from .types import APIVersion
2
2
 
3
- MAX_SUPPORTED_VERSION = APIVersion(2, 25)
3
+ MAX_SUPPORTED_VERSION = APIVersion(2, 26)
4
4
  """The maximum supported protocol API version in this release."""
5
5
 
6
6
  MIN_SUPPORTED_VERSION = APIVersion(2, 0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opentrons
3
- Version: 8.6.0a12
3
+ Version: 8.7.0a0
4
4
  Summary: The Opentrons API is a simple framework designed to make writing automated biology lab protocols easy.
5
5
  Project-URL: opentrons.com, https://www.opentrons.com
6
6
  Project-URL: Source Code On Github, https://github.com/Opentrons/opentrons/tree/edge/api
@@ -24,7 +24,7 @@ Requires-Dist: click<9,>=8.0.0
24
24
  Requires-Dist: importlib-metadata>=1.0; python_version < '3.8'
25
25
  Requires-Dist: jsonschema<4.18.0,>=3.0.1
26
26
  Requires-Dist: numpy<2,>=1.20.0
27
- Requires-Dist: opentrons-shared-data==8.6.0a12
27
+ Requires-Dist: opentrons-shared-data==8.7.0a0
28
28
  Requires-Dist: packaging>=21.0
29
29
  Requires-Dist: pydantic-settings<3,>=2
30
30
  Requires-Dist: pydantic<3,>=2.0.0
@@ -32,6 +32,6 @@ Requires-Dist: pyserial>=3.5
32
32
  Requires-Dist: pyusb==1.2.1
33
33
  Requires-Dist: typing-extensions<5,>=4.0.0
34
34
  Provides-Extra: flex-hardware
35
- Requires-Dist: opentrons-hardware[flex]==8.6.0a12; extra == 'flex-hardware'
35
+ Requires-Dist: opentrons-hardware[flex]==8.7.0a0; extra == 'flex-hardware'
36
36
  Provides-Extra: ot2-hardware
37
- Requires-Dist: opentrons-hardware==8.6.0a12; extra == 'ot2-hardware'
37
+ Requires-Dist: opentrons-hardware==8.7.0a0; extra == 'ot2-hardware'
@@ -1,5 +1,5 @@
1
1
  opentrons/__init__.py,sha256=TQ_Ca_zzAM3iLzAysWKkFkQHG8-imihxDPQbLCYrf-E,4533
2
- opentrons/_version.py,sha256=Ej-eiQxj2liXf3S-OFMSv77mR8rEtkyJT0yFtbesf_E,714
2
+ opentrons/_version.py,sha256=d3ve2LJJuyjX8J_41fIn96U4XlDfRGAll6nNIi4dBwY,712
3
3
  opentrons/execute.py,sha256=Y88qICDiHWQjU0L4Ou7DI5OXXu7zZcdkUvNUYmZqIfc,29282
4
4
  opentrons/legacy_broker.py,sha256=XnuEBBlrHCThc31RFW2UR0tGqctqWZ-CZ9vSC4L9whU,1553
5
5
  opentrons/ordered_set.py,sha256=g-SB3qA14yxHu9zjGyc2wC7d2TUCBE6fKZlHAtbPzI8,4082
@@ -105,7 +105,7 @@ opentrons/hardware_control/module_control.py,sha256=0mmVH9fiZWNyc33ilCpJHajX1Dfh
105
105
  opentrons/hardware_control/motion_utilities.py,sha256=7VG60YQ9MSMAZ0hO-q-kRAdkcebzrx7uIPtc6FMCViE,10311
106
106
  opentrons/hardware_control/nozzle_manager.py,sha256=dqD8XlYsOu0PFFyxvmsMypBB52Gi6x-VIwhykV7JhuU,16868
107
107
  opentrons/hardware_control/ot3_calibration.py,sha256=vHB17U-FBzytvM8QeEu5kRYPo8lFwAo31ZEpiU4yf_0,45000
108
- opentrons/hardware_control/ot3api.py,sha256=E8WNL-9Y-tGdkyWeDVysxqHQR_DfK5RAiKulS_365EI,127869
108
+ opentrons/hardware_control/ot3api.py,sha256=1vPsaNPmtjsJI1EJF8JPKOd2Bj2GDJLvmKU8eMKGhi8,127869
109
109
  opentrons/hardware_control/pause_manager.py,sha256=wmNmraimE2yZQVqCxX_rtQHUWRzpzyQEaym9fLMgyww,888
110
110
  opentrons/hardware_control/poller.py,sha256=rx6Q-UxbUIj3ek69IlYenFh7BFuasszRO-GzzhRPuHQ,3885
111
111
  opentrons/hardware_control/robot_calibration.py,sha256=ilszGjZPspKiEk8MQPaHm2B-ljeisAYflKl8UyQ_D0U,7155
@@ -119,8 +119,8 @@ opentrons/hardware_control/backends/controller.py,sha256=MOVMq9s1rY_jHhajHB1hQ1M
119
119
  opentrons/hardware_control/backends/errors.py,sha256=ZiVP16exHMTWWOajxffnXEqI6NNfeTw-4RkhXE0EBJA,249
120
120
  opentrons/hardware_control/backends/estop_state.py,sha256=_GYjI6OaD3CZNduWV2_RVeOtQ4K_Fg-SP8yU01ENhCY,6554
121
121
  opentrons/hardware_control/backends/flex_protocol.py,sha256=3S-OHbAnOSTF5PxzhMxD0TdEfxurLwecBrDkedl2O3s,13185
122
- opentrons/hardware_control/backends/ot3controller.py,sha256=R_BhVNuycoQyWJngFj4oCoCiOVAkT9yGqjLhP4rcN3g,70641
123
- opentrons/hardware_control/backends/ot3simulator.py,sha256=lmef2w4KeyHqswGAwsr9RTKO0OclH3h6snq7osEoRik,30385
122
+ opentrons/hardware_control/backends/ot3controller.py,sha256=w0LMGu0WWkGd4cEWaqlhMk1NQFHg1-Di83s5_KrKP3U,71374
123
+ opentrons/hardware_control/backends/ot3simulator.py,sha256=CtYnb7NpqIc1TNK91hI0UaK4OyaIecFDczsb-T7DX_w,30387
124
124
  opentrons/hardware_control/backends/ot3utils.py,sha256=HYlIZRGmLqudS1mIt0Io2LxQ1BrLrxVFQCjqudbTUWU,22374
125
125
  opentrons/hardware_control/backends/simulator.py,sha256=q_9PQlBdOyCa9sj2gLqYWZ-fG9v4mddDAiScL-yHCXY,17549
126
126
  opentrons/hardware_control/backends/status_bar_state.py,sha256=E8z9dCJDI3Nb4qfUA5y2_PrE2jSYzZJQVkk75UqY5ZE,9287
@@ -234,24 +234,25 @@ opentrons/protocol_api/create_protocol_context.py,sha256=wwsZje0L__oDnu1Yrihau32
234
234
  opentrons/protocol_api/deck.py,sha256=94vFceg1SC1bAGd7TvC1ZpYwnJR-VlzurEZ6jkacYeg,8910
235
235
  opentrons/protocol_api/disposal_locations.py,sha256=NRiSGmDR0LnbyEkWSOM-o64uR2fUoB1NWJG7Y7SsJSs,7920
236
236
  opentrons/protocol_api/instrument_context.py,sha256=dOg04iqYnNMJ7XnlHBX3tTGiEahc-7feIuErcevRdwY,141216
237
- opentrons/protocol_api/labware.py,sha256=ZP4QuGadoDp6xtyToupXVSJFnsx4NfWcskRQAH3iU4Y,61443
238
- opentrons/protocol_api/module_contexts.py,sha256=HYQ20RV2c-NNwgObQZNxyvVKmy2Ufkf--ILoRmhkcvA,59988
237
+ opentrons/protocol_api/labware.py,sha256=ZGukS0oE6vOltolNx9ZFXj_HFhm5BRaTnS0tJUKxGsE,63061
238
+ opentrons/protocol_api/module_contexts.py,sha256=cPyay45R3SeBckC4fk8txuC7DZoCSeoVSp1ALCMNipQ,63292
239
239
  opentrons/protocol_api/module_validation_and_errors.py,sha256=ljst-M_KK78GnyG3pyZ_6yoYkMY3HORS1QyQyWrme-U,2250
240
- opentrons/protocol_api/protocol_context.py,sha256=Hzgw3FbCRyd4kWmw4RZwZHJhoGZkmn7ug-Q7JZGCcqs,70298
240
+ opentrons/protocol_api/protocol_context.py,sha256=2F-awiZGGNwwdu2xxkjrVDCuemJaV3z4bSIBZoXVVlY,77105
241
241
  opentrons/protocol_api/robot_context.py,sha256=D6ZdpFX30VTtVUDHitsVjabJQXD5TxOV9_Z6sik1LvE,11891
242
- opentrons/protocol_api/validation.py,sha256=73QwpdK5337yu9g8jvpHHizOD0Mf3m6Wr9S8eikrHIc,28993
242
+ opentrons/protocol_api/validation.py,sha256=jFJcw_ixifViupEFaGrjEcuHyNIHG1gvo-n2jSqGnok,29227
243
243
  opentrons/protocol_api/core/__init__.py,sha256=-g74o8OtBB0LmmOvwkRvPgrHt7fF7T8FRHDj-x_-Onk,736
244
244
  opentrons/protocol_api/core/common.py,sha256=Ne7D4yBC3qywy35jIAC_1xI8HQwYt0HjPRXqIcyP06M,1276
245
245
  opentrons/protocol_api/core/core_map.py,sha256=NX06HEDi5Obmaz0Xwwc_dikH0M-bTnZcfnSdMLdQqms,2074
246
246
  opentrons/protocol_api/core/instrument.py,sha256=ZlEv60tzH5jxP0Wh9eyTc_28ju75RsllkQufMwYdIio,13985
247
247
  opentrons/protocol_api/core/labware.py,sha256=-ZOjkalikXCV3ptehKCNaWGAdKxIdwne8LRFQW9NAm4,4290
248
248
  opentrons/protocol_api/core/module.py,sha256=D8d9Xs_AgI53i8POkK2deUiu92V93Wt9-HG4FDKrHnE,15833
249
- opentrons/protocol_api/core/protocol.py,sha256=3K6D2ClT3-bPySuKJuAPWVwvxD8fTvAKUlQG26I9H4M,8685
249
+ opentrons/protocol_api/core/protocol.py,sha256=Jru2lRuPtgdzpZiuhU6VV6UGN2wbjCSoWm_CAbOVPiU,8695
250
250
  opentrons/protocol_api/core/robot.py,sha256=QMAqj5Oqq3_IhTDyUF4jpWI4j2LRPP9crUiaYD_RUv4,1385
251
251
  opentrons/protocol_api/core/well.py,sha256=Lf89YYEyq-ahRSRIFJw42vxIP8Fw6kzIUh9K1HEijUQ,3487
252
252
  opentrons/protocol_api/core/well_grid.py,sha256=BU28DKaBgEU_JdZ6pEzrwNxmuh6TkO4zlg7Pq1Rf5Xk,1516
253
253
  opentrons/protocol_api/core/engine/__init__.py,sha256=B_5T7zgkWDb1mXPg4NbT-wBkQaK-WVokMMnJRNu7xiM,582
254
254
  opentrons/protocol_api/core/engine/_default_labware_versions.py,sha256=hLKAp33c_eNLpvT5qUt8AOYy6PHhM_JnkdOXaMl80jA,7541
255
+ opentrons/protocol_api/core/engine/_default_liquid_class_versions.py,sha256=MCPKf-7fAULQ4oPVYxiyKHr4AYRAevwA9uhkdur3-kQ,1513
255
256
  opentrons/protocol_api/core/engine/deck_conflict.py,sha256=j3AJ-sYr5e-06UgeGueUldx9B3fn7AhN738kJxZO_vw,14693
256
257
  opentrons/protocol_api/core/engine/exceptions.py,sha256=aZgNrmYEeuPZm21nX_KZYtvyjv5h_zPjxxgPkEV7_bw,725
257
258
  opentrons/protocol_api/core/engine/instrument.py,sha256=lDrCqOZm7ceu1E50EYiSh7qTDMci5cgw4bM-AvLyMjE,98890
@@ -261,7 +262,7 @@ opentrons/protocol_api/core/engine/module_core.py,sha256=qxxcqpH-A4Zil9hHDxnvh4H
261
262
  opentrons/protocol_api/core/engine/overlap_versions.py,sha256=PyGvQtQUg1wzNtkuGZtxwXm019PoIjq7em2JiWaxbXc,675
262
263
  opentrons/protocol_api/core/engine/pipette_movement_conflict.py,sha256=x54RIYtkL1rdzvkSp2JgusLY3EEvY8bX3OwipeVKdsE,15511
263
264
  opentrons/protocol_api/core/engine/point_calculations.py,sha256=C2eF0fvJQGMqQv3DzNhc1-m8HTAXTyTsHPJEPrEUEmo,2502
264
- opentrons/protocol_api/core/engine/protocol.py,sha256=uX-qwATcTXiEUXe9gGDmp1cJ1Xd4eQnyy-q_jpiyAYY,46023
265
+ opentrons/protocol_api/core/engine/protocol.py,sha256=MQNMYNII1OxwaQGsKbOgVtmEH54mjDahzD-WHst9MH8,46247
265
266
  opentrons/protocol_api/core/engine/robot.py,sha256=bzUt23NG-clD-9-QFsV_6nm3fMgSmvYEG9DyyZI1xgw,5366
266
267
  opentrons/protocol_api/core/engine/stringify.py,sha256=GwFgEhFMk-uPfFQhQG_2mkaf4cxaItiY8RW7rZwiooQ,2794
267
268
  opentrons/protocol_api/core/engine/transfer_components_executor.py,sha256=mR59C-e6IHSZthlbQEwmRnh5ye8lhr6a0Qp5CNNi9n8,45211
@@ -273,7 +274,7 @@ opentrons/protocol_api/core/legacy/labware_offset_provider.py,sha256=2DLIby9xmUr
273
274
  opentrons/protocol_api/core/legacy/legacy_instrument_core.py,sha256=mEX2Kmx8vBag7ndk4pCIssKkH9C-FEk0xphDyogCLGQ,27023
274
275
  opentrons/protocol_api/core/legacy/legacy_labware_core.py,sha256=ksal6uzzGcMFEE3Ko2H9cbG8b8u4IprzejkkxdBHwHQ,8579
275
276
  opentrons/protocol_api/core/legacy/legacy_module_core.py,sha256=CFCuXN1g5zE2IXD1I09vkngBlOdDzQjuIaNlJ5tVXnQ,23231
276
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py,sha256=fodiDwsBi1_Yd6Hgf8Kx-iTvky_J6WHmGhwmeRBHqmE,23702
277
+ opentrons/protocol_api/core/legacy/legacy_protocol_core.py,sha256=Owj8Vx3ysQEarPH81PcCpAA0MnVegMkjWXNz5-nRIqg,23712
277
278
  opentrons/protocol_api/core/legacy/legacy_well_core.py,sha256=wxeiPBqaS8YQwRpDGwF7ykJ0s2y3bExwVGpNbUZMmFg,5560
278
279
  opentrons/protocol_api/core/legacy/load_info.py,sha256=r-WaH5ZJb3TRCp_zvbMMh0P4BhbZM8HsBs1K_pU98dk,1857
279
280
  opentrons/protocol_api/core/legacy/module_geometry.py,sha256=lvWFHZ81-JFw-1VZUW1R3yUIb59xpXT6H3jwlRintRo,21082
@@ -305,7 +306,7 @@ opentrons/protocol_engine/commands/aspirate_while_tracking.py,sha256=d8-UBiXmBZ1
305
306
  opentrons/protocol_engine/commands/blow_out.py,sha256=3gboq4x5S8fq7j4ZZGNClXFDlOjcdW1v2g58GPdhaPI,4338
306
307
  opentrons/protocol_engine/commands/blow_out_in_place.py,sha256=jm2XXyJfIP9-AAFwXhD59_13nX18-i6QqpLGb-lK7sI,3391
307
308
  opentrons/protocol_engine/commands/command.py,sha256=1hWH_KWg_WDL4R4VXe1ZH2vO6pYt5SA-ZpuPPF1oV5E,10149
308
- opentrons/protocol_engine/commands/command_unions.py,sha256=MqZ4Otswq--gzPmkZOk7VLdtaOPvmqu4FiCkOWUPo58,27464
309
+ opentrons/protocol_engine/commands/command_unions.py,sha256=_2iINXrl9yc3H8X-AF8YBhYZQHLU0RHFEfl0MwE2H2w,27550
309
310
  opentrons/protocol_engine/commands/comment.py,sha256=-6o07x-MZ6-IvZas84OVFmqF0gAbbKWJZIlGVYThCqM,1638
310
311
  opentrons/protocol_engine/commands/configure_for_volume.py,sha256=wLt7-zJfKrRZhz9E0J9Xu_eayDMVPl8utdUYDMwgzFw,3615
311
312
  opentrons/protocol_engine/commands/configure_nozzle_layout.py,sha256=M_s5Ee03a7sSnbvkibDHzEqZwkca0y8J7F60EnSEq7A,3849
@@ -364,12 +365,12 @@ opentrons/protocol_engine/commands/calibration/calibrate_module.py,sha256=5QZ5zL
364
365
  opentrons/protocol_engine/commands/calibration/calibrate_pipette.py,sha256=YMH2MJ7RI0Nf7xjoXJLPlCuMCs5_Stj8zLj-oHcfnDk,3278
365
366
  opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py,sha256=Y5UI4zcnhhVdfQOYh1N07jkBiVChD0kS_H_ow7_qiCA,5311
366
367
  opentrons/protocol_engine/commands/flex_stacker/__init__.py,sha256=IJLskKdZZOGUA1eOm2e3fiP1C9GyTdbTS6uY6Hc4nUk,1369
367
- opentrons/protocol_engine/commands/flex_stacker/common.py,sha256=MHd3mIGK7JpTvL8NGdKQZFBg5yr20dyY4cJMq4TQqlw,34813
368
+ opentrons/protocol_engine/commands/flex_stacker/common.py,sha256=QHBtKawQxWssm6nSmtIpuJCH6BFlT54k4XQTBNSU8mY,35249
368
369
  opentrons/protocol_engine/commands/flex_stacker/empty.py,sha256=1R0AwQtLn_wfuFH0Og2yAngJU8T_XLqf0a__9CqZQy0,11492
369
370
  opentrons/protocol_engine/commands/flex_stacker/fill.py,sha256=3qhAQxJfaSp4EAFGIUotkrJVuOvdFrwzmkMCa2v6khA,10866
370
371
  opentrons/protocol_engine/commands/flex_stacker/retrieve.py,sha256=kh9Lh-FW-RrXmV4RS8txmTYPfPDKhQhjW0UXr8k0vhc,12763
371
372
  opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py,sha256=5VdqCcBdIHmpWqIJN3rCKeZ6IKwfxAdQTXMTD-KL-5w,12484
372
- opentrons/protocol_engine/commands/flex_stacker/store.py,sha256=8iS77NRj9CVp12S9uVfCJTl-Q0iaJkCQDcOJWZnSeI0,12770
373
+ opentrons/protocol_engine/commands/flex_stacker/store.py,sha256=Ed49qEUc16wo643PztZLYNPhVuLNZbx0lALSvpRYwDk,13632
373
374
  opentrons/protocol_engine/commands/heater_shaker/__init__.py,sha256=ImAPrYSUvP8tI7obvoHmrJbjwLldgGNTnFYRgfXj8hI,2757
374
375
  opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py,sha256=Q7sqFtzUD8wclRLL2PLWjnClIeLtJsiMCobStvzoJKc,2847
375
376
  opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py,sha256=UYeGrTmnGtfw22p0agefI2ZnpukKlIgFcmJv9v58Xnc,2755
@@ -426,7 +427,7 @@ opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.p
426
427
  opentrons/protocol_engine/execution/gantry_mover.py,sha256=LFTPmzuGRuP6IspgXxIEyJIXV0tHkc4UWDDjWFCClYo,26477
427
428
  opentrons/protocol_engine/execution/hardware_stopper.py,sha256=ZlhVYEdFfuKqp5slZBkustXcRPy5fJsw2rmfYzHuJkQ,6127
428
429
  opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py,sha256=BSFLzSSeELAYZCrCUfJZx5DdlrwU06Ur92TYd0T-hzM,9084
429
- opentrons/protocol_engine/execution/labware_movement.py,sha256=Bl-Nx3y5-zMlsxL3fcXV04OyiU1JFyqPJTS1Fir_XkA,12962
430
+ opentrons/protocol_engine/execution/labware_movement.py,sha256=0QnTf98CpYItP1icvNpwUeIa2LUWk4w7yBCUVJw-64g,12656
430
431
  opentrons/protocol_engine/execution/movement.py,sha256=ZU4K4OHnzZYCZbk3RwfSOC6C3T2jtBlvYMppJhJSF08,12749
431
432
  opentrons/protocol_engine/execution/pipetting.py,sha256=cnJYbLiJ2QD1xziD8dkRm0mZG3xOk00klW8Ff8rgSG4,22199
432
433
  opentrons/protocol_engine/execution/queue_worker.py,sha256=LM753TrQzJoKUSIrtcaHDOWLe58zcpx-fUOLVpyDlHM,3302
@@ -463,7 +464,7 @@ opentrons/protocol_engine/state/files.py,sha256=w8xxxg8HY0RqKKEGSfHWfrjV54Gb02O3
463
464
  opentrons/protocol_engine/state/fluid_stack.py,sha256=uwkf0qYk1UX5iU52xmk-e3yLPK8OG-TtMCcBqrkVFpM,5932
464
465
  opentrons/protocol_engine/state/geometry.py,sha256=o8tefXS_Jekdt82dW4HHVJSnsxCsTFJuG6ogtri2wTY,104065
465
466
  opentrons/protocol_engine/state/inner_well_math_utils.py,sha256=UhemsPpcuKwVc-iGXI2-v--miOGNunAnAVznJTVADlQ,20598
466
- opentrons/protocol_engine/state/labware.py,sha256=bmNOa6vDFXa-Iow4x_1zNa3tIcNkUvu1OCg3ED2E4i4,59936
467
+ opentrons/protocol_engine/state/labware.py,sha256=vwagsqSBAIkVj4eupu0pIK6F3idnqqoRWDjVbp4ZwKQ,62977
467
468
  opentrons/protocol_engine/state/liquid_classes.py,sha256=u_z75UYdiFAKG0yB3mr1il4T3qaS0Sotq8sL7KLODP8,2990
468
469
  opentrons/protocol_engine/state/liquids.py,sha256=NoesktcQdJUjIVmet1uqqJPf-rzbo4SGemXwQC295W0,2338
469
470
  opentrons/protocol_engine/state/modules.py,sha256=SM_6j3YfZV4ZXWTGjwxQIVH-jtHEI-YFuJtoMyPBReo,61599
@@ -482,7 +483,7 @@ opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py,sha2
482
483
  opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py,sha256=IJ5zpufz5WSRbJqHOAi-WroDxpsRZz-GvwznIL4v7VQ,2468
483
484
  opentrons/protocol_engine/state/module_substates/temperature_module_substate.py,sha256=w9h6EBM1YY8SeUOlUz5-nW1Zoyce8-zua8Z6mX4sDNg,2310
484
485
  opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py,sha256=fLt2jMsbnfe8Q25vAjloxLBGdx8sotqM34VxbwfegpE,5167
485
- opentrons/protocol_engine/types/__init__.py,sha256=8nOYquZPSvQAqkCz9Jfev86SmQ1Tou-AL5RMMvSz07o,8344
486
+ opentrons/protocol_engine/types/__init__.py,sha256=8zInoWjiYEAir1Frq1ESEdFYj17aBH4zXjxL4odPLR0,8376
486
487
  opentrons/protocol_engine/types/automatic_tip_selection.py,sha256=I_B3iWei1Sl7F7IrMKqOn4S12heZXRnfKvtCTUXIMyM,1118
487
488
  opentrons/protocol_engine/types/command_annotations.py,sha256=5A4k_R_4A2_nGl0K85SKwNlnKA09fUhEIe_mdU55yro,1843
488
489
  opentrons/protocol_engine/types/deck_configuration.py,sha256=3dhkk3Z_PrJvqb26brkEdlyzMAGih_UopoEzu9k6SRk,2422
@@ -490,7 +491,7 @@ opentrons/protocol_engine/types/execution.py,sha256=6g_NvlF4niXjFQwDjkmTgKx-N6I8
490
491
  opentrons/protocol_engine/types/hardware_passthrough.py,sha256=tpTE3XHbRjXWQqY0rgosIfcOAGHqMkOpIU3IpIXgdAA,534
491
492
  opentrons/protocol_engine/types/instrument.py,sha256=sqiY6OKYgI0ViQ2UsuYMkL9MI6OpvdgLzC1mvclrp2M,984
492
493
  opentrons/protocol_engine/types/instrument_sensors.py,sha256=CGcChvuxpRXVJHLZP_wd1ej3XDD9x1S9biugMAnk0tM,1449
493
- opentrons/protocol_engine/types/labware.py,sha256=Htfoqz5lXCJmdib4hYIyXkETTsPZ67bfkZXrO1gmLtk,4441
494
+ opentrons/protocol_engine/types/labware.py,sha256=huIKtzEmWJcWuyKq5jN_3Ra4QXRDUbaK2Ck0O3vV5zU,4615
494
495
  opentrons/protocol_engine/types/labware_movement.py,sha256=BEZIDc-6YhU9LRACi0ozroIxuOIq-tngvrFE22uufjs,577
495
496
  opentrons/protocol_engine/types/labware_offset_location.py,sha256=gXOmIHLD1Hk6OhfhmV9Uf2HN0rIKD6syWSPfYehB9QQ,4237
496
497
  opentrons/protocol_engine/types/labware_offset_vector.py,sha256=2M_q0vSjOyjujt-0NY9NM0asQS27MHYElcFgoKCAZAY,377
@@ -541,7 +542,7 @@ opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py,sha256=w
541
542
  opentrons/protocols/api_support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
542
543
  opentrons/protocols/api_support/constants.py,sha256=pI_zJ8oORr6FUOaF508ttll3KOIYqRRgcwVFwnqZuqc,262
543
544
  opentrons/protocols/api_support/deck_type.py,sha256=cBxm-IQqFyL1QtYTMGtLXOlyuh-67xWgnJSP6rkg8oc,3942
544
- opentrons/protocols/api_support/definitions.py,sha256=vjt7jgMqtntWL2MvYC6pAXcPWJ066Xf4coi3RwbArv8,727
545
+ opentrons/protocols/api_support/definitions.py,sha256=Sg0LIzkncnqTPz-e6EtLxdPmEVhogKkmDv3lTpGfmdI,727
545
546
  opentrons/protocols/api_support/instrument.py,sha256=xbgFKbJU_gL1QjbH_mgGHJx2USQIQisjEkBHiFfYEqA,5712
546
547
  opentrons/protocols/api_support/labware_like.py,sha256=JArK3XIYSMzDJTnpsVg9KNcMBEaRLMllmbV4ZtcI02s,7701
547
548
  opentrons/protocols/api_support/tip_tracker.py,sha256=ztngh5wGworD77ycKHm3_f9EqjT24VFXIAARAGcCPns,7407
@@ -594,8 +595,8 @@ opentrons/util/linal.py,sha256=IlKAP9HkNBBgULeSf4YVwSKHdx9jnCjSr7nvDvlRALg,5753
594
595
  opentrons/util/logging_config.py,sha256=7et4YYuQdWdq_e50U-8vFS_QyNBRgdnqPGAQJm8qrIo,9954
595
596
  opentrons/util/logging_queue_handler.py,sha256=ZsSJwy-oV8DXwpYiZisQ1PbYwmK2cOslD46AcyJ1E4I,2484
596
597
  opentrons/util/performance_helpers.py,sha256=ew7H8XD20iS6-2TJAzbQeyzStZkkE6PzHt_Adx3wbZQ,5172
597
- opentrons-8.6.0a12.dist-info/METADATA,sha256=l9QH2vlXU_XB9ZQoxc0ls8JKOmdyxwzStTlW-DmhdUw,1611
598
- opentrons-8.6.0a12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
599
- opentrons-8.6.0a12.dist-info/entry_points.txt,sha256=fTa6eGCYkvOtv0ov-KVE8LLGetgb35LQLF9x85OWPVw,106
600
- opentrons-8.6.0a12.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
601
- opentrons-8.6.0a12.dist-info/RECORD,,
598
+ opentrons-8.7.0a0.dist-info/METADATA,sha256=U7gGnD5DR1XRNN5e9BqM9v9_NnJFeqsqVZI51jyMnoM,1607
599
+ opentrons-8.7.0a0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
600
+ opentrons-8.7.0a0.dist-info/entry_points.txt,sha256=fTa6eGCYkvOtv0ov-KVE8LLGetgb35LQLF9x85OWPVw,106
601
+ opentrons-8.7.0a0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
602
+ opentrons-8.7.0a0.dist-info/RECORD,,