From 312b861f1738356779c51245720cf5dc3137d1e5 Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Wed, 7 Feb 2024 11:19:34 -0500 Subject: [PATCH 01/10] chore: verbose pypi deploys to catch errors (#14441) * chore: verbose pypi deploys to catch errors * let's push an sdist while we're at it --- .github/actions/python/pypi-deploy/action.yaml | 2 +- api/Makefile | 4 ++-- hardware/Makefile | 4 ++-- scripts/python.mk | 3 ++- shared-data/python/Makefile | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/actions/python/pypi-deploy/action.yaml b/.github/actions/python/pypi-deploy/action.yaml index 1ce4ff67a1e..8f1d9407fe5 100644 --- a/.github/actions/python/pypi-deploy/action.yaml +++ b/.github/actions/python/pypi-deploy/action.yaml @@ -28,7 +28,7 @@ runs: fi fi status=0 - QUIET=1 BUILD_NUMBER=${OT_BUILD} make -C ${{ inputs.project }} clean deploy twine_repository_url=${{ inputs.repository_url }} pypi_username=opentrons pypi_password=${{ inputs.password }} || status=$? + CI=1 QUIET=1 BUILD_NUMBER=${OT_BUILD} make -C ${{ inputs.project }} clean deploy twine_repository_url=${{ inputs.repository_url }} pypi_username=opentrons pypi_password=${{ inputs.password }} || status=$? if [[ ${status} != 0 ]] && [[ ${{ inputs.repository_url }} =~ "test.pypi.org" ]]; then echo "upload failures allowed to test pypi" exit 0 diff --git a/api/Makefile b/api/Makefile index 81d49ea5a83..a10b737ed8d 100755 --- a/api/Makefile +++ b/api/Makefile @@ -199,8 +199,8 @@ emulator: -$(python) -m opentrons.hardware_control.emulation.app .PHONY: deploy -deploy: wheel - $(call python_upload_package,$(twine_auth_args),$(twine_repository_url),$(wheel_file)) +deploy: wheel sdist + $(call python_upload_package,$(twine_auth_args),$(twine_repository_url),$(wheel_file),$(sdist_file)) # User must currently specify host, e.g.: `make term host=169.254.202.176` .PHONY: term diff --git a/hardware/Makefile b/hardware/Makefile index 757beb564f1..45c44d98994 100755 --- a/hardware/Makefile +++ b/hardware/Makefile @@ -144,5 +144,5 @@ emulator: echo "Nothing here yet" .PHONY: deploy -deploy: wheel - $(call python_upload_package,$(twine_auth_args),$(twine_repository_url),$(wheel_file)) +deploy: wheel sdist + $(call python_upload_package,$(twine_auth_args),$(twine_repository_url),$(wheel_file),$(sdist_file)) diff --git a/scripts/python.mk b/scripts/python.mk index 917f6b8b319..64f37721b45 100644 --- a/scripts/python.mk +++ b/scripts/python.mk @@ -68,8 +68,9 @@ endef # parameter 1: auth arguments for twine # parameter 2: repository url # parameter 3: the wheel file to upload +# parameter 4: the sdist to upload define python_upload_package -$(python) -m twine upload --repository-url $(2) $(1) $(3) +$(python) -m twine upload $(and $(CI),--verbose) --repository-url $(2) $(1) $(3) $(4) endef # Get an enhanced version dict of the project diff --git a/shared-data/python/Makefile b/shared-data/python/Makefile index 439d5901574..c1ffe9bd239 100644 --- a/shared-data/python/Makefile +++ b/shared-data/python/Makefile @@ -118,8 +118,8 @@ push-ot3: push-no-restart-ot3 $(call restart-server,$(host),$(ssh_key),$(ssh_opts),opentrons-robot-server) .PHONY: deploy -deploy: wheel - $(call python_upload_package,$(twine_auth_args),$(twine_repository_url),$(wheel_file)) +deploy: wheel sdist + $(call python_upload_package,$(twine_auth_args),$(twine_repository_url),$(wheel_file),$(sdist_file)) .PHONY: test test: From 96f4468ff5ef5032622b39f85d713e1c0226a14f Mon Sep 17 00:00:00 2001 From: Sanniti Pimpley Date: Wed, 7 Feb 2024 11:32:26 -0500 Subject: [PATCH 02/10] feat(api): check all possible collisions with deck items during partial tip movement (#14426) * added pipette bounds fetch and height check on overlapping slots --------- Co-authored-by: CaseyBatten --- .../opentrons/hardware_control/dev_types.py | 2 +- .../hardware_control/nozzle_manager.py | 14 + .../motion_planning/adjacent_slots_getters.py | 91 +++++- .../protocol_api/core/engine/deck_conflict.py | 268 ++++++---------- .../resources/pipette_data_provider.py | 13 + .../state/addressable_areas.py | 48 ++- .../protocol_engine/state/geometry.py | 12 +- .../protocol_engine/state/pipettes.py | 73 ++++- api/src/opentrons/protocol_engine/types.py | 16 +- .../test_adjacent_slots_getters.py | 79 +++++ .../core/engine/test_deck_conflict.py | 290 +++++++++--------- .../test_pipette_movement_deck_conflicts.py | 2 +- .../commands/test_configure_for_volume.py | 3 + .../commands/test_load_pipette.py | 6 +- .../execution/test_equipment_handler.py | 4 +- .../protocol_engine/pipette_fixtures.py | 54 ++++ .../resources/test_pipette_data_provider.py | 23 +- .../state/test_geometry_view.py | 10 +- .../state/test_pipette_store.py | 9 +- .../state/test_pipette_view.py | 220 ++++++++++++- .../protocol_engine/state/test_tip_state.py | 12 + .../gravimetric/overrides/api.patch | 6 +- 22 files changed, 912 insertions(+), 343 deletions(-) diff --git a/api/src/opentrons/hardware_control/dev_types.py b/api/src/opentrons/hardware_control/dev_types.py index 0c4e5ae4ef7..45c0f1bf9b0 100644 --- a/api/src/opentrons/hardware_control/dev_types.py +++ b/api/src/opentrons/hardware_control/dev_types.py @@ -95,7 +95,7 @@ class PipetteDict(InstrumentDict): has_tip: bool default_push_out_volume: Optional[float] supported_tips: Dict[PipetteTipType, SupportedTipsDefinition] - current_nozzle_map: Optional[NozzleMap] + current_nozzle_map: NozzleMap # spp: why was this Optional? class PipetteStateDict(TypedDict): diff --git a/api/src/opentrons/hardware_control/nozzle_manager.py b/api/src/opentrons/hardware_control/nozzle_manager.py index 0f55dfb1151..499ddf4c0f6 100644 --- a/api/src/opentrons/hardware_control/nozzle_manager.py +++ b/api/src/opentrons/hardware_control/nozzle_manager.py @@ -192,6 +192,20 @@ def front_nozzle_offset(self) -> Point: front_left = next(iter(self.columns.values()))[-1] return self.map_store[front_left] + @property + def front_right_nozzle_offset(self) -> Point: + """The offset for the front_right nozzle.""" + # Front-right-most nozzle of the 96 channel in a given configuration + # and Front-most nozzle of the 8-channel + return self.map_store[self.front_right] + + @property + def back_left_nozzle_offset(self) -> Point: + """The offset for the back_left nozzle.""" + # Back-left-most nozzle of the 96-channel in a given configuration + # and back-most nozzle of the 8-channel + return self.map_store[self.back_left] + @property def tip_count(self) -> int: """The total number of active nozzles in the configuration, and thus the number of tips that will be picked up.""" diff --git a/api/src/opentrons/motion_planning/adjacent_slots_getters.py b/api/src/opentrons/motion_planning/adjacent_slots_getters.py index e60a922351e..9644f40f157 100644 --- a/api/src/opentrons/motion_planning/adjacent_slots_getters.py +++ b/api/src/opentrons/motion_planning/adjacent_slots_getters.py @@ -1,6 +1,8 @@ """Getters for specific adjacent slots.""" +from dataclasses import dataclass +from typing import Optional, List, Dict, Union -from typing import Optional, List, Dict +from opentrons_shared_data.robot.dev_types import RobotType from opentrons.types import DeckSlotName, StagingSlotName @@ -37,6 +39,72 @@ def get_west_slot(slot: int) -> Optional[int]: return slot - 1 +def get_north_west_slot(slot: int) -> Optional[int]: + """Get the slot that's north-west of the given slot.""" + if slot in [1, 4, 7, 10, 11, 12]: + return None + else: + north_slot = get_north_slot(slot) + return north_slot - 1 if north_slot else None + + +def get_north_east_slot(slot: int) -> Optional[int]: + """Get the slot that's north-east of the given slot.""" + if slot in [3, 6, 9, 10, 11, 12]: + return None + else: + north_slot = get_north_slot(slot) + return north_slot + 1 if north_slot else None + + +def get_south_west_slot(slot: int) -> Optional[int]: + """Get the slot that's south-west of the given slot.""" + if slot in [1, 2, 3, 4, 7, 10]: + return None + else: + south_slot = get_south_slot(slot) + return south_slot - 1 if south_slot else None + + +def get_south_east_slot(slot: int) -> Optional[int]: + """Get the slot that's south-east of the given slot.""" + if slot in [1, 2, 3, 6, 9, 12]: + return None + else: + south_slot = get_south_slot(slot) + return south_slot + 1 if south_slot else None + + +@dataclass +class _MixedTypeSlots: + regular_slots: List[DeckSlotName] + staging_slots: List[StagingSlotName] + + +def get_surrounding_slots(slot: int, robot_type: RobotType) -> _MixedTypeSlots: + """Get all the surrounding slots, i.e., adjacent slots as well as corner slots.""" + corner_slots: List[Union[int, None]] = [ + get_north_east_slot(slot), + get_north_west_slot(slot), + get_south_east_slot(slot), + get_south_west_slot(slot), + ] + + surrounding_regular_slots_int = get_adjacent_slots(slot) + [ + maybe_slot for maybe_slot in corner_slots if maybe_slot is not None + ] + surrounding_regular_slots = [ + DeckSlotName.from_primitive(slot_int).to_equivalent_for_robot_type(robot_type) + for slot_int in surrounding_regular_slots_int + ] + surrounding_staging_slots = _SURROUNDING_STAGING_SLOTS_MAP.get( + DeckSlotName.from_primitive(slot).to_equivalent_for_robot_type(robot_type), [] + ) + return _MixedTypeSlots( + regular_slots=surrounding_regular_slots, staging_slots=surrounding_staging_slots + ) + + _WEST_OF_STAGING_SLOT_MAP: Dict[StagingSlotName, DeckSlotName] = { StagingSlotName.SLOT_A4: DeckSlotName.SLOT_A3, StagingSlotName.SLOT_B4: DeckSlotName.SLOT_B3, @@ -50,6 +118,22 @@ def get_west_slot(slot: int) -> Optional[int]: } +_SURROUNDING_STAGING_SLOTS_MAP: Dict[DeckSlotName, List[StagingSlotName]] = { + DeckSlotName.SLOT_D3: [StagingSlotName.SLOT_C4, StagingSlotName.SLOT_D4], + DeckSlotName.SLOT_C3: [ + StagingSlotName.SLOT_B4, + StagingSlotName.SLOT_C4, + StagingSlotName.SLOT_D4, + ], + DeckSlotName.SLOT_B3: [ + StagingSlotName.SLOT_A4, + StagingSlotName.SLOT_B4, + StagingSlotName.SLOT_C4, + ], + DeckSlotName.SLOT_A3: [StagingSlotName.SLOT_A4, StagingSlotName.SLOT_B4], +} + + def get_west_of_staging_slot(staging_slot: StagingSlotName) -> DeckSlotName: """Get slot west of a staging slot.""" return _WEST_OF_STAGING_SLOT_MAP[staging_slot] @@ -60,6 +144,11 @@ def get_adjacent_staging_slot(deck_slot: DeckSlotName) -> Optional[StagingSlotNa return _EAST_OF_FLEX_COLUMN_3_MAP.get(deck_slot) +def get_surrounding_staging_slots(deck_slot: DeckSlotName) -> List[StagingSlotName]: + """Get the staging slots surrounding the given deck slot.""" + return _SURROUNDING_STAGING_SLOTS_MAP.get(deck_slot, []) + + def get_east_west_slots(slot: int) -> List[int]: """Get slots east & west of the given slot.""" east = get_east_slot(slot) diff --git a/api/src/opentrons/protocol_api/core/engine/deck_conflict.py b/api/src/opentrons/protocol_api/core/engine/deck_conflict.py index 031ad46acb4..0ba7e17621d 100644 --- a/api/src/opentrons/protocol_api/core/engine/deck_conflict.py +++ b/api/src/opentrons/protocol_api/core/engine/deck_conflict.py @@ -2,19 +2,23 @@ from __future__ import annotations import itertools import logging -from typing import Collection, Dict, Optional, Tuple, overload, Union, TYPE_CHECKING +from typing import ( + Collection, + Dict, + Optional, + Tuple, + overload, + Union, + TYPE_CHECKING, +) from opentrons_shared_data.errors.exceptions import MotionPlanningFailureError from opentrons.hardware_control.nozzle_manager import NozzleConfigurationType from opentrons.hardware_control.modules.types import ModuleType from opentrons.motion_planning import deck_conflict as wrapped_deck_conflict -from opentrons.motion_planning.adjacent_slots_getters import ( - get_north_slot, - get_west_slot, - get_east_slot, - get_south_slot, -) +from opentrons.motion_planning import adjacent_slots_getters + from opentrons.protocol_engine import ( StateView, DeckSlotLocation, @@ -26,6 +30,7 @@ DropTipWellLocation, ) from opentrons.protocol_engine.errors.exceptions import LabwareNotLoadedOnModuleError +from opentrons.protocol_engine.types import StagingSlotLocation, Dimensions from opentrons.types import DeckSlotName, StagingSlotName, Point from ..._trash_bin import TrashBin from ..._waste_chute import WasteChute @@ -190,7 +195,7 @@ def check( ) -def check_safe_for_pipette_movement( +def check_safe_for_pipette_movement( # noqa: C901 engine_state: StateView, pipette_id: str, labware_id: str, @@ -198,6 +203,7 @@ def check_safe_for_pipette_movement( well_location: Union[WellLocation, DropTipWellLocation], ) -> None: """Check if the labware is safe to move to with a pipette in partial tip configuration. + Args: engine_state: engine state view pipette_id: ID of the pipette to be moved @@ -205,26 +211,94 @@ def check_safe_for_pipette_movement( well_name: Name of the well to move to well_location: exact location within the well to move to """ - # TODO: either hide unsupported configurations behind an advance setting - # or log a warning that deck conflicts cannot be checked for tip config other than - # column config with A12 primary nozzle for the 96 channel - # or single tip config for 8-channel. - if engine_state.pipettes.get_channels(pipette_id) == 96: - _check_deck_conflict_for_96_channel( - engine_state=engine_state, + # TODO (spp, 2023-02-06): remove this check after thorough testing. + # This function is capable of checking for movement conflict regardless of + # nozzle configuration. + if not engine_state.pipettes.get_is_partially_configured(pipette_id): + return + + if isinstance(well_location, DropTipWellLocation): + # convert to WellLocation + well_location = engine_state.geometry.get_checked_tip_drop_location( pipette_id=pipette_id, labware_id=labware_id, - well_name=well_name, well_location=well_location, + partially_configured=True, ) - elif engine_state.pipettes.get_channels(pipette_id) == 8: - _check_deck_conflict_for_8_channel( - engine_state=engine_state, + well_location_point = engine_state.geometry.get_well_position( + labware_id=labware_id, well_name=well_name, well_location=well_location + ) + primary_nozzle = engine_state.pipettes.get_primary_nozzle(pipette_id) + + if not _is_within_pipette_extents( + engine_state=engine_state, pipette_id=pipette_id, location=well_location_point + ): + raise PartialTipMovementNotAllowedError( + f"Requested motion with the {primary_nozzle} nozzle partial configuration" + f" is outside of robot bounds for the pipette." + ) + + labware_slot = engine_state.geometry.get_ancestor_slot_name(labware_id) + pipette_bounds_at_well_location = ( + engine_state.pipettes.get_nozzle_bounds_at_specified_move_to_position( pipette_id=pipette_id, - labware_id=labware_id, - well_name=well_name, - well_location=well_location, + destination_position=well_location_point, + ) + ) + surrounding_slots = adjacent_slots_getters.get_surrounding_slots( + slot=labware_slot.as_int(), robot_type=engine_state.config.robot_type + ) + + def _check_conflict_with_slot_item( + surrounding_slot: Union[DeckSlotName, StagingSlotName], + ) -> None: + """Raises error if the pipette is expected to collide with surrounding slot items.""" + # Check if slot overlaps with pipette position + slot_pos = engine_state.addressable_areas.get_addressable_area_position( + addressable_area_name=surrounding_slot.id, + do_compatibility_check=False, + ) + slot_bounds = engine_state.addressable_areas.get_addressable_area_bounding_box( + addressable_area_name=surrounding_slot.id, + do_compatibility_check=False, ) + for bound_vertex in pipette_bounds_at_well_location: + if not _point_overlaps_with_slot( + slot_pos, slot_bounds, nozzle_point=bound_vertex + ): + continue + # Check z-height of items in overlapping slot + if isinstance(surrounding_slot, DeckSlotName): + slot_highest_z = engine_state.geometry.get_highest_z_in_slot( + DeckSlotLocation(slotName=surrounding_slot) + ) + else: + slot_highest_z = engine_state.geometry.get_highest_z_in_slot( + StagingSlotLocation(slotName=surrounding_slot) + ) + if slot_highest_z + Z_SAFETY_MARGIN > pipette_bounds_at_well_location[0].z: + raise PartialTipMovementNotAllowedError( + f"Moving to {engine_state.labware.get_display_name(labware_id)} in slot" + f" {labware_slot} with {primary_nozzle} nozzle partial configuration" + f" will result in collision with items in deck slot {surrounding_slot}." + ) + + for regular_slot in surrounding_slots.regular_slots: + _check_conflict_with_slot_item(regular_slot) + for staging_slot in surrounding_slots.staging_slots: + _check_conflict_with_slot_item(staging_slot) + + +def _point_overlaps_with_slot( + slot_position: Point, + slot_dimensions: Dimensions, + nozzle_point: Point, +) -> bool: + """Check if the given nozzle point overlaps with any slot area in x & y""" + return ( + slot_position.x <= nozzle_point.x <= slot_position.x + slot_dimensions.x + and slot_position.y <= nozzle_point.y <= slot_position.y + slot_dimensions.y + ) def check_safe_for_tip_pickup_and_return( @@ -281,154 +355,8 @@ def check_safe_for_tip_pickup_and_return( ) -def _check_deck_conflict_for_96_channel( - engine_state: StateView, - pipette_id: str, - labware_id: str, - well_name: str, - well_location: Union[WellLocation, DropTipWellLocation], -) -> None: - """Check if there are any conflicts moving to the given labware with the configuration of 96-ch pipette.""" - if not ( - engine_state.pipettes.get_nozzle_layout_type(pipette_id) - == NozzleConfigurationType.COLUMN - ): - # Checking deck conflicts only for column config - return - - if isinstance(well_location, DropTipWellLocation): - # convert to WellLocation - well_location = engine_state.geometry.get_checked_tip_drop_location( - pipette_id=pipette_id, - labware_id=labware_id, - well_location=well_location, - partially_configured=True, - ) - - well_location_point = engine_state.geometry.get_well_position( - labware_id=labware_id, well_name=well_name, well_location=well_location - ) - primary_nozzle = engine_state.pipettes.get_primary_nozzle(pipette_id) - - if not _is_within_pipette_extents( - engine_state=engine_state, pipette_id=pipette_id, location=well_location_point - ): - raise PartialTipMovementNotAllowedError( - f"Requested motion with the {primary_nozzle} nozzle column configuration" - f" is outside of robot bounds for the 96-channel." - ) - - labware_slot = engine_state.geometry.get_ancestor_slot_name(labware_id) - - destination_slot_num = labware_slot.as_int() - adjacent_slot_num = None - # TODO (spp, 2023-12-18): change this eventually to "column 1"/"column 12" - # via the column mappings in the pipette geometry definitions. - if primary_nozzle == "A12": - adjacent_slot_num = get_west_slot(destination_slot_num) - elif primary_nozzle == "A1": - adjacent_slot_num = get_east_slot(destination_slot_num) - - def _check_conflict_with_slot_item( - adjacent_slot: DeckSlotName, - ) -> None: - """Raises error if the pipette is expected to collide with adjacent slot items.""" - slot_highest_z = engine_state.geometry.get_highest_z_in_slot( - DeckSlotLocation(slotName=adjacent_slot) - ) - - pipette_tip = engine_state.pipettes.get_attached_tip(pipette_id) - tip_length = pipette_tip.length if pipette_tip else 0.0 - - if slot_highest_z + Z_SAFETY_MARGIN > well_location_point.z + tip_length: - raise PartialTipMovementNotAllowedError( - f"Moving to {engine_state.labware.get_display_name(labware_id)} in slot" - f" {labware_slot} with pipette column {primary_nozzle} nozzle configuration" - f" will result in collision with items in deck slot {adjacent_slot}." - ) - - if adjacent_slot_num is None: - return - _check_conflict_with_slot_item( - adjacent_slot=DeckSlotName.from_primitive( - adjacent_slot_num - ).to_equivalent_for_robot_type(engine_state.config.robot_type) - ) - - -def _check_deck_conflict_for_8_channel( - engine_state: StateView, - pipette_id: str, - labware_id: str, - well_name: str, - well_location: Union[WellLocation, DropTipWellLocation], -) -> None: - """Check if there are any conflicts moving to the given labware with the configuration of 8-ch pipette.""" - if not ( - engine_state.pipettes.get_nozzle_layout_type(pipette_id) - == NozzleConfigurationType.SINGLE - ): - # Checking deck conflicts only for single tip config - return - - if isinstance(well_location, DropTipWellLocation): - # convert to WellLocation - well_location = engine_state.geometry.get_checked_tip_drop_location( - pipette_id=pipette_id, - labware_id=labware_id, - well_location=well_location, - partially_configured=True, - ) - - well_location_point = engine_state.geometry.get_well_position( - labware_id=labware_id, well_name=well_name, well_location=well_location - ) - primary_nozzle = engine_state.pipettes.get_primary_nozzle(pipette_id) - - if not _is_within_pipette_extents( - engine_state=engine_state, pipette_id=pipette_id, location=well_location_point - ): - # WARNING: (spp, 2023-11-30: this needs to be wired up to check for - # 8-channel pipette extents on both OT2 & Flex!!) - raise PartialTipMovementNotAllowedError( - f"Requested motion with single {primary_nozzle} nozzle configuration" - f" is outside of robot bounds for the 8-channel." - ) - - labware_slot = engine_state.geometry.get_ancestor_slot_name(labware_id) - destination_slot = labware_slot.as_int() - adjacent_slot_num = None - # TODO (spp, 2023-12-18): change this eventually to use nozzles from mappings in - # the pipette geometry definitions. - if primary_nozzle == "H1": - adjacent_slot_num = get_north_slot(destination_slot) - elif primary_nozzle == "A1": - adjacent_slot_num = get_south_slot(destination_slot) - - def _check_conflict_with_slot_item(adjacent_slot: DeckSlotName) -> None: - slot_highest_z = engine_state.geometry.get_highest_z_in_slot( - DeckSlotLocation(slotName=adjacent_slot) - ) - - pipette_tip = engine_state.pipettes.get_attached_tip(pipette_id) - tip_length = pipette_tip.length if pipette_tip else 0.0 - - if slot_highest_z + Z_SAFETY_MARGIN > well_location_point.z + tip_length: - raise PartialTipMovementNotAllowedError( - f"Moving to {engine_state.labware.get_display_name(labware_id)} in slot" - f" {labware_slot} with pipette nozzle {primary_nozzle} configuration" - f" will result in collision with items in deck slot {adjacent_slot}." - ) - - if adjacent_slot_num is None: - return - _check_conflict_with_slot_item( - adjacent_slot=DeckSlotName.from_primitive( - adjacent_slot_num - ).to_equivalent_for_robot_type(engine_state.config.robot_type) - ) - - +# TODO (spp, 2023-02-06): update the extents check to use all nozzle bounds instead of +# just position of primary nozzle when checking if the pipette is out-of-bounds def _is_within_pipette_extents( engine_state: StateView, pipette_id: str, diff --git a/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py b/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py index b3bf334933f..940440826e7 100644 --- a/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py +++ b/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py @@ -18,6 +18,7 @@ ) from ..types import FlowRates +from ...types import Point @dataclass(frozen=True) @@ -36,6 +37,8 @@ class LoadedStaticPipetteData: float, pipette_definition.SupportedTipsDefinition ] nominal_tip_overlap: Dict[str, float] + back_left_nozzle_offset: Point + front_right_nozzle_offset: Point class VirtualPipetteDataProvider: @@ -147,6 +150,7 @@ def _get_virtual_pipette_static_config_by_model( tip_type ] + nozzle_manager = NozzleConfigurationManager.build_from_config(config) return LoadedStaticPipetteData( model=str(pipette_model), display_name=config.display_name, @@ -169,6 +173,8 @@ def _get_virtual_pipette_static_config_by_model( nominal_tip_overlap=config.liquid_properties[ liquid_class ].tip_overlap_dictionary, + back_left_nozzle_offset=nozzle_manager.current_configuration.back_left_nozzle_offset, + front_right_nozzle_offset=nozzle_manager.current_configuration.front_right_nozzle_offset, ) def get_virtual_pipette_static_config( @@ -202,4 +208,11 @@ def get_pipette_static_config(pipette_dict: PipetteDict) -> LoadedStaticPipetteD # https://opentrons.atlassian.net/browse/RCORE-655 home_position=0, nozzle_offset_z=0, + # TODO (spp): Confirm that the nozzle map is populated by the hardware api by default + back_left_nozzle_offset=pipette_dict[ + "current_nozzle_map" + ].back_left_nozzle_offset, + front_right_nozzle_offset=pipette_dict[ + "current_nozzle_map" + ].front_right_nozzle_offset, ) diff --git a/api/src/opentrons/protocol_engine/state/addressable_areas.py b/api/src/opentrons/protocol_engine/state/addressable_areas.py index 5c9e0d77875..add8fa35dc1 100644 --- a/api/src/opentrons/protocol_engine/state/addressable_areas.py +++ b/api/src/opentrons/protocol_engine/state/addressable_areas.py @@ -33,6 +33,7 @@ AddressableArea, PotentialCutoutFixture, DeckConfigurationType, + Dimensions, ) from ..actions import Action, UpdateCommandAction, PlayAction, AddAddressableAreaAction from .config import Config @@ -329,7 +330,10 @@ def get_addressable_area(self, addressable_area_name: str) -> AddressableArea: if not self._state.use_simulated_deck_config: return self._get_loaded_addressable_area(addressable_area_name) else: - return self._get_addressable_area_from_deck_data(addressable_area_name) + return self._get_addressable_area_from_deck_data( + addressable_area_name=addressable_area_name, + do_compatibility_check=True, + ) def get_all(self) -> List[str]: """Get a list of all loaded addressable area names.""" @@ -389,7 +393,9 @@ def _check_if_area_is_compatible_with_potential_fixtures( ) def _get_addressable_area_from_deck_data( - self, addressable_area_name: str + self, + addressable_area_name: str, + do_compatibility_check: bool, ) -> AddressableArea: """Get an addressable area that may not have been already loaded for a simulated run. @@ -407,9 +413,10 @@ def _get_addressable_area_from_deck_data( addressable_area_name, self._state.deck_definition ) - self._check_if_area_is_compatible_with_potential_fixtures( - addressable_area_name, cutout_id, potential_fixtures - ) + if do_compatibility_check: + self._check_if_area_is_compatible_with_potential_fixtures( + addressable_area_name, cutout_id, potential_fixtures + ) cutout_position = deck_configuration_provider.get_cutout_position( cutout_id, self._state.deck_definition @@ -429,7 +436,11 @@ def get_addressable_area_base_slot( addressable_area = self.get_addressable_area(addressable_area_name) return addressable_area.base_slot - def get_addressable_area_position(self, addressable_area_name: str) -> Point: + def get_addressable_area_position( + self, + addressable_area_name: str, + do_compatibility_check: bool = True, + ) -> Point: """Get the position of an addressable area. This does not require the addressable area to be in the deck configuration. @@ -441,11 +452,29 @@ def get_addressable_area_position(self, addressable_area_name: str) -> Point: areas that have been pre-validated, otherwise there could be the risk of collision. """ addressable_area = self._get_addressable_area_from_deck_data( - addressable_area_name + addressable_area_name=addressable_area_name, + do_compatibility_check=do_compatibility_check, ) position = addressable_area.position return Point(x=position.x, y=position.y, z=position.z) + def get_addressable_area_bounding_box( + self, + addressable_area_name: str, + do_compatibility_check: bool = True, + ) -> Dimensions: + """Get the bounding box of an addressable area. + + This does not require the addressable area to be in the deck configuration. + For movement purposes, this should only be called for + areas that have been pre-validated, otherwise there could be the risk of collision. + """ + addressable_area = self._get_addressable_area_from_deck_data( + addressable_area_name=addressable_area_name, + do_compatibility_check=do_compatibility_check, + ) + return addressable_area.bounding_box + def get_addressable_area_move_to_location( self, addressable_area_name: str ) -> Point: @@ -509,7 +538,10 @@ def get_slot_definition(self, slot_id: str) -> SlotDefV3: This does not require that the slot exist in deck configuration. """ try: - addressable_area = self._get_addressable_area_from_deck_data(slot_id) + addressable_area = self._get_addressable_area_from_deck_data( + addressable_area_name=slot_id, + do_compatibility_check=True, # From the description of get_slot_definition, this might have to be False. + ) except AddressableAreaDoesNotExistError: raise SlotDoesNotExistError( f"Slot ID {slot_id} does not exist in deck {self._state.deck_definition['otId']}" diff --git a/api/src/opentrons/protocol_engine/state/geometry.py b/api/src/opentrons/protocol_engine/state/geometry.py index 0762dbe452e..88fb7861b98 100644 --- a/api/src/opentrons/protocol_engine/state/geometry.py +++ b/api/src/opentrons/protocol_engine/state/geometry.py @@ -4,9 +4,11 @@ from typing import Optional, List, Tuple, Union, cast, TypeVar, Dict from opentrons.types import Point, DeckSlotName, StagingSlotName, MountType -from opentrons_shared_data.labware.constants import WELL_NAME_PATTERN +from opentrons_shared_data.labware.constants import WELL_NAME_PATTERN from opentrons_shared_data.deck.dev_types import CutoutFixture +from opentrons_shared_data.pipette import PIPETTE_X_SPAN +from opentrons_shared_data.pipette.dev_types import ChannelCount from .. import errors from ..errors import ( @@ -39,6 +41,7 @@ OnDeckLabwareLocation, AddressableAreaLocation, AddressableOffsetVector, + StagingSlotLocation, ) from .config import Config from .labware import LabwareView @@ -46,9 +49,6 @@ from .pipettes import PipetteView from .addressable_areas import AddressableAreaView -from opentrons_shared_data.pipette import PIPETTE_X_SPAN -from opentrons_shared_data.pipette.dev_types import ChannelCount - SLOT_WIDTH = 128 _PIPETTE_HOMED_POSITION_Z = ( @@ -149,7 +149,9 @@ def get_all_obstacle_highest_z(self) -> float: highest_fixture_z, ) - def get_highest_z_in_slot(self, slot: DeckSlotLocation) -> float: + def get_highest_z_in_slot( + self, slot: Union[DeckSlotLocation, StagingSlotLocation] + ) -> float: """Get the highest Z-point of all items stacked in the given deck slot.""" slot_item = self.get_slot_item(slot.slotName) if isinstance(slot_item, LoadedModule): diff --git a/api/src/opentrons/protocol_engine/state/pipettes.py b/api/src/opentrons/protocol_engine/state/pipettes.py index 169ec63a450..a1269c9a8f5 100644 --- a/api/src/opentrons/protocol_engine/state/pipettes.py +++ b/api/src/opentrons/protocol_engine/state/pipettes.py @@ -10,7 +10,7 @@ NozzleConfigurationType, NozzleMap, ) -from opentrons.types import MountType, Mount as HwMount +from opentrons.types import MountType, Mount as HwMount, Point from .. import errors from ..types import ( @@ -77,6 +77,14 @@ class CurrentDeckPoint: deck_point: Optional[DeckPoint] +@dataclass(frozen=True) +class BoundingNozzlesOffsets: + """Offsets of the bounding nozzles of the pipette.""" + + back_left_offset: Point + front_right_offset: Point + + @dataclass(frozen=True) class StaticPipetteConfig: """Static config for a pipette.""" @@ -93,6 +101,7 @@ class StaticPipetteConfig: nominal_tip_overlap: Dict[str, float] home_position: float nozzle_offset_z: float + bounding_nozzle_offsets: BoundingNozzlesOffsets @dataclass @@ -157,6 +166,10 @@ def _handle_command( # noqa: C901 nominal_tip_overlap=config.nominal_tip_overlap, home_position=config.home_position, nozzle_offset_z=config.nozzle_offset_z, + bounding_nozzle_offsets=BoundingNozzlesOffsets( + back_left_offset=config.back_left_nozzle_offset, + front_right_offset=config.front_right_nozzle_offset, + ), ) self._state.flow_rates_by_id[private_result.pipette_id] = config.flow_rates elif isinstance(private_result, PipetteNozzleLayoutResultMixin): @@ -653,3 +666,61 @@ def get_primary_nozzle(self, pipette_id: str) -> Optional[str]: """Get the primary nozzle, if any, related to the given pipette's nozzle configuration.""" nozzle_map = self._state.nozzle_configuration_by_id.get(pipette_id) return nozzle_map.starting_nozzle if nozzle_map else None + + def get_primary_nozzle_offset(self, pipette_id: str) -> Point: + """Get the pipette's current primary nozzle's offset.""" + nozzle_map = self._state.nozzle_configuration_by_id.get(pipette_id) + if nozzle_map: + primary_nozzle_offset = nozzle_map.starting_nozzle_offset + else: + # When not in partial configuration, back-left nozzle is the primary + primary_nozzle_offset = self.get_config( + pipette_id + ).bounding_nozzle_offsets.back_left_offset + return primary_nozzle_offset + + def get_pipette_bounding_nozzle_offsets( + self, pipette_id: str + ) -> BoundingNozzlesOffsets: + """Get the nozzle offsets of the pipette's bounding nozzles.""" + return self.get_config(pipette_id).bounding_nozzle_offsets + + def get_nozzle_bounds_at_specified_move_to_position( + self, + pipette_id: str, + destination_position: Point, + ) -> Tuple[Point, Point, Point, Point]: + """Get the given pipette's bounding nozzles' positions when primary nozzle is at the given destination position.""" + primary_nozzle_offset = self.get_primary_nozzle_offset(pipette_id) + tip = self.get_attached_tip(pipette_id) + # Primary nozzle position at destination, in deck coordinates + primary_nozzle_position = destination_position + Point( + x=0, y=0, z=tip.length if tip else 0 + ) + + # Get the pipette bounding box based on total nozzles + bounding_nozzles_offsets = self.get_pipette_bounding_nozzle_offsets(pipette_id) + + # TODO (spp): add a margin to these bounds + pip_back_left_bound = ( + primary_nozzle_position + - primary_nozzle_offset + + bounding_nozzles_offsets.back_left_offset + ) + pip_front_right_bound = ( + primary_nozzle_position + - primary_nozzle_offset + + bounding_nozzles_offsets.front_right_offset + ) + pip_back_right_bound = Point( + pip_front_right_bound.x, pip_back_left_bound.y, pip_front_right_bound.z + ) + pip_front_left_bound = Point( + pip_back_left_bound.x, pip_front_right_bound.y, pip_back_left_bound.z + ) + return ( + pip_back_left_bound, + pip_front_right_bound, + pip_back_right_bound, + pip_front_left_bound, + ) diff --git a/api/src/opentrons/protocol_engine/types.py b/api/src/opentrons/protocol_engine/types.py index 8263f224962..656f2263efc 100644 --- a/api/src/opentrons/protocol_engine/types.py +++ b/api/src/opentrons/protocol_engine/types.py @@ -9,7 +9,7 @@ from typing_extensions import Literal, TypeGuard from opentrons_shared_data.pipette.dev_types import PipetteNameType -from opentrons.types import MountType, DeckSlotName +from opentrons.types import MountType, DeckSlotName, StagingSlotName from opentrons.hardware_control.types import TipStateType as HwTipStateType from opentrons.hardware_control.modules import ( ModuleType as ModuleType, @@ -56,6 +56,20 @@ class DeckSlotLocation(BaseModel): ) +class StagingSlotLocation(BaseModel): + """The location of something placed in a single staging slot.""" + + slotName: StagingSlotName = Field( + ..., + description=( + # This description should be kept in sync with LabwareOffsetLocation.slotName. + "A slot on the robot's staging area." + "\n\n" + "These apply only to the Flex. The OT-2 has no staging slots." + ), + ) + + class AddressableAreaLocation(BaseModel): """The location of something place in an addressable area. This is a superset of deck slots.""" diff --git a/api/tests/opentrons/motion_planning/test_adjacent_slots_getters.py b/api/tests/opentrons/motion_planning/test_adjacent_slots_getters.py index 35ce15be449..09805e93ca8 100644 --- a/api/tests/opentrons/motion_planning/test_adjacent_slots_getters.py +++ b/api/tests/opentrons/motion_planning/test_adjacent_slots_getters.py @@ -2,6 +2,8 @@ import pytest from typing import List, Optional +from opentrons_shared_data.robot.dev_types import RobotType + from opentrons.types import DeckSlotName, StagingSlotName from opentrons.motion_planning.adjacent_slots_getters import ( get_east_slot, @@ -13,6 +15,8 @@ get_adjacent_slots, get_west_of_staging_slot, get_adjacent_staging_slot, + _MixedTypeSlots, + get_surrounding_slots, ) @@ -128,3 +132,78 @@ def test_get_adjacent_staging_slot( ) -> None: """It should find the adjacent slot east of a staging slot if it exists.""" assert get_adjacent_staging_slot(slot) == expected_adjacent + + +@pytest.mark.parametrize( + argnames=["slot", "robot_type", "expected_surrounding_slots"], + argvalues=[ + ( + 2, + "OT-2 Standard", + _MixedTypeSlots( + regular_slots=[ + DeckSlotName.SLOT_3, + DeckSlotName.SLOT_1, + DeckSlotName.SLOT_5, + DeckSlotName.SLOT_6, + DeckSlotName.SLOT_4, + ], + staging_slots=[], + ), + ), + ( + 6, + "OT-2 Standard", + _MixedTypeSlots( + regular_slots=[ + DeckSlotName.SLOT_5, + DeckSlotName.SLOT_9, + DeckSlotName.SLOT_3, + DeckSlotName.SLOT_8, + DeckSlotName.SLOT_2, + ], + staging_slots=[], + ), + ), + ( + 6, + "OT-3 Standard", + _MixedTypeSlots( + regular_slots=[ + DeckSlotName.SLOT_C2, + DeckSlotName.SLOT_B3, + DeckSlotName.SLOT_D3, + DeckSlotName.SLOT_B2, + DeckSlotName.SLOT_D2, + ], + staging_slots=[ + StagingSlotName.SLOT_B4, + StagingSlotName.SLOT_C4, + StagingSlotName.SLOT_D4, + ], + ), + ), + ( + 10, + "OT-3 Standard", + _MixedTypeSlots( + regular_slots=[ + DeckSlotName.SLOT_A2, + DeckSlotName.SLOT_B1, + DeckSlotName.SLOT_B2, + ], + staging_slots=[], + ), + ), + ], +) +def test_get_surrounding_slots( + slot: int, + robot_type: RobotType, + expected_surrounding_slots: _MixedTypeSlots, +) -> None: + """It should get the list of surrounding slots appropriate for the robot type.""" + assert ( + get_surrounding_slots(slot=slot, robot_type=robot_type) + == expected_surrounding_slots + ) diff --git a/api/tests/opentrons/protocol_api/core/engine/test_deck_conflict.py b/api/tests/opentrons/protocol_api/core/engine/test_deck_conflict.py index 781b219df27..7d4d7c6f10e 100644 --- a/api/tests/opentrons/protocol_api/core/engine/test_deck_conflict.py +++ b/api/tests/opentrons/protocol_api/core/engine/test_deck_conflict.py @@ -1,7 +1,6 @@ """Unit tests for the deck_conflict module.""" - import pytest -from typing import ContextManager, Any, NamedTuple, List +from typing import ContextManager, Any, NamedTuple, List, Tuple from decoy import Decoy from contextlib import nullcontext as does_not_raise from opentrons_shared_data.labware.dev_types import LabwareUri @@ -9,6 +8,8 @@ from opentrons.hardware_control.nozzle_manager import NozzleConfigurationType from opentrons.motion_planning import deck_conflict as wrapped_deck_conflict +from opentrons.motion_planning import adjacent_slots_getters +from opentrons.motion_planning.adjacent_slots_getters import _MixedTypeSlots from opentrons.protocol_api._trash_bin import TrashBin from opentrons.protocol_api._waste_chute import WasteChute from opentrons.protocol_api.labware import Labware @@ -20,7 +21,7 @@ StateView, ) from opentrons.protocol_engine.errors import LabwareNotLoadedOnModuleError -from opentrons.types import DeckSlotName, Point +from opentrons.types import DeckSlotName, Point, StagingSlotName from opentrons.protocol_engine.types import ( DeckType, @@ -29,13 +30,32 @@ WellLocation, WellOrigin, WellOffset, - TipGeometry, OnDeckLabwareLocation, OnLabwareLocation, Dimensions, + StagingSlotLocation, ) +@pytest.fixture(autouse=True) +def patch_slot_getters(decoy: Decoy, monkeypatch: pytest.MonkeyPatch) -> None: + """Mock out adjacent_slots_getters functions.""" + mock_get_surrounding_slots = decoy.mock( + func=adjacent_slots_getters.get_surrounding_slots + ) + mock_get_surrounding_staging_slots = decoy.mock( + func=adjacent_slots_getters.get_surrounding_staging_slots + ) + monkeypatch.setattr( + adjacent_slots_getters, "get_surrounding_slots", mock_get_surrounding_slots + ) + monkeypatch.setattr( + adjacent_slots_getters, + "get_surrounding_staging_slots", + mock_get_surrounding_staging_slots, + ) + + @pytest.fixture(autouse=True) def use_mock_wrapped_deck_conflict( decoy: Decoy, monkeypatch: pytest.MonkeyPatch @@ -359,85 +379,82 @@ def test_maps_trash_bins(decoy: Decoy, mock_state_view: StateView) -> None: [("OT-3 Standard", DeckType.OT3_STANDARD)], ) @pytest.mark.parametrize( - ["destination_well_point", "expected_raise"], + ["nozzle_bounds", "expected_raise"], [ - (Point(x=100, y=100, z=60), does_not_raise()), - # Z-collisions - ( - Point(x=100, y=100, z=10), - pytest.raises( - deck_conflict.PartialTipMovementNotAllowedError, - match="collision with items in deck slot", + ( # nozzles above highest Z + ( + Point(x=50, y=150, z=60), + Point(x=150, y=50, z=60), + Point(x=150, y=150, z=60), + Point(x=50, y=50, z=60), ), + does_not_raise(), ), + # X, Y, Z collisions ( - Point(x=100, y=100, z=20), - pytest.raises( - deck_conflict.PartialTipMovementNotAllowedError, - match="collision with items in deck slot", + ( + Point(x=50, y=150, z=40), + Point(x=150, y=50, z=40), + Point(x=150, y=150, z=40), + Point(x=50, y=50, z=40), ), - ), - # Out-of-bounds error - ( - Point(x=-12, y=100, z=60), pytest.raises( deck_conflict.PartialTipMovementNotAllowedError, - match="outside of robot bounds", + match="collision with items in deck slot D1", ), ), ( - Point(x=593, y=100, z=60), - pytest.raises( - deck_conflict.PartialTipMovementNotAllowedError, - match="outside of robot bounds", + ( + Point(x=101, y=150, z=40), + Point(x=150, y=50, z=40), + Point(x=150, y=150, z=40), + Point(x=101, y=50, z=40), ), - ), - ( - Point(x=100, y=1, z=60), pytest.raises( deck_conflict.PartialTipMovementNotAllowedError, - match="outside of robot bounds", + match="collision with items in deck slot D2", ), ), - ( - Point(x=100, y=507, z=60), + ( # Collision with staging slot + ( + Point(x=150, y=150, z=40), + Point(x=250, y=101, z=40), + Point(x=150, y=101, z=40), + Point(x=250, y=150, z=40), + ), pytest.raises( deck_conflict.PartialTipMovementNotAllowedError, - match="outside of robot bounds", + match="collision with items in deck slot C4", ), ), ], ) -def test_deck_conflict_raises_for_bad_partial_96_channel_move( +def test_deck_conflict_raises_for_bad_pipette_move( decoy: Decoy, mock_state_view: StateView, - destination_well_point: Point, + nozzle_bounds: Tuple[Point, Point, Point, Point], expected_raise: ContextManager[Any], ) -> None: - """It should raise errors when moving to locations with restrictions for partial tip 96-channel movement. + """It should raise errors when moving to locations with restrictions for partial pipette movement. Test premise: - we are using a pipette configured for COLUMN nozzle layout with primary nozzle A12 - - there's a labware of height 50mm in C1 + - there are labware of height 50mm in C1, D1 & D2 - we are checking for conflicts when moving to a labware in C2. For each test case, we are moving to a different point in the destination labware, - with the same pipette and tip (tip length is 10mm) + with the same pipette and tip """ - decoy.when(mock_state_view.pipettes.get_channels("pipette-id")).then_return(96) + destination_well_point = Point(x=123, y=123, z=123) decoy.when( - mock_state_view.pipettes.get_nozzle_layout_type("pipette-id") - ).then_return(NozzleConfigurationType.COLUMN) + mock_state_view.pipettes.get_is_partially_configured("pipette-id") + ).then_return(True) decoy.when(mock_state_view.pipettes.get_primary_nozzle("pipette-id")).then_return( "A12" ) decoy.when( mock_state_view.geometry.get_ancestor_slot_name("destination-labware-id") ).then_return(DeckSlotName.SLOT_C2) - decoy.when( - mock_state_view.geometry.get_highest_z_in_slot( - DeckSlotLocation(slotName=DeckSlotName.SLOT_C1) - ) - ).then_return(50) + decoy.when( mock_state_view.geometry.get_well_position( labware_id="destination-labware-id", @@ -445,93 +462,76 @@ def test_deck_conflict_raises_for_bad_partial_96_channel_move( well_location=WellLocation(origin=WellOrigin.TOP, offset=WellOffset(z=10)), ) ).then_return(destination_well_point) - decoy.when(mock_state_view.pipettes.get_attached_tip("pipette-id")).then_return( - TipGeometry(length=10, diameter=100, volume=0) - ) - - with expected_raise: - deck_conflict.check_safe_for_pipette_movement( - engine_state=mock_state_view, - pipette_id="pipette-id", - labware_id="destination-labware-id", - well_name="A2", - well_location=WellLocation(origin=WellOrigin.TOP, offset=WellOffset(z=10)), + decoy.when( + mock_state_view.pipettes.get_nozzle_bounds_at_specified_move_to_position( + pipette_id="pipette-id", destination_position=destination_well_point ) + ).then_return(nozzle_bounds) + decoy.when( + adjacent_slots_getters.get_surrounding_slots(5, robot_type="OT-3 Standard") + ).then_return( + _MixedTypeSlots( + regular_slots=[ + DeckSlotName.SLOT_D1, + DeckSlotName.SLOT_D2, + DeckSlotName.SLOT_C1, + ], + staging_slots=[StagingSlotName.SLOT_C4], + ) + ) + decoy.when( + adjacent_slots_getters.get_surrounding_staging_slots(DeckSlotName.SLOT_C2) + ).then_return([StagingSlotName.SLOT_C4]) -@pytest.mark.parametrize( - ("robot_type", "deck_type"), - [("OT-3 Standard", DeckType.OT3_STANDARD)], -) -@pytest.mark.parametrize( - ["destination_well_point", "expected_raise"], - [ - ( - Point(x=100, y=100, z=10), - pytest.raises( - deck_conflict.PartialTipMovementNotAllowedError, - match="Moving to destination-labware in slot D2 with pipette column A1 nozzle configuration will result in collision with items in deck slot D3.", - ), - ), - ], -) -def test_deck_conflict_raises_for_bad_partial_96_channel_move_with_fixtures( - decoy: Decoy, - mock_state_view: StateView, - destination_well_point: Point, - expected_raise: ContextManager[Any], -) -> None: - """It should raise an error when moving to locations adjacent to fixtures with restrictions for partial tip 96-channel movement. - - Test premise: - - we are using a pipette configured for COLUMN nozzle layout with primary nozzle A1 - - there's a waste chute with in D3 - - we are checking for conflicts when moving to column A12 of a labware in D2. - """ - decoy.when(mock_state_view.pipettes.get_channels("pipette-id")).then_return(96) decoy.when( - mock_state_view.labware.get_display_name("destination-labware-id") - ).then_return("destination-labware") + mock_state_view.addressable_areas.get_addressable_area_position( + addressable_area_name="C1", do_compatibility_check=False + ) + ).then_return(Point(0, 100, 0)) decoy.when( - mock_state_view.pipettes.get_nozzle_layout_type("pipette-id") - ).then_return(NozzleConfigurationType.COLUMN) - decoy.when(mock_state_view.pipettes.get_primary_nozzle("pipette-id")).then_return( - "A1" - ) + mock_state_view.addressable_areas.get_addressable_area_position( + addressable_area_name="D1", do_compatibility_check=False + ) + ).then_return(Point(0, 0, 0)) decoy.when( - mock_state_view.geometry.get_well_position( - labware_id="destination-labware-id", - well_name="A12", - well_location=WellLocation(origin=WellOrigin.TOP, offset=WellOffset(z=10)), + mock_state_view.addressable_areas.get_addressable_area_position( + addressable_area_name="D2", do_compatibility_check=False ) - ).then_return(destination_well_point) + ).then_return(Point(100, 0, 0)) decoy.when( - mock_state_view.geometry.get_ancestor_slot_name("destination-labware-id") - ).then_return(DeckSlotName.SLOT_D2) + mock_state_view.addressable_areas.get_addressable_area_position( + addressable_area_name="C4", do_compatibility_check=False + ) + ).then_return(Point(200, 100, 0)) decoy.when( - mock_state_view.addressable_areas.get_fixture_height( - "wasteChuteRightAdapterNoCover" + mock_state_view.addressable_areas.get_addressable_area_bounding_box( + addressable_area_name="C4", do_compatibility_check=False ) - ).then_return(124.5) + ).then_return(Dimensions(90, 90, 0)) decoy.when( mock_state_view.geometry.get_highest_z_in_slot( - DeckSlotLocation(slotName=DeckSlotName.SLOT_D3) - ) - ).then_return( - mock_state_view.addressable_areas.get_fixture_height( - "wasteChuteRightAdapterNoCover" + StagingSlotLocation(slotName=StagingSlotName.SLOT_C4) ) - ) - decoy.when(mock_state_view.pipettes.get_attached_tip("pipette-id")).then_return( - TipGeometry(length=10, diameter=100, volume=0) - ) + ).then_return(50) + for slot_name in [DeckSlotName.SLOT_C1, DeckSlotName.SLOT_D1, DeckSlotName.SLOT_D2]: + decoy.when( + mock_state_view.geometry.get_highest_z_in_slot( + DeckSlotLocation(slotName=slot_name) + ) + ).then_return(50) + decoy.when( + mock_state_view.addressable_areas.get_addressable_area_bounding_box( + addressable_area_name=slot_name.id, do_compatibility_check=False + ) + ).then_return(Dimensions(90, 90, 0)) with expected_raise: deck_conflict.check_safe_for_pipette_movement( engine_state=mock_state_view, pipette_id="pipette-id", labware_id="destination-labware-id", - well_name="A12", + well_name="A2", well_location=WellLocation(origin=WellOrigin.TOP, offset=WellOffset(z=10)), ) @@ -543,54 +543,64 @@ def test_deck_conflict_raises_for_bad_partial_96_channel_move_with_fixtures( @pytest.mark.parametrize( ["destination_well_point", "expected_raise"], [ - (Point(x=100, y=100, z=60), does_not_raise()), - # Z-collisions ( - Point(x=100, y=100, z=10), + Point(x=-12, y=100, z=60), pytest.raises( deck_conflict.PartialTipMovementNotAllowedError, - match="collision with items in deck slot", + match="outside of robot bounds", ), ), ( - Point(x=100, y=100, z=20), + Point(x=593, y=100, z=60), pytest.raises( deck_conflict.PartialTipMovementNotAllowedError, - match="collision with items in deck slot", + match="outside of robot bounds", + ), + ), + ( + Point(x=100, y=1, z=60), + pytest.raises( + deck_conflict.PartialTipMovementNotAllowedError, + match="outside of robot bounds", + ), + ), + ( + Point(x=100, y=507, z=60), + pytest.raises( + deck_conflict.PartialTipMovementNotAllowedError, + match="outside of robot bounds", ), ), ], ) -def test_deck_conflict_raises_for_bad_partial_8_channel_move( +def test_deck_conflict_raises_for_out_of_bounds_96_channel_move( decoy: Decoy, mock_state_view: StateView, destination_well_point: Point, expected_raise: ContextManager[Any], ) -> None: - """It should raise errors when moving to locations with restrictions for partial tip 8-channel movement. + """It should raise errors when moving to locations out of robot's bounds for partial tip 96-channel movement. Test premise: - - we are using a pipette configured for SINGLE nozzle layout with primary nozzle H1 - - there's a labware of height 50mm in B2 - - we are checking for conflicts when moving to a labware in C2. - For each test case, we are moving to a different point in the destination labware, - with the same pipette and tip (tip length is 10mm) + - we are using a pipette configured for COLUMN nozzle layout with primary nozzle A12 """ - decoy.when(mock_state_view.pipettes.get_channels("pipette-id")).then_return(8) + decoy.when(mock_state_view.pipettes.get_channels("pipette-id")).then_return(96) + decoy.when( + mock_state_view.labware.get_display_name("destination-labware-id") + ).then_return("destination-labware") decoy.when( mock_state_view.pipettes.get_nozzle_layout_type("pipette-id") - ).then_return(NozzleConfigurationType.SINGLE) + ).then_return(NozzleConfigurationType.COLUMN) + decoy.when( + mock_state_view.pipettes.get_is_partially_configured("pipette-id") + ).then_return(True) decoy.when(mock_state_view.pipettes.get_primary_nozzle("pipette-id")).then_return( - "H1" + "A12" ) decoy.when( mock_state_view.geometry.get_ancestor_slot_name("destination-labware-id") ).then_return(DeckSlotName.SLOT_C2) - decoy.when( - mock_state_view.geometry.get_highest_z_in_slot( - DeckSlotLocation(slotName=DeckSlotName.SLOT_B2) - ) - ).then_return(50) + decoy.when( mock_state_view.geometry.get_well_position( labware_id="destination-labware-id", @@ -598,18 +608,6 @@ def test_deck_conflict_raises_for_bad_partial_8_channel_move( well_location=WellLocation(origin=WellOrigin.TOP, offset=WellOffset(z=10)), ) ).then_return(destination_well_point) - decoy.when(mock_state_view.pipettes.get_attached_tip("pipette-id")).then_return( - TipGeometry(length=10, diameter=100, volume=0) - ) - - with expected_raise: - deck_conflict.check_safe_for_pipette_movement( - engine_state=mock_state_view, - pipette_id="pipette-id", - labware_id="destination-labware-id", - well_name="A2", - well_location=WellLocation(origin=WellOrigin.TOP, offset=WellOffset(z=10)), - ) class PipetteMovementSpec(NamedTuple): diff --git a/api/tests/opentrons/protocol_api_integration/test_pipette_movement_deck_conflicts.py b/api/tests/opentrons/protocol_api_integration/test_pipette_movement_deck_conflicts.py index cf01608d2fe..66e3e560776 100644 --- a/api/tests/opentrons/protocol_api_integration/test_pipette_movement_deck_conflicts.py +++ b/api/tests/opentrons/protocol_api_integration/test_pipette_movement_deck_conflicts.py @@ -138,7 +138,7 @@ def test_deck_conflicts_for_96_ch_a1_column_configuration() -> None: with pytest.raises( PartialTipMovementNotAllowedError, match="collision with items in deck slot" ): - instrument.aspirate(25, badly_placed_plate.wells_by_name()["A1"]) + instrument.aspirate(25, badly_placed_plate.wells_by_name()["A10"]) with pytest.raises( PartialTipMovementNotAllowedError, match="outside of robot bounds" diff --git a/api/tests/opentrons/protocol_engine/commands/test_configure_for_volume.py b/api/tests/opentrons/protocol_engine/commands/test_configure_for_volume.py index 857386f83a0..8ccc3d3f8cc 100644 --- a/api/tests/opentrons/protocol_engine/commands/test_configure_for_volume.py +++ b/api/tests/opentrons/protocol_engine/commands/test_configure_for_volume.py @@ -16,6 +16,7 @@ ConfigureForVolumePrivateResult, ConfigureForVolumeImplementation, ) +from opentrons.types import Point async def test_configure_for_volume_implementation( @@ -43,6 +44,8 @@ async def test_configure_for_volume_implementation( ), tip_configuration_lookup_table={}, nominal_tip_overlap={}, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ) decoy.when( diff --git a/api/tests/opentrons/protocol_engine/commands/test_load_pipette.py b/api/tests/opentrons/protocol_engine/commands/test_load_pipette.py index 6ce569529a9..967d60be945 100644 --- a/api/tests/opentrons/protocol_engine/commands/test_load_pipette.py +++ b/api/tests/opentrons/protocol_engine/commands/test_load_pipette.py @@ -4,7 +4,7 @@ from opentrons_shared_data.pipette.dev_types import PipetteNameType from opentrons_shared_data.robot.dev_types import RobotType -from opentrons.types import MountType +from opentrons.types import MountType, Point from opentrons.protocol_engine.errors import InvalidSpecificationForRobotTypeError from opentrons.protocol_engine.types import FlowRates @@ -41,6 +41,8 @@ async def test_load_pipette_implementation( ), tip_configuration_lookup_table={}, nominal_tip_overlap={}, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ) data = LoadPipetteParams( pipetteName=PipetteNameType.P300_SINGLE, @@ -96,6 +98,8 @@ async def test_load_pipette_implementation_96_channel( ), tip_configuration_lookup_table={}, nominal_tip_overlap={}, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ) decoy.when( diff --git a/api/tests/opentrons/protocol_engine/execution/test_equipment_handler.py b/api/tests/opentrons/protocol_engine/execution/test_equipment_handler.py index 17cf5d53248..0ef6a1b00bb 100644 --- a/api/tests/opentrons/protocol_engine/execution/test_equipment_handler.py +++ b/api/tests/opentrons/protocol_engine/execution/test_equipment_handler.py @@ -10,7 +10,7 @@ from opentrons_shared_data.labware.dev_types import LabwareUri from opentrons.calibration_storage.helpers import uri_from_details -from opentrons.types import Mount as HwMount, MountType, DeckSlotName +from opentrons.types import Mount as HwMount, MountType, DeckSlotName, Point from opentrons.hardware_control import HardwareControlAPI from opentrons.hardware_control.modules import ( TempDeck, @@ -147,6 +147,8 @@ def loaded_static_pipette_data( nominal_tip_overlap={"default": 9.87}, home_position=10.11, nozzle_offset_z=12.13, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ) diff --git a/api/tests/opentrons/protocol_engine/pipette_fixtures.py b/api/tests/opentrons/protocol_engine/pipette_fixtures.py index 32b3616b918..b2d2e6bafe3 100644 --- a/api/tests/opentrons/protocol_engine/pipette_fixtures.py +++ b/api/tests/opentrons/protocol_engine/pipette_fixtures.py @@ -263,3 +263,57 @@ ("H12", Point(63.0, -88.5, -259.15)), ) ) + +EIGHT_CHANNEL_ROWS = OrderedDict( + ( + ( + "A", + ["A1"], + ), + ( + "B", + ["B1"], + ), + ( + "C", + ["C1"], + ), + ( + "D", + ["D1"], + ), + ( + "E", + ["E1"], + ), + ( + "F", + ["F1"], + ), + ( + "G", + ["G1"], + ), + ( + "H", + ["H1"], + ), + ) +) + +EIGHT_CHANNEL_COLS = OrderedDict( + (("1", ["A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1"]),) +) + +EIGHT_CHANNEL_MAP = OrderedDict( + ( + ("A1", Point(0.0, 31.5, 35.52)), + ("B1", Point(0.0, 22.5, 35.52)), + ("C1", Point(0.0, 13.5, 35.52)), + ("D1", Point(0.0, 4.5, 35.52)), + ("E1", Point(0.0, -4.5, 35.52)), + ("F1", Point(0.0, -13.5, 35.52)), + ("G1", Point(0.0, -22.5, 35.52)), + ("H1", Point(0.0, -31.5, 35.52)), + ) +) diff --git a/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py b/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py index 444ced17857..432c408e43e 100644 --- a/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py +++ b/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py @@ -1,9 +1,12 @@ """Test pipette data provider.""" +from collections import OrderedDict + import pytest from opentrons_shared_data.pipette.dev_types import PipetteNameType, PipetteModel from opentrons_shared_data.pipette import pipette_definition, types as pip_types from opentrons.hardware_control.dev_types import PipetteDict +from opentrons.hardware_control.nozzle_manager import NozzleMap from opentrons.protocol_engine.types import FlowRates from opentrons.protocol_engine.resources.pipette_data_provider import ( LoadedStaticPipetteData, @@ -11,6 +14,7 @@ ) from opentrons.protocol_engine.resources import pipette_data_provider as subject +from opentrons.types import Point @pytest.fixture @@ -50,6 +54,8 @@ def test_get_virtual_pipette_static_config( "opentrons/opentrons_96_tiprack_10ul/1": 8.25, "opentrons/opentrons_96_tiprack_20ul/1": 8.25, }, + back_left_nozzle_offset=Point(x=0.0, y=0.0, z=10.45), + front_right_nozzle_offset=Point(x=0.0, y=0.0, z=10.45), ) @@ -75,6 +81,8 @@ def test_configure_virtual_pipette_for_volume( ), tip_configuration_lookup_table=result1.tip_configuration_lookup_table, nominal_tip_overlap=result1.nominal_tip_overlap, + back_left_nozzle_offset=Point(x=-8.0, y=-22.0, z=-259.15), + front_right_nozzle_offset=Point(x=-8.0, y=-22.0, z=-259.15), ) subject_instance.configure_virtual_pipette_for_volume( "my-pipette", 1, result1.model @@ -97,6 +105,8 @@ def test_configure_virtual_pipette_for_volume( ), tip_configuration_lookup_table=result2.tip_configuration_lookup_table, nominal_tip_overlap=result2.nominal_tip_overlap, + back_left_nozzle_offset=Point(x=-8.0, y=-22.0, z=-259.15), + front_right_nozzle_offset=Point(x=-8.0, y=-22.0, z=-259.15), ) @@ -122,6 +132,8 @@ def test_load_virtual_pipette_by_model_string( ), tip_configuration_lookup_table=result.tip_configuration_lookup_table, nominal_tip_overlap=result.nominal_tip_overlap, + back_left_nozzle_offset=Point(x=0.0, y=31.5, z=35.52), + front_right_nozzle_offset=Point(x=0.0, y=-31.5, z=35.52), ) @@ -202,7 +214,14 @@ def test_get_pipette_static_config( "default_aspirate_speeds": {"2.0": 5.021202, "2.6": 10.042404}, "default_push_out_volume": 3, "supported_tips": {pip_types.PipetteTipType.t300: supported_tip_fixture}, - "current_nozzle_map": None, + "current_nozzle_map": NozzleMap.build( + physical_nozzles=OrderedDict({"A1": Point(1, 2, 3), "B1": Point(4, 5, 6)}), + physical_rows=OrderedDict({"A": ["A1"], "B": ["B1"]}), + physical_columns=OrderedDict({"1": ["A1", "B1"]}), + starting_nozzle="A1", + back_left_nozzle="A1", + front_right_nozzle="B1", + ), } result = subject.get_pipette_static_config(pipette_dict) @@ -228,4 +247,6 @@ def test_get_pipette_static_config( # https://opentrons.atlassian.net/browse/RCORE-655 nozzle_offset_z=0, home_position=0, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ) diff --git a/api/tests/opentrons/protocol_engine/state/test_geometry_view.py b/api/tests/opentrons/protocol_engine/state/test_geometry_view.py index f137e9f72f5..93c3be8ebbe 100644 --- a/api/tests/opentrons/protocol_engine/state/test_geometry_view.py +++ b/api/tests/opentrons/protocol_engine/state/test_geometry_view.py @@ -50,7 +50,11 @@ from opentrons.protocol_engine.state.config import Config from opentrons.protocol_engine.state.labware import LabwareView from opentrons.protocol_engine.state.modules import ModuleView -from opentrons.protocol_engine.state.pipettes import PipetteView, StaticPipetteConfig +from opentrons.protocol_engine.state.pipettes import ( + PipetteView, + StaticPipetteConfig, + BoundingNozzlesOffsets, +) from opentrons.protocol_engine.state.addressable_areas import AddressableAreaView from opentrons.protocol_engine.state.geometry import GeometryView, _GripperMoveType @@ -1847,6 +1851,10 @@ def test_get_next_drop_tip_location( nominal_tip_overlap={}, home_position=0, nozzle_offset_z=0, + bounding_nozzle_offsets=BoundingNozzlesOffsets( + back_left_offset=Point(x=10, y=20, z=30), + front_right_offset=Point(x=40, y=50, z=60), + ), ) ) decoy.when(mock_pipette_view.get_mount("pip-123")).then_return(pipette_mount) diff --git a/api/tests/opentrons/protocol_engine/state/test_pipette_store.py b/api/tests/opentrons/protocol_engine/state/test_pipette_store.py index 17b90628ad2..a8a03539848 100644 --- a/api/tests/opentrons/protocol_engine/state/test_pipette_store.py +++ b/api/tests/opentrons/protocol_engine/state/test_pipette_store.py @@ -6,7 +6,7 @@ from opentrons_shared_data.pipette.dev_types import PipetteNameType from opentrons_shared_data.pipette import pipette_definition -from opentrons.types import DeckSlotName, MountType +from opentrons.types import DeckSlotName, MountType, Point from opentrons.protocol_engine import commands as cmd from opentrons.protocol_engine.types import ( DeckPoint, @@ -27,6 +27,7 @@ PipetteState, CurrentDeckPoint, StaticPipetteConfig, + BoundingNozzlesOffsets, ) from opentrons.protocol_engine.resources.pipette_data_provider import ( LoadedStaticPipetteData, @@ -681,6 +682,8 @@ def test_add_pipette_config( nominal_tip_overlap={"default": 5}, home_position=8.9, nozzle_offset_z=10.11, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ), ) subject.handle_action( @@ -698,6 +701,10 @@ def test_add_pipette_config( nominal_tip_overlap={"default": 5}, home_position=8.9, nozzle_offset_z=10.11, + bounding_nozzle_offsets=BoundingNozzlesOffsets( + back_left_offset=Point(x=1, y=2, z=3), + front_right_offset=Point(x=4, y=5, z=6), + ), ) assert subject.state.flow_rates_by_id["pipette-id"].default_aspirate == {"a": 1.0} assert subject.state.flow_rates_by_id["pipette-id"].default_dispense == {"b": 2.0} diff --git a/api/tests/opentrons/protocol_engine/state/test_pipette_view.py b/api/tests/opentrons/protocol_engine/state/test_pipette_view.py index f7b32c9d37e..b272ca6aa54 100644 --- a/api/tests/opentrons/protocol_engine/state/test_pipette_view.py +++ b/api/tests/opentrons/protocol_engine/state/test_pipette_view.py @@ -2,7 +2,7 @@ from collections import OrderedDict import pytest -from typing import cast, Dict, List, Optional +from typing import cast, Dict, List, Optional, Tuple, NamedTuple from opentrons_shared_data.pipette.dev_types import PipetteNameType from opentrons_shared_data.pipette import pipette_definition @@ -25,10 +25,24 @@ CurrentDeckPoint, HardwarePipette, StaticPipetteConfig, + BoundingNozzlesOffsets, ) from opentrons.hardware_control.nozzle_manager import NozzleMap, NozzleConfigurationType from opentrons.protocol_engine.errors import TipNotAttachedError, PipetteNotLoadedError +from ..pipette_fixtures import ( + NINETY_SIX_ROWS, + NINETY_SIX_COLS, + NINETY_SIX_MAP, + EIGHT_CHANNEL_ROWS, + EIGHT_CHANNEL_COLS, + EIGHT_CHANNEL_MAP, +) + +_SAMPLE_NOZZLE_BOUNDS_OFFSETS = BoundingNozzlesOffsets( + back_left_offset=Point(x=10, y=20, z=30), front_right_offset=Point(x=40, y=50, z=60) +) + def get_pipette_view( pipettes_by_id: Optional[Dict[str, LoadedPipette]] = None, @@ -253,6 +267,7 @@ def test_get_pipette_working_volume( nominal_tip_overlap={}, home_position=0, nozzle_offset_z=0, + bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, ) }, ) @@ -280,6 +295,7 @@ def test_get_pipette_working_volume_raises_if_tip_volume_is_none( nominal_tip_overlap={}, home_position=0, nozzle_offset_z=0, + bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, ) }, ) @@ -316,6 +332,7 @@ def test_get_pipette_available_volume( nominal_tip_overlap={}, home_position=0, nozzle_offset_z=0, + bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, ), "pipette-id-none": StaticPipetteConfig( min_volume=1, @@ -328,6 +345,7 @@ def test_get_pipette_available_volume( nominal_tip_overlap={}, home_position=0, nozzle_offset_z=0, + bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, ), }, ) @@ -436,6 +454,7 @@ def test_get_static_config( nominal_tip_overlap={}, home_position=10.12, nozzle_offset_z=12.13, + bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, ) subject = get_pipette_view( @@ -483,6 +502,7 @@ def test_get_nominal_tip_overlap( }, home_position=0, nozzle_offset_z=0, + bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, ) subject = get_pipette_view(static_config_by_id={"pipette-id": config}) @@ -530,3 +550,201 @@ def test_nozzle_configuration_getters() -> None: assert subject.get_nozzle_layout_type("pipette-id") == NozzleConfigurationType.FULL assert subject.get_is_partially_configured("pipette-id") is False assert subject.get_primary_nozzle("pipette-id") == "A1" + + +class _PipetteSpecs(NamedTuple): + tip_length: float + bounding_nozzle_offsets: BoundingNozzlesOffsets + nozzle_map: NozzleMap + destination_position: Point + nozzle_bounds_result: Tuple[Point, Point, Point, Point] + + +_pipette_spec_cases = [ + _PipetteSpecs( + # 8-channel P300, full configuration + tip_length=42, + bounding_nozzle_offsets=BoundingNozzlesOffsets( + back_left_offset=Point(0.0, 31.5, 35.52), + front_right_offset=Point(0.0, -31.5, 35.52), + ), + nozzle_map=NozzleMap.build( + physical_nozzles=EIGHT_CHANNEL_MAP, + physical_rows=EIGHT_CHANNEL_ROWS, + physical_columns=EIGHT_CHANNEL_COLS, + starting_nozzle="A1", + back_left_nozzle="A1", + front_right_nozzle="H1", + ), + destination_position=Point(100, 200, 300), + nozzle_bounds_result=( + ( + Point(x=100.0, y=200.0, z=342.0), + Point(x=100.0, y=137.0, z=342.0), + Point(x=100.0, y=200.0, z=342.0), + Point(x=100.0, y=137.0, z=342.0), + ) + ), + ), + _PipetteSpecs( + # 8-channel P300, single configuration + tip_length=42, + bounding_nozzle_offsets=BoundingNozzlesOffsets( + back_left_offset=Point(0.0, 31.5, 35.52), + front_right_offset=Point(0.0, -31.5, 35.52), + ), + nozzle_map=NozzleMap.build( + physical_nozzles=EIGHT_CHANNEL_MAP, + physical_rows=EIGHT_CHANNEL_ROWS, + physical_columns=EIGHT_CHANNEL_COLS, + starting_nozzle="H1", + back_left_nozzle="H1", + front_right_nozzle="H1", + ), + destination_position=Point(100, 200, 300), + nozzle_bounds_result=( + ( + Point(x=100.0, y=263.0, z=342.0), + Point(x=100.0, y=200.0, z=342.0), + Point(x=100.0, y=263.0, z=342.0), + Point(x=100.0, y=200.0, z=342.0), + ) + ), + ), + _PipetteSpecs( + # 96-channel P1000, full configuration + tip_length=42, + bounding_nozzle_offsets=BoundingNozzlesOffsets( + back_left_offset=Point(-36.0, -25.5, -259.15), + front_right_offset=Point(63.0, -88.5, -259.15), + ), + nozzle_map=NozzleMap.build( + physical_nozzles=NINETY_SIX_MAP, + physical_rows=NINETY_SIX_ROWS, + physical_columns=NINETY_SIX_COLS, + starting_nozzle="A1", + back_left_nozzle="A1", + front_right_nozzle="H12", + ), + destination_position=Point(100, 200, 300), + nozzle_bounds_result=( + ( + Point(x=100.0, y=200.0, z=342.0), + Point(x=199.0, y=137.0, z=342.0), + Point(x=199.0, y=200.0, z=342.0), + Point(x=100.0, y=137.0, z=342.0), + ) + ), + ), + _PipetteSpecs( + # 96-channel P1000, A1 COLUMN configuration + tip_length=42, + bounding_nozzle_offsets=BoundingNozzlesOffsets( + back_left_offset=Point(-36.0, -25.5, -259.15), + front_right_offset=Point(63.0, -88.5, -259.15), + ), + nozzle_map=NozzleMap.build( + physical_nozzles=NINETY_SIX_MAP, + physical_rows=NINETY_SIX_ROWS, + physical_columns=NINETY_SIX_COLS, + starting_nozzle="A1", + back_left_nozzle="A1", + front_right_nozzle="H1", + ), + destination_position=Point(100, 200, 300), + nozzle_bounds_result=( + Point(100, 200, 342), + Point(199, 137, 342), + Point(199, 200, 342), + Point(100, 137, 342), + ), + ), + _PipetteSpecs( + # 96-channel P1000, A12 COLUMN configuration + tip_length=42, + bounding_nozzle_offsets=BoundingNozzlesOffsets( + back_left_offset=Point(-36.0, -25.5, -259.15), + front_right_offset=Point(63.0, -88.5, -259.15), + ), + nozzle_map=NozzleMap.build( + physical_nozzles=NINETY_SIX_MAP, + physical_rows=NINETY_SIX_ROWS, + physical_columns=NINETY_SIX_COLS, + starting_nozzle="A12", + back_left_nozzle="A12", + front_right_nozzle="H12", + ), + destination_position=Point(100, 200, 300), + nozzle_bounds_result=( + Point(1, 200, 342), + Point(100, 137, 342), + Point(100, 200, 342), + Point(1, 137, 342), + ), + ), + _PipetteSpecs( + # 96-channel P1000, ROW configuration + tip_length=42, + bounding_nozzle_offsets=BoundingNozzlesOffsets( + back_left_offset=Point(-36.0, -25.5, -259.15), + front_right_offset=Point(63.0, -88.5, -259.15), + ), + nozzle_map=NozzleMap.build( + physical_nozzles=NINETY_SIX_MAP, + physical_rows=NINETY_SIX_ROWS, + physical_columns=NINETY_SIX_COLS, + starting_nozzle="A1", + back_left_nozzle="A1", + front_right_nozzle="A12", + ), + destination_position=Point(100, 200, 300), + nozzle_bounds_result=( + Point(100, 200, 342), + Point(199, 137, 342), + Point(199, 200, 342), + Point(100, 137, 342), + ), + ), +] + + +@pytest.mark.parametrize( + argnames=_PipetteSpecs._fields, + argvalues=_pipette_spec_cases, +) +def test_get_nozzle_bounds_at_location( + tip_length: float, + bounding_nozzle_offsets: BoundingNozzlesOffsets, + nozzle_map: NozzleMap, + destination_position: Point, + nozzle_bounds_result: Tuple[Point, Point, Point, Point], +) -> None: + """It should get the pipette's nozzle's bounds at the given location.""" + subject = get_pipette_view( + nozzle_layout_by_id={"pipette-id": nozzle_map}, + attached_tip_by_id={ + "pipette-id": TipGeometry(length=tip_length, diameter=123, volume=123), + }, + static_config_by_id={ + "pipette-id": StaticPipetteConfig( + min_volume=1, + max_volume=9001, + channels=5, + model="blah", + display_name="bleh", + serial_number="", + tip_configuration_lookup_table={}, + nominal_tip_overlap={}, + home_position=0, + nozzle_offset_z=0, + bounding_nozzle_offsets=bounding_nozzle_offsets, + ) + }, + ) + assert ( + subject.get_nozzle_bounds_at_specified_move_to_position( + pipette_id="pipette-id", + destination_position=destination_position, + ) + == nozzle_bounds_result + ) diff --git a/api/tests/opentrons/protocol_engine/state/test_tip_state.py b/api/tests/opentrons/protocol_engine/state/test_tip_state.py index 0058ae1ef93..59be5e927f5 100644 --- a/api/tests/opentrons/protocol_engine/state/test_tip_state.py +++ b/api/tests/opentrons/protocol_engine/state/test_tip_state.py @@ -218,6 +218,8 @@ def test_get_next_tip_skips_picked_up_tip( nominal_tip_overlap={}, nozzle_offset_z=1.23, home_position=4.56, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ), ) subject.handle_action( @@ -410,6 +412,8 @@ def test_reset_tips( nominal_tip_overlap={}, nozzle_offset_z=1.23, home_position=4.56, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ), ) @@ -458,6 +462,8 @@ def test_handle_pipette_config_action( nominal_tip_overlap={}, nozzle_offset_z=1.23, home_position=4.56, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ), ) subject.handle_action( @@ -538,6 +544,8 @@ def test_drop_tip( nominal_tip_overlap={}, nozzle_offset_z=1.23, home_position=4.56, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ), ) subject.handle_action( @@ -641,6 +649,8 @@ def test_active_channels( nominal_tip_overlap={}, nozzle_offset_z=1.23, home_position=4.56, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ), ) subject.handle_action( @@ -703,6 +713,8 @@ def test_next_tip_uses_active_channels( nominal_tip_overlap={}, nozzle_offset_z=1.23, home_position=4.56, + back_left_nozzle_offset=Point(x=1, y=2, z=3), + front_right_nozzle_offset=Point(x=4, y=5, z=6), ), ) subject.handle_action( diff --git a/hardware-testing/hardware_testing/gravimetric/overrides/api.patch b/hardware-testing/hardware_testing/gravimetric/overrides/api.patch index c14653a8be8..4e2ab9b6c23 100644 --- a/hardware-testing/hardware_testing/gravimetric/overrides/api.patch +++ b/hardware-testing/hardware_testing/gravimetric/overrides/api.patch @@ -27,10 +27,10 @@ index 2d36460ca6..8578768930 100644 def ok_to_push_out(self, push_out_dist_mm: float) -> bool: return push_out_dist_mm <= ( diff --git a/api/src/opentrons/protocol_api/core/engine/deck_conflict.py b/api/src/opentrons/protocol_api/core/engine/deck_conflict.py -index 1a756f751f..a739ec553c 100644 +index 0ba7e17621..4d6682f5e4 100644 --- a/api/src/opentrons/protocol_api/core/engine/deck_conflict.py +++ b/api/src/opentrons/protocol_api/core/engine/deck_conflict.py -@@ -267,18 +267,12 @@ def check_safe_for_tip_pickup_and_return( +@@ -341,18 +341,12 @@ def check_safe_for_tip_pickup_and_return( f" when picking up fewer than 96 tips." ) elif not is_partial_config and not is_96_ch_tiprack_adapter: @@ -50,7 +50,7 @@ index 1a756f751f..a739ec553c 100644 + pass - def _check_deck_conflict_for_96_channel( + # TODO (spp, 2023-02-06): update the extents check to use all nozzle bounds instead of diff --git a/api/src/opentrons/protocol_api/core/legacy/deck.py b/api/src/opentrons/protocol_api/core/legacy/deck.py index 9a9092af5a..33aa5941ce 100644 --- a/api/src/opentrons/protocol_api/core/legacy/deck.py From c77a53be24a4b752efc30bbd69229e00702907f9 Mon Sep 17 00:00:00 2001 From: Nick Diehl <47604184+ncdiehl11@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:33:05 -0500 Subject: [PATCH 03/10] feat(app, components, shared-data): disable invalid slots during module cal (#14411) * feat(app, components, shared-data): disable incompatible fixture-occupied slots during module cal closes RQA-2164 --- .../localization/en/module_wizard_flows.json | 2 + app/src/molecules/GenericWizardTile/index.tsx | 45 ++++-- .../ModuleWizardFlows/SelectLocation.tsx | 21 ++- app/src/organisms/ModuleWizardFlows/index.tsx | 55 +++++-- .../src/hooks/useSelectDeckLocation/index.tsx | 151 +++++++++++++++--- shared-data/js/fixtures.ts | 16 ++ 6 files changed, 234 insertions(+), 56 deletions(-) diff --git a/app/src/assets/localization/en/module_wizard_flows.json b/app/src/assets/localization/en/module_wizard_flows.json index b347ced8f01..636bb368662 100644 --- a/app/src/assets/localization/en/module_wizard_flows.json +++ b/app/src/assets/localization/en/module_wizard_flows.json @@ -24,6 +24,7 @@ "get_started": "To get started, remove labware from the deck and clean up the working area to make the calibration easier. Also gather the needed equipment shown to the right.The calibration adapter came with your module. The pipette probe came with your Flex pipette.", "install_adapter": "Place calibration adapter in {{module}}", "install_calibration_adapter": "Install calibration adapter", + "location_occupied": "A {{fixture}} is currently specified here on the deck configuration", "module_calibrating": "Stand back, {{moduleName}} is calibrating", "module_calibration_failed": "Module calibration was unsuccessful. Make sure the calibration adapter is fully seated on the module and try again. If you still have trouble, contact Opentrons Support.{{error}}", "module_calibration": "Module calibration", @@ -39,6 +40,7 @@ "recalibrate": "Recalibrate", "select_location": "Select module location", "select_the_slot": "Select the slot where you installed the {{module}} on the deck map to the right. The location must be correct for successful calibration.", + "slot_unavailable": "Slot unavailable", "stand_back_exiting": "Stand back, robot is in motion", "stand_back": "Stand back, calibration in progress", "start_setup": "Start setup", diff --git a/app/src/molecules/GenericWizardTile/index.tsx b/app/src/molecules/GenericWizardTile/index.tsx index 930269bc129..de4d904e948 100644 --- a/app/src/molecules/GenericWizardTile/index.tsx +++ b/app/src/molecules/GenericWizardTile/index.tsx @@ -19,9 +19,11 @@ import { DISPLAY_INLINE_BLOCK, ALIGN_CENTER, ALIGN_FLEX_END, + useHoverTooltip, } from '@opentrons/components' import { getIsOnDevice } from '../../redux/config' import { StyledText } from '../../atoms/text' +import { Tooltip } from '../../atoms/Tooltip' import { NeedHelpLink } from '../../organisms/CalibrationPanels' import { SmallButton } from '../../atoms/buttons' @@ -90,6 +92,7 @@ export interface GenericWizardTileProps { proceedIsDisabled?: boolean proceedButton?: JSX.Element backIsDisabled?: boolean + disableProceedReason?: string } export function GenericWizardTile(props: GenericWizardTileProps): JSX.Element { @@ -104,9 +107,11 @@ export function GenericWizardTile(props: GenericWizardTileProps): JSX.Element { proceedIsDisabled, proceedButton, backIsDisabled, + disableProceedReason, } = props const { t } = useTranslation('shared') const isOnDevice = useSelector(getIsOnDevice) + const [targetProps, tooltipProps] = useHoverTooltip() let buttonPositioning: string = '' if ( @@ -158,19 +163,35 @@ export function GenericWizardTile(props: GenericWizardTileProps): JSX.Element { {getHelp != null ? : null} {proceed != null && proceedButton == null ? ( isOnDevice ? ( - + <> + + {disableProceedReason != null && ( + + {disableProceedReason} + + )} + ) : ( - - {proceedButtonText} - + <> + + {proceedButtonText} + + {disableProceedReason != null && ( + + {disableProceedReason} + + )} + ) ) : null} {proceed == null && proceedButton != null ? proceedButton : null} diff --git a/app/src/organisms/ModuleWizardFlows/SelectLocation.tsx b/app/src/organisms/ModuleWizardFlows/SelectLocation.tsx index 09087740eec..ea801c48f4c 100644 --- a/app/src/organisms/ModuleWizardFlows/SelectLocation.tsx +++ b/app/src/organisms/ModuleWizardFlows/SelectLocation.tsx @@ -3,10 +3,10 @@ import { useTranslation } from 'react-i18next' import { css } from 'styled-components' import { FLEX_ROBOT_TYPE, - ModuleLocation, getDeckDefFromRobotType, getModuleDisplayName, THERMOCYCLER_MODULE_TYPE, + CutoutConfig, } from '@opentrons/shared-data' import { RESPONSIVENESS, @@ -31,6 +31,7 @@ export const BODY_STYLE = css` interface SelectLocationProps extends ModuleCalibrationWizardStepProps { setSlotName: React.Dispatch> availableSlotNames: string[] + occupiedCutouts: CutoutConfig[] } export const SelectLocation = ( props: SelectLocationProps @@ -41,6 +42,7 @@ export const SelectLocation = ( slotName, setSlotName, availableSlotNames, + occupiedCutouts, } = props const { t } = useTranslation('module_wizard_flows') const moduleName = getModuleDisplayName(attachedModule.moduleModel) @@ -58,6 +60,7 @@ export const SelectLocation = ( ) + return ( setSlotName(loc.slotName)} - disabledLocations={deckDef.locations.addressableAreas.reduce< - ModuleLocation[] - >((acc, slot) => { - if (availableSlotNames.some(slotName => slotName === slot.id)) - return acc - return [...acc, { slotName: slot.id }] - }, [])} + availableSlotNames={availableSlotNames} + occupiedCutouts={occupiedCutouts} isThermocycler={ attachedModule.moduleType === THERMOCYCLER_MODULE_TYPE } + showTooltipOnDisabled={true} /> } bodyText={bodyText} proceedButtonText={t('confirm_location')} proceed={handleOnClick} + proceedIsDisabled={slotName == null} + disableProceedReason={ + slotName == null + ? 'Current deck configuration prevents module placement' + : undefined + } /> ) } diff --git a/app/src/organisms/ModuleWizardFlows/index.tsx b/app/src/organisms/ModuleWizardFlows/index.tsx index 9d2e90f7bf9..61d3bdd5bec 100644 --- a/app/src/organisms/ModuleWizardFlows/index.tsx +++ b/app/src/organisms/ModuleWizardFlows/index.tsx @@ -1,14 +1,18 @@ import * as React from 'react' import { useSelector } from 'react-redux' import { Trans, useTranslation } from 'react-i18next' -import { useDeleteMaintenanceRunMutation } from '@opentrons/react-api-client' +import { + useDeleteMaintenanceRunMutation, + useCurrentMaintenanceRun, + useDeckConfigurationQuery, +} from '@opentrons/react-api-client' import { COLORS } from '@opentrons/components' import { - CreateCommand, getModuleType, getModuleDisplayName, + FLEX_CUTOUT_BY_SLOT_ID, + SINGLE_SLOT_FIXTURES, } from '@opentrons/shared-data' - import { LegacyModalShell } from '../../molecules/LegacyModal' import { Portal } from '../../App/portal' import { StyledText } from '../../atoms/text' @@ -29,9 +33,13 @@ import { PlaceAdapter } from './PlaceAdapter' import { SelectLocation } from './SelectLocation' import { Success } from './Success' import { DetachProbe } from './DetachProbe' -import { useNotifyCurrentMaintenanceRun } from '../../resources/maintenance_runs/useNotifyCurrentMaintenanceRun' import type { AttachedModule, CommandData } from '@opentrons/api-client' +import type { + CreateCommand, + CutoutConfig, + SingleSlotCutoutFixtureId, +} from '@opentrons/shared-data' interface ModuleWizardFlowsProps { attachedModule: AttachedModule @@ -64,10 +72,26 @@ export const ModuleWizardFlows = ( : attachedPipettes.right const moduleCalibrationSteps = getModuleCalibrationSteps() + const deckConfig = useDeckConfigurationQuery().data ?? [] + const occupiedCutouts = deckConfig.filter( + (fixture: CutoutConfig) => + !SINGLE_SLOT_FIXTURES.includes( + fixture.cutoutFixtureId as SingleSlotCutoutFixtureId + ) + ) const availableSlotNames = - FLEX_SLOT_NAMES_BY_MOD_TYPE[getModuleType(attachedModule.moduleModel)] ?? [] + FLEX_SLOT_NAMES_BY_MOD_TYPE[ + getModuleType(attachedModule.moduleModel) + ]?.filter( + slot => + !occupiedCutouts.some( + (occCutout: CutoutConfig) => + occCutout.cutoutId === FLEX_CUTOUT_BY_SLOT_ID[slot] + ) + ) ?? [] + const [slotName, setSlotName] = React.useState( - initialSlotName != null ? initialSlotName : availableSlotNames?.[0] ?? 'D1' + initialSlotName != null ? initialSlotName : availableSlotNames?.[0] ?? null ) const [currentStepIndex, setCurrentStepIndex] = React.useState(0) const totalStepCount = moduleCalibrationSteps.length - 1 @@ -91,7 +115,7 @@ export const ModuleWizardFlows = ( setMonitorMaintenanceRunForDeletion, ] = React.useState(false) - const { data: maintenanceRunData } = useNotifyCurrentMaintenanceRun({ + const { data: maintenanceRunData } = useCurrentMaintenanceRun({ refetchInterval: RUN_REFETCH_INTERVAL, enabled: createdMaintenanceRunId != null, }) @@ -104,7 +128,9 @@ export const ModuleWizardFlows = ( createTargetedMaintenanceRun, isLoading: isCreateLoading, } = useCreateTargetedMaintenanceRunMutation({ - onSuccess: response => { + onSuccess: (response: { + data: { id: React.SetStateAction } + }) => { setCreatedMaintenanceRunId(response.data.id) }, }) @@ -149,8 +175,12 @@ export const ModuleWizardFlows = ( } const { deleteMaintenanceRun } = useDeleteMaintenanceRunMutation({ - onSuccess: () => handleClose(), - onError: () => handleClose(), + onSuccess: () => { + handleClose() + }, + onError: () => { + handleClose() + }, }) const handleCleanUpAndClose = (): void => { @@ -158,7 +188,7 @@ export const ModuleWizardFlows = ( if (maintenanceRunData?.data.id == null) handleClose() else { chainRunCommands( - maintenanceRunData?.data.id, + maintenanceRunData?.data.id as string, [{ commandType: 'home' as const, params: {} }], false ) @@ -190,7 +220,7 @@ export const ModuleWizardFlows = ( continuePastCommandFailure: boolean ): Promise => chainRunCommands( - maintenanceRunData?.data.id, + maintenanceRunData?.data.id as string, commands, continuePastCommandFailure ) @@ -275,6 +305,7 @@ export const ModuleWizardFlows = ( {...calibrateBaseProps} availableSlotNames={availableSlotNames} setSlotName={setSlotName} + occupiedCutouts={occupiedCutouts} /> ) } else if (currentStep.section === SECTIONS.PLACE_ADAPTER) { diff --git a/components/src/hooks/useSelectDeckLocation/index.tsx b/components/src/hooks/useSelectDeckLocation/index.tsx index 7bd9f9d974f..c7ccf53e6bf 100644 --- a/components/src/hooks/useSelectDeckLocation/index.tsx +++ b/components/src/hooks/useSelectDeckLocation/index.tsx @@ -1,15 +1,20 @@ import * as React from 'react' import isEqual from 'lodash/isEqual' - +import { useTranslation } from 'react-i18next' import { + CutoutConfig, FLEX_CUTOUT_BY_SLOT_ID, + FLEX_SINGLE_SLOT_BY_CUTOUT_ID, FLEX_ROBOT_TYPE, getDeckDefFromRobotType, getPositionFromSlotId, + getFixtureDisplayName, isAddressableAreaStandardSlot, OT2_ROBOT_TYPE, + AddressableArea, + CoordinateTuple, + CutoutFixtureId, } from '@opentrons/shared-data' - import { DeckFromLayers, LegacyDeckSlotLocation, @@ -75,19 +80,55 @@ interface DeckLocationSelectProps { selectedLocation: ModuleLocation theme?: DeckLocationSelectThemes setSelectedLocation?: (loc: ModuleLocation) => void - disabledLocations?: ModuleLocation[] + availableSlotNames?: string[] + occupiedCutouts?: CutoutConfig[] isThermocycler?: boolean + showTooltipOnDisabled?: boolean } + export function DeckLocationSelect({ deckDef, selectedLocation, setSelectedLocation, - disabledLocations = [], + availableSlotNames, + occupiedCutouts = [], theme = 'default', isThermocycler = false, + showTooltipOnDisabled = false, }: DeckLocationSelectProps): JSX.Element { const robotType = deckDef.robot.model + const { t } = useTranslation('module_wizard_flows') + + const [hoveredData, setHoveredData] = React.useState<{ + slot: AddressableArea + slotPosition: CoordinateTuple | null + isDisabled: boolean + disabledReason?: CutoutFixtureId | null + } | null>(null) + + const handleMouseEnter = ( + slot: AddressableArea, + slotPosition: CoordinateTuple | null, + isDisabled: boolean, + disabledReason?: CutoutFixtureId | null + ): void => { + if (isDisabled) { + setHoveredData({ + slot: slot, + slotPosition: slotPosition, + isDisabled: isDisabled, + disabledReason: disabledReason, + }) + } else { + setHoveredData(null) + } + } + + const handleMouseLeave = (): void => { + setHoveredData(null) + } + return ( { const slotLocation = { slotName: slot.id } - const isDisabled = disabledLocations.some( - l => - typeof l === 'object' && 'slotName' in l && l.slotName === slot.id - ) + const isDisabled = + availableSlotNames !== undefined + ? !availableSlotNames.some(slotName => slotName === slot.id) + : false + + const disabledReason = + occupiedCutouts.find( + cutout => + FLEX_SINGLE_SLOT_BY_CUTOUT_ID[cutout.cutoutId] === slot.id + )?.cutoutFixtureId ?? null const isSelected = isEqual(selectedLocation, slotLocation) let fill = theme === 'default' ? COLORS.purple35 : COLORS.grey35 if (isSelected) @@ -148,22 +195,33 @@ export function DeckLocationSelect({ return ( {robotType === FLEX_ROBOT_TYPE ? ( - - !isDisabled && - setSelectedLocation != null && - setSelectedLocation(slotLocation) - } - cursor={ - setSelectedLocation == null || isDisabled || isSelected - ? 'default' - : 'pointer' - } - deckDefinition={deckDef} - /> + <> + + !isDisabled && + setSelectedLocation != null && + setSelectedLocation(slotLocation) + } + cursor={ + setSelectedLocation == null || isDisabled || isSelected + ? 'default' + : 'pointer' + } + deckDefinition={deckDef} + onMouseEnter={() => + handleMouseEnter( + slot, + slotPosition, + isDisabled, + disabledReason + ) + } + onMouseLeave={handleMouseLeave} + /> + ) : ( ) : null} + {hoveredData != null && + hoveredData.isDisabled && + hoveredData.slotPosition != null && + showTooltipOnDisabled && ( + + + {hoveredData.disabledReason != null + ? t('location_occupied', { + fixture: getFixtureDisplayName( + hoveredData.disabledReason + ).toLowerCase(), + }) + : 'Slot unavailable'} + + + )} ) } diff --git a/shared-data/js/fixtures.ts b/shared-data/js/fixtures.ts index f0b906575d8..7e2f117bca8 100644 --- a/shared-data/js/fixtures.ts +++ b/shared-data/js/fixtures.ts @@ -50,6 +50,22 @@ export const FLEX_CUTOUT_BY_SLOT_ID: { [slotId: string]: CutoutId } = { D4: 'cutoutD3', } +// mapping of Flex single slot cutouts to deck slots +export const FLEX_SINGLE_SLOT_BY_CUTOUT_ID: { [CutoutId: string]: string } = { + cutoutA1: 'A1', + cutoutA2: 'A2', + cutoutA3: 'A3', + cutoutB1: 'B1', + cutoutB2: 'B2', + cutoutB3: 'B3', + cutoutC1: 'C1', + cutoutC2: 'C2', + cutoutC3: 'C3', + cutoutD1: 'D1', + cutoutD2: 'D2', + cutoutD3: 'D3', +} + // returns the position associated with a slot id export function getPositionFromSlotId( slotId: string, From 67579f4259eb23b1fb3b37dd754a287ef4e113be Mon Sep 17 00:00:00 2001 From: Nick Diehl <47604184+ncdiehl11@users.noreply.github.com> Date: Wed, 7 Feb 2024 13:38:54 -0500 Subject: [PATCH 04/10] feat(app): add privacy policy acknowledgement screen on ODD (#14435) * feat(app): add privacy policy acknowledgement screen to new 7.2 bootup on ODD closes RAUT-818 --- app/src/App/OnDeviceDisplayApp.tsx | 7 ++ .../privacy_policy_qrcode.png | Bin 0 -> 10003 bytes .../localization/en/device_settings.json | 3 + .../NameRobot/ConfirmRobotName.tsx | 2 +- app/src/pages/ConnectViaEthernet/index.tsx | 2 +- app/src/pages/ConnectViaUSB/index.tsx | 2 +- .../__tests__/ConnectViaWifi.test.tsx | 2 +- app/src/pages/ConnectViaWifi/index.tsx | 2 +- app/src/pages/EmergencyStop/index.tsx | 15 ++- .../NameRobot/__tests__/NameRobot.test.tsx | 7 -- app/src/pages/NameRobot/index.tsx | 18 +-- app/src/pages/NetworkSetupMenu/index.tsx | 2 +- app/src/pages/PrivacyPolicy/index.tsx | 106 ++++++++++++++++++ .../RobotDashboard/AnalyticsOptInModal.tsx | 91 --------------- app/src/pages/RobotDashboard/WelcomeModal.tsx | 13 ++- .../__tests__/AnalyticsOptInModal.test.tsx | 86 -------------- .../__tests__/WelcomeModal.test.tsx | 2 - app/src/pages/RobotDashboard/index.tsx | 28 ++--- 18 files changed, 161 insertions(+), 227 deletions(-) create mode 100644 app/src/assets/images/on-device-display/privacy_policy_qrcode.png create mode 100644 app/src/pages/PrivacyPolicy/index.tsx delete mode 100644 app/src/pages/RobotDashboard/AnalyticsOptInModal.tsx delete mode 100644 app/src/pages/RobotDashboard/__tests__/AnalyticsOptInModal.test.tsx diff --git a/app/src/App/OnDeviceDisplayApp.tsx b/app/src/App/OnDeviceDisplayApp.tsx index d28f82b3b36..95a2abd1afd 100644 --- a/app/src/App/OnDeviceDisplayApp.tsx +++ b/app/src/App/OnDeviceDisplayApp.tsx @@ -27,6 +27,7 @@ import { ConnectViaWifi } from '../pages/ConnectViaWifi' import { EmergencyStop } from '../pages/EmergencyStop' import { NameRobot } from '../pages/NameRobot' import { NetworkSetupMenu } from '../pages/NetworkSetupMenu' +import { PrivacyPolicy } from '../pages/PrivacyPolicy' import { ProtocolSetup } from '../pages/ProtocolSetup' import { RobotDashboard } from '../pages/RobotDashboard' import { RobotSettingsDashboard } from '../pages/RobotSettingsDashboard' @@ -195,6 +196,12 @@ export const onDeviceDisplayRoutes: RouteProps[] = [ name: 'Emergency Stop', path: '/emergency-stop', }, + { + Component: PrivacyPolicy, + exact: true, + name: 'Privacy Policy', + path: '/privacy-policy', + }, { Component: DeckConfigurationEditor, exact: true, diff --git a/app/src/assets/images/on-device-display/privacy_policy_qrcode.png b/app/src/assets/images/on-device-display/privacy_policy_qrcode.png new file mode 100644 index 0000000000000000000000000000000000000000..3de0cbe215865cb3a2307d2ad958b661b826e9a5 GIT binary patch literal 10003 zcmd6Nc~}#7*EZJHSht~y1{9s(ifi1FZH5RI`cwt0xYSAn#9add1tes|VbP+3`+|~y zvdAJTDuS3%TtEoJm2@e-(O!sE@tLF=iK)>=eLoI zgI>$shYlJ&$jr=a=no!lKbe{JW6_`S1N+lYcAun*=wDxN;Vk2rnO#d9Z1nwxzV8?O zllx+`E7jKR^!3YatJa3BUAEN0pSNq4?sE_?3WnY6{s;E3HJzTq=>2T%At$RBas z0)qYbYzqw8#@o#@#r5^$g@!nfA8#W1^Yy#Vfbea9G3^fioEDuR+k~*^%$m*qGdAt& zWP0l0wJkhg=Q_7-y8?Cx(;U!T``J#P?EiuM#rTEi+Alm8E&9^)3*^6hdItyWapmoz zDMO%@{(Ayw>aDzx&(2?hpBcKhhZ)* zFq6ron@n5FWU_q-VlmPJ!^C-cc>)B%uzM~p930mZ1R)k<2(piUBLajbz;T@mhkm=n z#Kw#qX%QG0l%9SmFpw7%7^tT)9A`2|RZApHOZv@}NU9NmKukx2U9fv%pAEDgXR-J$ zFEB7JHV%SdixDGzHf-?W`fyy}^b9&uI&&1$$7e%KOiWx{EG8BQ1_fG-u+Z!AkrpFq zS|-!--aTxD#mL;eytufS*ti%mCZ?6e#l|{Akoc|`a)$J{POuMwUEq;)+7=eEbRgO; zHZC?M4%g%2d-rIS>6b3mNF=Ze=Tdt52D(f>T#_JQ7;2TtY9uvAI&FgFa9jk)KKn&< zksK^7nR$7+Z8F&?Cew$@y^@!QVRs3VFp>lWJ7eOz^otkBL-q;oVqyq}?ux}hL4h!x zAq-1us_%-ipuiw!XPCze671XO!`+aPeu)muv>YXCZQbCrfdjipY9!Uwl1mw;GH`u- zTwqRhO-;t7bcv)U?@FHKC?-J|X%L28>=!xY<>sZQXUJOH?Clp-OR66}ct{wDD1OvF zL_llm=X*b+C7!FYlL@8Vm-#-cVe8$4DA;bMs`fHo|CBDwR8S z?8v2q=H^E9c=Vc?jd%RPjk7BJ^@sBZ6Rq7xKF--26*6j-2Fz~JC z*;&(U!o=5Yq&1=F$gw}2Iigrh-M$%0Tv>OtX7dou65B)DIy*|wFOKbvFKoQoeG6A< zn(#;|Hk&#cn-~>NMyb_dGiUI7KMo!|SgY?q*wyRjo!_ThcWS|0{Fq#GJ0&{h>fULU z%a%6#>*2}S`99S81%g5Aj&EME;nHu1(w1WT-^aiI(fZ-Px}U9|dSn(0>gaGe+^+Ck z>m2PnCNs?B0snlE-CJI)V=gSPt^VrjsQj}_U;C>IG6ixkff$C9W3 z*Yq~~jjNE5G<}E0|DJ2`$e@j)cDnZdjVMBzibs6L#uB{`IiIRYFm| zO?pmq!2`^oFlR~a6 zDRaMIJ-YT8c)i$bO69_NSH{#ymeO2;+~HhB!Tgh9bMPwzUoTuZW%G&4_fqx_KH~Uv z@}+M(T2I9|=tr#fd`DKcUpUy2Q=ho{{ov#4FQr+1bNITXVpE~Far$VdB^ z+SZJZb9q4r@7qrE`1+8~iqmUK&YWDbT9cl(;U;!+Ezx0KeYC~?V&vEDQ+if}wZi?$ zx1pMK#$Dyq+9gb#+w_VbXBg@RHBnezvjf_fen!E79 z`gvZ{iHT6h5hL>+l63`2z=q-y?~qjG5Ly1HWo0P=9aE<~a&+ImM{)T{wm8%H;|Yp< z*s;cWpRq;OJz-jM`cW(RU}EtEYDqV|YK`y_HUN(txnXN(?%vv@C3dxICt4glw|QRi z+3oYdiw?i`9A53Gv8%Njp*Z?O(qXX&zjiF{_^!IMqd@oOU6*%=Z$@82-}cARDM14_ zE{W-wef$z;RmZH1KCMEWuIUqWJ>`d&a06d^zQ5R2F71c-m={wjcXkJhfXj%NAeyv!+|v+srA29Zr)wtGtX8! zjmfQ?HFHw&@{=9jWpnOcj(l5+aQ!ruKlyF7ig^Agy8UMV;b5pcIZUT6*3Tdplq0!m zgXeM!vw)q49z@MsfAV?54*g=H`FXA}?_o!M%ggJNtw*28ysbK}$Z}M{gUOQLiyJxe z!jQZNjsecsU1whi|JQ*2Hj7GQo>h)pYJktKC9IaOSfY;`m2=!f|AVPG$k!xTU$>=4 z8EbT(UTps6>9mmRZt@!&Z+)jZ5fbVhHFbXwcltGbRqs5f1*7~Q-;PFC9iqE|FpSep zLqWRFD9y7uJxhgfC|^_2Q+Hen;p&_+&%3va_jXit)V-J29bdDC z>kull>SmvEcfqw&!XKP_7JPq2O!0ZfEO38%qMHk`b-eHRHgLi#iYM&?E z)JVUk9BQ@c*V3;gRqu}%dL7?2Z_jPsDQn5;GB3@=;4H~m`=)?yyA`~C+!2-1TEmFv zC%)f;kL@ksOA17C5zxyjnMIi!BRN#@Nnrc-!f`)Lhca@&LF3Q2y{u0?-{AZeIk{uz zyB(sO%RT;r+I0d3F+&>Muh+VF{hT2;Um5G~Ne2+>)sW);`(ELSf`algr^~ww0uGpk zTAIh5IHP76gBy%&6dSr%Qo)${r1{oP-&TL| z+9opXed57Y_1T$I>+Ve(mhu(#AWO>NFB3KW-02Q6LQhFKaHaN_uZiz!xF;p!G&nW% z4*^BC!%yT{vA|&HMdw6W78tT1cbZS-J6>ATSK{wiZ|RvJL>(%XBB3m@dY>5RjUJa; zF9Y{e^F-h+6{pI6t)Cmzb}+5X?!wrPvp+)z(|FO?!M%fZ=T!R|jAy{l%poq+Bn2|H zv!IolqQlHg;_ouHTuVx{pB{OWm2w<4KO>v#FA3;or_!{KhkVm%{3~&}OMH-5P;z4b z^`wnXyT7SG#fhx_$WHRMgfe~{1+I`h)jtpD#`je?bz_=)gMEv}3cBs~ULE|ycA@>{S>XNexKk&^p zouthf4jHddY*G6g1c&B7aHj9&Mis~I-ni<>4ZB;F2usIo7o%*PTt1xJ92=p?H}I+0DS_RbTW)#{&e zL%rbiJ!x+nx)x&KVA@4tm86G5OGZMvIr%P8j45(7DY5-EelDO}srqEa1Kr%=WMK>1 z*H1bxu$$wW#f#bl4aCn}xsZ?B=uVg5tW%QD83gmahK=y)&j9Dg=wD8jqk&h_cgT0l zipJWj7}xm2RPg6ed;ZXV^G`nEerh=nIv@*9qHG+_4sBKi^J@lKpY9w6DF)OQF0=<@ z)ZcG#y(;DmU zGl)?g>xCw(j2(XCr5CUEFR~sn14W+PXV^$xjl)Pr{l^tkaC^v>K?$#05=%{8?3>T` zDlAoQI-y*bas=4Z?Pv|Usovls&QN5N@xkF{w0NXoN*Z5sv|YzyU=MmY6R``x=-O`g z$4IchPNb&M48A1&OSIVM0cb@{AM=3W%xw<)szUqA-y+xV&`oHeh{xTWw}Y_bE5!2h z5PlLWZPu}lNvjzf@|zP6QICH|UF+*Ea+j7d>~&+00ORqG{2EalJeNFe7Y8`3Zw{MV zp*3!FfXeSH1Nr7pcyg5d#l*aWW)7WhT>d?tQu(5XGfWWQf_exX!H^u2^B1V>OVyup zf*UO%MXy%aMO~62`q&Xt$7f2RLa1wK7hqH;^EU~%UF)g6i?ggR;c7=~xV4HgbQ674 z0BA+y9SG^`Y==t5cVlr@ljKpNmAE_^P~{`jpz=s+>?ztnWltKkf&4@}u$4=#;wNcI z#~Gko$oUMd6pL?(q(>X2&wP)TXr;b5D{X?X1w()`ZMd34YCIn?B9zzz701mTDnqDo zN0dEnsIgP{8=z`J;$`T8Bm5&2>1-`+sbb*u@JO)rE;a0v7Hf)#TqG|0pGj#AHfoj4 zx^X7 zxgJ+@yaiK&yPa3LLkAS$mIp!HrgsFyXc>H6;VVNka-_*Xw#xA=s!VmDvneBx1JY}V z`QtJIwdU7^Xtbo%K$lQU*$B!=jwQ%+9Lukn{02UtxJ>~)j(tF>?lzKy0+pSOivKSVt_ZE^wGWOqFjwf2y`~o z1-8CJ7dDWz7Vp(xnDt_fu)?ko(`+cb8zDb3){%E7N`8cz9Y)Rib;BBqvIVDPcBk*f zu6gP)WIrc%kaLU!le01GaaQ06yUA0JT|U(RhvN_5jrSfja@J4ZJip{|wt8dWX@r$D zz7MnrXf4_yjga1{7t2e^9$HdAe+ZV0yq8J7^#3>l5LnNri)agO zgR&aI7)Y^JD>R5oz^thfesv?m7csw(`2X+2p*o>rM{C$~QWzWY0^DRcc#qMnt}5wT zL(e}*u?l2t#1f6mUsDCMd3tmw{A`(+k39so`Dmy24PF8lNR{){_WA>{>f<3kV9&gH$vH@Q;w0K(;&yu3aTx};XwpIMKD9A`_} zJ+9{fp}_~^4$()aNsi_>8z){kExBJ(LhZl>2f^nhUG-Q0#P}X^4L0a$r2#voJgu{- z>J%hv439*gN#jF&Ack5+=F1F|1Rm;Q?gPOb1>-l!T^y&jxd2GD%ZfDacG%2Mr1iwY zPHh4Q_Ug4)EjSOfm+*(R$p~(x_D5q{e`T6E%VuRu%t?yrm=stY&K&so>t(hU~5;Lp$DJctiMwa$VKcj0L@nx5d)- z-s5}N09?~6*eeLdEW4E1hSBH3psZ9_aZ6f6wtOpd0HvN1NfVXwM(V9yFki{{az$$L z40o#-6`_z=m?FH3z5NR@?_!Rzt*5^Y+AHWIwTE$Tem@L-&!a75e59nfDfZ%~8PA@Hln&B&|B$MTp6 z**QSKkW8UQsQTlqk5nlg^jE*W_zRyL%Mv9S5hgWOWTVuJ#m zUC%cz6?CD!{N5kh1d4=gXkb*;hsdVwhC4M3U)l{h1Uy$in{w8W%Fh1mCm7euIYZ|R zw*1ZQu+g(f$cQp;I|q^YaN z$BH_}6XhcK(l3InM!;f^2~ZQh{j1rAjH{Dh8CdvOdHjj^{9eBli9eEb){byl#M8%S zLmq-M+(xEyJug?k0yniSgUzdx1*zG#%qsVA3$DR5ZXCqz!G3pF1omSlKwTm>a z6|(q668SZ_{Asd)b>5Cx>mtkIiDm$R&k29c8 zOWGNw5ii)QG#r&rF&fag@jm~*CDL-zxk%?;v&V8vRcqyWT@md6I zS1qAuJ8eu)vh$djo@rxR&{DhAHRSAG&NA^pJzB%q*3`?0Ro817-yr_{q_!Z$QZJg! z{hHt?(E0SrUy64c(BBzv!$bZev?Dmp#y{B_!8j=E36q1E>seLFq$rTolcIM#dZapa z0j^+eYk~+K7?sqv45>K;qSFQ*o4?Mpamh}Y}U#e#U~0G+G6m4F+8+IsM_K@2oS zNi_>ZVp5bOO$E~EO4>(IfVRIz!-zEwi!!ITf5{UAavRLbhizNK6lfNm#quWV0pSuw zaBMJF(2cHBu!;n`7#*F!AbhNz)d4IP9@kQVuooBcDp%GpR?tN`UqZzjqD@koWN7P_ zS_uky5Y89qDRf$SS{P;ZPsL z3cT?ld9~?WLd$JIuEJRo2E8yB13&jI%Q5wH1(MVQ|6Unv?OVo7Lx#7hms#*1p>K0@ zyUyD*}SA*#gq#e8h{tg$NB77BS2z4De zhRq>3k%V(SHYhx>bMV$52~H?D-;pZAX%k?2uBJI@RL*n zz)Re?G++?dDTBPQUIP>ofZnno7>2>Xgm2& zq(i%|Ili1RmDkNt*(uQ0;H!wcy`hC=#0@$|oiewA_kZ&8FX#p)aI)|GGB|0Ym2eN3qmTuVL2 zy9|5ScTuJ4lP&6Nu!oqTtZzZTFW~OXYFn@3R2&9MNfsZ{(}(X8t|wB%rkxCR{2xE9 zhs}JMj^E2^X8ML;1K+;vV>nl7Xo1yF({Mg<-r&w~ z680r{8_?>1l0Fk$>*l{^ul@+^9nYPY;yk8IohffQ9%L=479N&Jjm=NC@JM}?vYy(> zrjGNgX-&pqdYc07Qyr_><{z0kdKydW zWS&#WRrYThDG~4-4+ZH>TX29@6jkE^m1_ns!`)T(>^&3;m49HmenLI$^=Y+?!>#Bb zLtzHO;Rzy-8o*vovP*l;r_f1zdY4=VMn7Q`2~wxRr~e!A-_d$zzrrGlW9m*SFjwme zU$Tx`(Sd%i;#}cwt#HTBbLC&E{@vMO0@$jL%`jf(SI7TnXN^!7cI)56cisYbl)tXI zlfxtL8uZ(>nl8iJ&Uzks!_d}oC+BUKW$=3EjmS#x51HQ4xRQBKu!aHCDJN zp;5|rtb)Bs-!8Q2zQE=+dttAJ-mSetu~!}hCtoEHB1_d5RX~NQXgl6;ZwceoC-bH3 zU%w|f%m_@9`NCLMQ5XQaiMMQRXI7{K#j0}%{fCvkhOwcQfKI9SWa+|r-mr;xi-lO%+|nCIlKOdd8N?Q^~ROG94wO* zdD7AXPRK``p@od!nAy=%dld+QX64kmH0Pl0$tOqV5T znRwz!B*~C^iWJd{H$IHI@eXbEhn_^$$mYYx0Ee~o7R6Dv5sMQHl19OeCE!F*9npo7 zP*q|pdR3VD2K;DXburJi0kxn7KZ*Y|r;)K?xmy13!6jWNbfFEN0LBnbZ^^AvMi5q$ zt7$f)PeP0*W&9L_h!%8|Z{DX4FKi)Qk=jh&kxiccDJZ)t==HU)Zw{ey!y+vgcQUS@bcAg`Y`iWZXU9COit13Q~3> zHJBF^idwM{oe%Id$vz) z-M}~3jg?aV2J~x;w&f${GPLOeTjF;J^LI*I1Ns^9DYGP}PHPjwzvKQp<5kqF&3yB= zqxlV3=J@?m&R8e#dIaIO4M}>B-c!~@w3d3# ze+;@A9$l5v_H6y5=OpV9om#58JXW~%5KJ$tzStY~t^bI;JSez!1NP|Q=!Sd9j}C^P zSt2y^13@8oC$~2to#6aNSJw6K$cH=y^G5?}L6<7NdID3BHiu-rrg!Px*sGM!NR04V zyYX$^x#$yLsObCUKSkUb3+$cEE#ZM6e-}G{in{Oi1+H}1>m_ey9g*IcQHZmeL3$9p zLt|k2c;>fZmat$Ja*7@VP??s|%x?x>|Af7|L9&u1Jp^ZwP~{wpqdR}cDzp}Dz;)bO zN`KitRl4#FT;3MUM{0gcINS4owKA{HG$cMXvRB`_Qm3;Yk|`~I z0k|%*Dm5=X{jSYl|LC4vN3yzIPbeFT;jOEvmsjLf8N~WKDR#HOtmh@y2$z#>hd(m1 z=ks>LUU!SyKVPLs_#2|9RgHNAtlHM}N+9}Iu#mb;+mM;h`R@hSRO*9For the robot to move accurately and precisely, you need to calibrate it. Pipette and gripper calibration is an automated process that uses a calibration probe or pin.After calibration is complete, you can save the calibration data to your computer as a JSON file.", "about_calibration_title": "About Calibration", + "acknowledge_privacy_policy": "Acknowledge Privacy Policy", "advanced": "Advanced", + "agree": "I agree", "alpha_description": "Warning: alpha releases are feature-complete but may contain significant bugs.", "alternative_security_types": "Alternative security types", "alternative_security_types_description": "The Opentrons App supports connecting Flex to various enterprise access points. Connect via USB and finish setup in the app.", @@ -206,6 +208,7 @@ "pipette_offset_calibration_recommended": "Pipette Offset calibration recommended", "pipette_offset_calibrations_history": "See all Pipette Offset Calibration history", "pipette_offset_calibrations_title": "Pipette Offset Calibrations", + "privacy_policy_description": "By proceeding you are agreeing to share robot usage data. Opentrons uses this data to improve our products and services.To read more about our data collection policies, visit our Privacy Policy.", "problem_during_update": "This update is taking longer than usual.", "proceed_without_updating": "Proceed without update", "protocol_run_history": "Protocol run History", diff --git a/app/src/organisms/OnDeviceDisplay/NameRobot/ConfirmRobotName.tsx b/app/src/organisms/OnDeviceDisplay/NameRobot/ConfirmRobotName.tsx index b8a7123603f..be5fe3530b7 100644 --- a/app/src/organisms/OnDeviceDisplay/NameRobot/ConfirmRobotName.tsx +++ b/app/src/organisms/OnDeviceDisplay/NameRobot/ConfirmRobotName.tsx @@ -34,7 +34,7 @@ export function ConfirmRobotName({ } return ( <> - + - + - + { render() screen.getByTestId('StepMeter_StepMeterContainer') const bar = screen.getByTestId('StepMeter_StepMeterBar') - expect(bar).toHaveStyle('width: 33.33333333333333%') + expect(bar).toHaveStyle('width: 20%') }) it('should render Searching for networks', () => { diff --git a/app/src/pages/ConnectViaWifi/index.tsx b/app/src/pages/ConnectViaWifi/index.tsx index fb3fcc98077..97792806512 100644 --- a/app/src/pages/ConnectViaWifi/index.tsx +++ b/app/src/pages/ConnectViaWifi/index.tsx @@ -110,7 +110,7 @@ export function ConnectViaWifi(): JSX.Element { return ( <> - + disengaged @@ -38,7 +45,7 @@ export function EmergencyStop(): JSX.Element { return ( <> - + history.push('/robot-settings/rename-robot')} + onClick={() => { + seenOptIn && optedIn + ? history.push('/robot-settings/rename-robot') + : history.push('/privacy-policy') + }} /> diff --git a/app/src/pages/NameRobot/__tests__/NameRobot.test.tsx b/app/src/pages/NameRobot/__tests__/NameRobot.test.tsx index b07def9bebb..e58ffcd56d7 100644 --- a/app/src/pages/NameRobot/__tests__/NameRobot.test.tsx +++ b/app/src/pages/NameRobot/__tests__/NameRobot.test.tsx @@ -150,11 +150,4 @@ describe('NameRobot', () => { screen.getByText('Enter up to 17 characters (letters and numbers only)') screen.getByText('Confirm') }) - - it('should call a mock function when tapping back button', () => { - mockuseIsUnboxingFlowOngoing.mockReturnValue(false) - render() - fireEvent.click(screen.getByTestId('name_back_button')) - expect(mockPush).toHaveBeenCalledWith('/robot-settings') - }) }) diff --git a/app/src/pages/NameRobot/index.tsx b/app/src/pages/NameRobot/index.tsx index 2b65755b8fc..a8d4a0ebdba 100644 --- a/app/src/pages/NameRobot/index.tsx +++ b/app/src/pages/NameRobot/index.tsx @@ -19,7 +19,6 @@ import { COLORS, TYPOGRAPHY, Icon, - Btn, } from '@opentrons/components' import { useUpdateRobotNameMutation } from '@opentrons/react-api-client' @@ -153,7 +152,7 @@ export function NameRobot(): JSX.Element { ) : ( <> {isUnboxingFlowOngoing ? ( - + ) : null} - - { - if (isUnboxingFlowOngoing) { - history.push('/emergency-stop') - } else { - history.push('/robot-settings') - } - }} - > - - - + {isUnboxingFlowOngoing diff --git a/app/src/pages/NetworkSetupMenu/index.tsx b/app/src/pages/NetworkSetupMenu/index.tsx index fe245bf22f5..6d668131862 100644 --- a/app/src/pages/NetworkSetupMenu/index.tsx +++ b/app/src/pages/NetworkSetupMenu/index.tsx @@ -44,7 +44,7 @@ export function NetworkSetupMenu(): JSX.Element { return ( <> - + () + const isUnboxingFlowOngoing = useIsUnboxingFlowOngoing() + const seenOptedIn = useSelector(getAnalyticsOptInSeen) + const optedIn = useSelector(getAnalyticsOptedIn) + + const handleAgree = (): void => { + dispatch(setAnalyticsOptInSeen()) + dispatch(toggleAnalyticsOptedIn()) + } + + if (seenOptedIn && optedIn) { + if (isUnboxingFlowOngoing) { + history.push('/robot-settings/rename-robot') + } else { + history.push('/dashboard') + } + } + + return ( + <> + {isUnboxingFlowOngoing ? ( + + ) : null} + + + + {t('acknowledge_privacy_policy')} + + + + + }} + /> + + {PRIVACY_POLICY_URL} + + + + {IMG_ALT} + + + + + + + + ) +} diff --git a/app/src/pages/RobotDashboard/AnalyticsOptInModal.tsx b/app/src/pages/RobotDashboard/AnalyticsOptInModal.tsx deleted file mode 100644 index ae3d6a112f5..00000000000 --- a/app/src/pages/RobotDashboard/AnalyticsOptInModal.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import * as React from 'react' -import { useTranslation } from 'react-i18next' -import { useDispatch, useSelector } from 'react-redux' - -import { - Flex, - COLORS, - DIRECTION_COLUMN, - DIRECTION_ROW, - SPACING, -} from '@opentrons/components' - -import { SmallButton } from '../../atoms/buttons' -import { StyledText } from '../../atoms/text' -import { Modal } from '../../molecules/Modal' -import { updateConfigValue } from '../../redux/config' -import { getLocalRobot } from '../../redux/discovery' -import { updateSetting } from '../../redux/robot-settings' - -import type { Dispatch } from '../../redux/types' - -export const ROBOT_ANALYTICS_SETTING_ID = 'disableLogAggregation' - -interface AnalyticsOptInModalProps { - setShowAnalyticsOptInModal: (showAnalyticsOptInModal: boolean) => void -} - -export function AnalyticsOptInModal({ - setShowAnalyticsOptInModal, -}: AnalyticsOptInModalProps): JSX.Element { - const { t } = useTranslation(['app_settings', 'shared']) - const dispatch = useDispatch() - - const localRobot = useSelector(getLocalRobot) - const robotName = localRobot?.name != null ? localRobot.name : 'no name' - - const handleCloseModal = (): void => { - dispatch( - updateConfigValue( - 'onDeviceDisplaySettings.unfinishedUnboxingFlowRoute', - null - ) - ) - setShowAnalyticsOptInModal(false) - } - - const handleOptIn = (): void => { - dispatch(updateSetting(robotName, ROBOT_ANALYTICS_SETTING_ID, false)) - dispatch(updateConfigValue('analytics.optedIn', true)) - handleCloseModal() - } - - const handleOptOut = (): void => { - dispatch(updateSetting(robotName, ROBOT_ANALYTICS_SETTING_ID, true)) - dispatch(updateConfigValue('analytics.optedIn', false)) - handleCloseModal() - } - - return ( - - - - - {t('opt_in_description')} - - - - - - - - - ) -} diff --git a/app/src/pages/RobotDashboard/WelcomeModal.tsx b/app/src/pages/RobotDashboard/WelcomeModal.tsx index 23777645a81..32ba09d7ec0 100644 --- a/app/src/pages/RobotDashboard/WelcomeModal.tsx +++ b/app/src/pages/RobotDashboard/WelcomeModal.tsx @@ -1,5 +1,7 @@ import * as React from 'react' import { useTranslation } from 'react-i18next' +import { useDispatch } from 'react-redux' +import { updateConfigValue } from '../../redux/config' import { COLORS, @@ -18,19 +20,19 @@ import { Modal } from '../../molecules/Modal' import welcomeModalImage from '../../assets/images/on-device-display/welcome_dashboard_modal.png' import type { SetStatusBarCreateCommand } from '@opentrons/shared-data' +import type { Dispatch } from '../../redux/types' interface WelcomeModalProps { - setShowAnalyticsOptInModal: (showAnalyticsOptInModal: boolean) => void setShowWelcomeModal: (showWelcomeModal: boolean) => void } export function WelcomeModal({ - setShowAnalyticsOptInModal, setShowWelcomeModal, }: WelcomeModalProps): JSX.Element { const { t } = useTranslation(['device_details', 'shared']) const { createLiveCommand } = useCreateLiveCommandMutation() + const dispatch = useDispatch() const animationCommand: SetStatusBarCreateCommand = { commandType: 'setStatusBar', params: { animation: 'disco' }, @@ -46,8 +48,13 @@ export function WelcomeModal({ } const handleCloseModal = (): void => { + dispatch( + updateConfigValue( + 'onDeviceDisplaySettings.unfinishedUnboxingFlowRoute', + null + ) + ) setShowWelcomeModal(false) - setShowAnalyticsOptInModal(true) } React.useEffect(startDiscoAnimation, []) diff --git a/app/src/pages/RobotDashboard/__tests__/AnalyticsOptInModal.test.tsx b/app/src/pages/RobotDashboard/__tests__/AnalyticsOptInModal.test.tsx deleted file mode 100644 index 09e521b43da..00000000000 --- a/app/src/pages/RobotDashboard/__tests__/AnalyticsOptInModal.test.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import * as React from 'react' -import { fireEvent } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' - -import { i18n } from '../../../i18n' -import { updateConfigValue } from '../../../redux/config' -import { getLocalRobot } from '../../../redux/discovery' -import { updateSetting } from '../../../redux/robot-settings' -import { AnalyticsOptInModal } from '../AnalyticsOptInModal' - -import type { DiscoveredRobot } from '../../../redux/discovery/types' - -jest.mock('../../../redux/config') -jest.mock('../../../redux/discovery') -jest.mock('../../../redux/robot-settings') - -const mockUpdateConfigValue = updateConfigValue as jest.MockedFunction< - typeof updateConfigValue -> -const mockGetLocalRobot = getLocalRobot as jest.MockedFunction< - typeof getLocalRobot -> -const mockUpdateSetting = updateSetting as jest.MockedFunction< - typeof updateSetting -> - -const render = (props: React.ComponentProps) => { - return renderWithProviders(, { - i18nInstance: i18n, - }) -} - -describe('AnalyticsOptInModal', () => { - let props: React.ComponentProps - - beforeEach(() => { - props = { - setShowAnalyticsOptInModal: jest.fn(), - } - mockGetLocalRobot.mockReturnValue({ name: 'Otie' } as DiscoveredRobot) - }) - - it('should render text and button', () => { - const [{ getByText }] = render(props) - - getByText('Want to help out Opentrons?') - getByText( - 'Automatically send us anonymous diagnostics and usage data. We only use this information to improve our products.' - ) - getByText('Opt out') - getByText('Opt in') - }) - - it('should call a mock function when tapping opt out button', () => { - const [{ getByText }] = render(props) - fireEvent.click(getByText('Opt out')) - - expect(mockUpdateConfigValue).toHaveBeenCalledWith( - 'analytics.optedIn', - false - ) - expect(mockUpdateSetting).toHaveBeenCalledWith( - 'Otie', - 'disableLogAggregation', - true - ) - expect(props.setShowAnalyticsOptInModal).toHaveBeenCalled() - }) - - it('should call a mock function when tapping out in button', () => { - const [{ getByText }] = render(props) - fireEvent.click(getByText('Opt in')) - - expect(mockUpdateConfigValue).toHaveBeenCalledWith( - 'analytics.optedIn', - true - ) - expect(mockUpdateSetting).toHaveBeenCalledWith( - 'Otie', - 'disableLogAggregation', - true - ) - expect(props.setShowAnalyticsOptInModal).toHaveBeenCalled() - }) -}) diff --git a/app/src/pages/RobotDashboard/__tests__/WelcomeModal.test.tsx b/app/src/pages/RobotDashboard/__tests__/WelcomeModal.test.tsx index 77ca462c490..a035398aa18 100644 --- a/app/src/pages/RobotDashboard/__tests__/WelcomeModal.test.tsx +++ b/app/src/pages/RobotDashboard/__tests__/WelcomeModal.test.tsx @@ -33,7 +33,6 @@ describe('WelcomeModal', () => { mockCreateLiveCommand = jest.fn() mockCreateLiveCommand.mockResolvedValue(null) props = { - setShowAnalyticsOptInModal: jest.fn(), setShowWelcomeModal: mockFunc, } mockUseCreateLiveCommandMutation.mockReturnValue({ @@ -66,6 +65,5 @@ describe('WelcomeModal', () => { const [{ getByText }] = render(props) fireEvent.click(getByText('Next')) expect(props.setShowWelcomeModal).toHaveBeenCalled() - expect(props.setShowAnalyticsOptInModal).toHaveBeenCalled() }) }) diff --git a/app/src/pages/RobotDashboard/index.tsx b/app/src/pages/RobotDashboard/index.tsx index 3913147db07..346129757c8 100644 --- a/app/src/pages/RobotDashboard/index.tsx +++ b/app/src/pages/RobotDashboard/index.tsx @@ -1,6 +1,7 @@ import * as React from 'react' import { useTranslation } from 'react-i18next' import { useSelector } from 'react-redux' +import { useHistory } from 'react-router-dom' import { COLORS, @@ -18,7 +19,10 @@ import { RecentRunProtocolCarousel, } from '../../organisms/OnDeviceDisplay/RobotDashboard' import { getOnDeviceDisplaySettings } from '../../redux/config' -import { AnalyticsOptInModal } from './AnalyticsOptInModal' +import { + getAnalyticsOptInSeen, + getAnalyticsOptedIn, +} from '../../redux/analytics' import { WelcomeModal } from './WelcomeModal' import { RunData } from '@opentrons/api-client' import { ServerInitializing } from '../../organisms/OnDeviceDisplay/RobotDashboard/ServerInitializing' @@ -39,10 +43,14 @@ export function RobotDashboard(): JSX.Element { const [showWelcomeModal, setShowWelcomeModal] = React.useState( unfinishedUnboxingFlowRoute !== null ) - const [ - showAnalyticsOptInModal, - setShowAnalyticsOptInModal, - ] = React.useState(false) + + const seen = useSelector(getAnalyticsOptInSeen) + const hasOptedIn = useSelector(getAnalyticsOptedIn) + const history = useHistory() + + if (!seen || !hasOptedIn) { + history.push('/privacy-policy') + } const recentRunsOfUniqueProtocols = (allRunsQueryData?.data ?? []) .reverse() // newest runs first @@ -89,15 +97,7 @@ export function RobotDashboard(): JSX.Element { gridGap={SPACING.spacing16} > {showWelcomeModal ? ( - - ) : null} - {showAnalyticsOptInModal ? ( - + ) : null} {contents} From 8398c83a52e2d0f60dc5814d1e5984746e44e94c Mon Sep 17 00:00:00 2001 From: Alise Au <20424172+ahiuchingau@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:46:18 -0500 Subject: [PATCH 05/10] fix(api): home before retrieving gantry position for disengaged Z mounts in FLEX (#14437) * use prepare_for_mount_movement and add home_if_idle for ot3 gantry position call --- api/src/opentrons/hardware_control/api.py | 7 +++- api/src/opentrons/hardware_control/ot3api.py | 39 +++++++++++++++++-- .../protocols/motion_controller.py | 4 ++ .../move_to_maintenance_position.py | 6 +-- .../protocol_engine/execution/gantry_mover.py | 13 +++++++ .../protocol_engine/execution/movement.py | 13 +++++++ 6 files changed, 72 insertions(+), 10 deletions(-) diff --git a/api/src/opentrons/hardware_control/api.py b/api/src/opentrons/hardware_control/api.py index 3ff5d01e7d3..4b62eba7e3a 100644 --- a/api/src/opentrons/hardware_control/api.py +++ b/api/src/opentrons/hardware_control/api.py @@ -762,7 +762,7 @@ async def move_to( top_types.Point(0, 0, 0), ) - await self._cache_and_maybe_retract_mount(mount) + await self.prepare_for_mount_movement(mount) await self._move(target_position, speed=speed, max_speeds=max_speeds) async def move_axes( @@ -822,7 +822,7 @@ async def move_rel( detail={"mount": str(mount), "unhomed_axes": str(unhomed)}, ) - await self._cache_and_maybe_retract_mount(mount) + await self.prepare_for_mount_movement(mount) await self._move( target_position, speed=speed, @@ -842,6 +842,9 @@ async def _cache_and_maybe_retract_mount(self, mount: top_types.Mount) -> None: await self.retract(self._last_moved_mount, 10) self._last_moved_mount = mount + async def prepare_for_mount_movement(self, mount: top_types.Mount) -> None: + await self._cache_and_maybe_retract_mount(mount) + @ExecutionManagerProvider.wait_for_running async def _move( self, diff --git a/api/src/opentrons/hardware_control/ot3api.py b/api/src/opentrons/hardware_control/ot3api.py index 38bcbb06563..4a586a43c4e 100644 --- a/api/src/opentrons/hardware_control/ot3api.py +++ b/api/src/opentrons/hardware_control/ot3api.py @@ -247,6 +247,23 @@ def estop_cb(event: HardwareEvent) -> None: OT3RobotCalibrationProvider.__init__(self, self._config) ExecutionManagerProvider.__init__(self, isinstance(backend, OT3Simulator)) + def is_idle_mount(self, mount: Union[top_types.Mount, OT3Mount]) -> bool: + """Only the gripper mount or the 96-channel pipette mount would be idle + (disengaged). + + If gripper mount is NOT the last moved mount, it's idle. + If a 96-channel pipette is attached, the mount is idle if it's not + the last moved mount. + """ + realmount = OT3Mount.from_mount(mount) + if not self._last_moved_mount or realmount == self._last_moved_mount: + return False + + return ( + realmount == OT3Mount.LEFT + and self._gantry_load == GantryLoad.HIGH_THROUGHPUT + ) or (realmount == OT3Mount.GRIPPER) + @property def door_state(self) -> DoorState: return self._door_state @@ -1153,7 +1170,7 @@ async def move_to( else: checked_max = None - await self._cache_and_maybe_retract_mount(realmount) + await self.prepare_for_mount_movement(realmount) await self._move( target_position, speed=speed, @@ -1264,7 +1281,8 @@ async def move_rel( checked_max: Optional[OT3AxisMap[float]] = max_speeds else: checked_max = None - await self._cache_and_maybe_retract_mount(realmount) + + await self.prepare_for_mount_movement(realmount) await self._move( target_position, speed=speed, @@ -1274,15 +1292,20 @@ async def move_rel( ) async def _cache_and_maybe_retract_mount(self, mount: OT3Mount) -> None: - """Retract the 'other' mount if necessary + """Retract the 'other' mount if necessary. If `mount` does not match the value in :py:attr:`_last_moved_mount` (and :py:attr:`_last_moved_mount` exists) then retract the mount in :py:attr:`_last_moved_mount`. Also unconditionally update :py:attr:`_last_moved_mount` to contain `mount`. - Disengage the 96-channel and gripper mount if retracted. + Disengage the 96-channel and gripper mount if retracted. Re-engage + the 96-channel or gripper mount if it is about to move. """ + if self.is_idle_mount(mount): + # home the left/gripper mount if it is current disengaged + await self.home_z(mount) + if mount != self._last_moved_mount and self._last_moved_mount: await self.retract(self._last_moved_mount, 10) @@ -1301,8 +1324,16 @@ async def _cache_and_maybe_retract_mount(self, mount: OT3Mount) -> None: if mount != OT3Mount.GRIPPER: await self.idle_gripper() + self._last_moved_mount = mount + async def prepare_for_mount_movement( + self, mount: Union[top_types.Mount, OT3Mount] + ) -> None: + """Retract the idle mount if necessary.""" + realmount = OT3Mount.from_mount(mount) + await self._cache_and_maybe_retract_mount(realmount) + async def idle_gripper(self) -> None: """Move gripper to its idle, gripped position.""" try: diff --git a/api/src/opentrons/hardware_control/protocols/motion_controller.py b/api/src/opentrons/hardware_control/protocols/motion_controller.py index 62b711aa261..8387e4a907c 100644 --- a/api/src/opentrons/hardware_control/protocols/motion_controller.py +++ b/api/src/opentrons/hardware_control/protocols/motion_controller.py @@ -226,3 +226,7 @@ def should_taskify_movement_execution(self, taskify: bool) -> None: async def cancel_execution_and_running_tasks(self) -> None: """Cancel all tasks and set execution manager state to Cancelled.""" ... + + async def prepare_for_mount_movement(self, mount: MountArgType) -> None: + """Retract the other mount if necessary.""" + ... diff --git a/api/src/opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py b/api/src/opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py index b610eefe86c..67d60eead86 100644 --- a/api/src/opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +++ b/api/src/opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py @@ -82,10 +82,7 @@ async def execute( ) # the 96-channel mount is disengaged during gripper calibration and # must be homed before the gantry position can be called - if ot3_api.encoder_status_ok(Axis.Z_L) and not ot3_api.motor_status_ok( - Axis.Z_L - ): - await ot3_api.home([Axis.Z_L]) + await ot3_api.prepare_for_mount_movement(Mount.LEFT) current_position_mount = await ot3_api.gantry_position( Mount.LEFT, critical_point=CriticalPoint.MOUNT ) @@ -105,6 +102,7 @@ async def execute( Point(x=_ATTACH_POINT.x, y=_ATTACH_POINT.y, z=max_height_z_mount), ] + await ot3_api.prepare_for_mount_movement(Mount.LEFT) for movement in movement_points: await ot3_api.move_to( mount=Mount.LEFT, diff --git a/api/src/opentrons/protocol_engine/execution/gantry_mover.py b/api/src/opentrons/protocol_engine/execution/gantry_mover.py index be31da77345..7e05c8db247 100644 --- a/api/src/opentrons/protocol_engine/execution/gantry_mover.py +++ b/api/src/opentrons/protocol_engine/execution/gantry_mover.py @@ -75,6 +75,11 @@ async def home(self, axes: Optional[List[MotorAxis]]) -> None: async def retract_axis(self, axis: MotorAxis) -> None: """Retract the specified axis to its home position.""" + ... + + async def prepare_for_mount_movement(self, mount: Mount) -> None: + """Retract the 'idle' mount if necessary.""" + ... class HardwareGantryMover(GantryMover): @@ -211,6 +216,10 @@ async def retract_axis(self, axis: MotorAxis) -> None: ) await self._hardware_api.retract_axis(axis=hardware_axis) + async def prepare_for_mount_movement(self, mount: Mount) -> None: + """Retract the 'idle' mount if necessary.""" + await self._hardware_api.prepare_for_mount_movement(mount) + class VirtualGantryMover(GantryMover): """State store based gantry movement handler for simulation/analysis.""" @@ -286,6 +295,10 @@ async def retract_axis(self, axis: MotorAxis) -> None: """Retract the specified axis. No-op in virtual implementation.""" pass + async def prepare_for_mount_movement(self, mount: Mount) -> None: + """Retract the 'idle' mount if necessary.""" + pass + def create_gantry_mover( state_view: StateView, hardware_api: HardwareControlAPI diff --git a/api/src/opentrons/protocol_engine/execution/movement.py b/api/src/opentrons/protocol_engine/execution/movement.py index 9c77d7dde0a..451f482ad0d 100644 --- a/api/src/opentrons/protocol_engine/execution/movement.py +++ b/api/src/opentrons/protocol_engine/execution/movement.py @@ -111,6 +111,9 @@ async def move_to_well( ) origin_cp = pipette_location.critical_point + await self._gantry_mover.prepare_for_mount_movement( + pipette_location.mount.to_hw_mount() + ) origin = await self._gantry_mover.get_position(pipette_id=pipette_id) max_travel_z = self._gantry_mover.get_max_travel_z(pipette_id=pipette_id) @@ -181,6 +184,9 @@ async def move_to_addressable_area( ) origin_cp = pipette_location.critical_point + await self._gantry_mover.prepare_for_mount_movement( + pipette_location.mount.to_hw_mount() + ) origin = await self._gantry_mover.get_position(pipette_id=pipette_id) max_travel_z = self._gantry_mover.get_max_travel_z(pipette_id=pipette_id) @@ -239,6 +245,13 @@ async def move_to_coordinates( speed: Optional[float] = None, ) -> Point: """Move pipette to a given deck coordinate.""" + # get the pipette's mount, if applicable + pipette_location = self._state_store.motion.get_pipette_location( + pipette_id=pipette_id + ) + await self._gantry_mover.prepare_for_mount_movement( + pipette_location.mount.to_hw_mount() + ) origin = await self._gantry_mover.get_position(pipette_id=pipette_id) max_travel_z = self._gantry_mover.get_max_travel_z(pipette_id=pipette_id) From ae4e2e36022c045c322dae9151f93bee72b926c9 Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Wed, 7 Feb 2024 16:29:10 -0500 Subject: [PATCH 06/10] chore: update python deps to breaking change breakpoints (#14420) This is a PRs to update python dependencies to modern versions. This one stops at the major breaking change point of pydantic 2.0. While Pydantic 2.0 is apparently much much faster (it's written in rust if you can believe it) it also makes a bunch of breaking api changes and in theory provides back-compat patches. Similarly, fastapi 0.100.0 switches internally to depend on pydantic 2, with similarly theoretical back compat patches. So, we've updated to, Dependency Version Changes In prod, major deps (full list is essentially entirely in the robot-server pipfile, see below for why): - fastapi 0.99.0 (from 0.68.1) - pydantic 1.10.12 (from 1.9.2) - uvicorn 0.27.0 (from 0.14.0) - sqlalchemy 1.4.51 (from 1.4.32 - bigger change than you think, and breaking changes above this) In dev tooling, - mypy 1.8.0 (from 0.981) - flake8 7 (from like 3 or something we never updated this) - mock 5 (from 4) - decoy 2 (from 1) - pytest 7.4.4 except robot-server, which is limited by tavern to 7.3 (from various) - tavern 2.9.1 (from 1.6) Version Definition Changes Some people want to use our python libraries that are published on pypi. The problem with this is that our libraries - opentrons and opentrons_shared_data have explicit version pinning in their setup.py install_requires, which makes it incredibly hard for them to coexist with other python packages that aren't comaintained by us (see #11912 , #12839 ). One way to fix this would be version ranges in the setup.py and explicit versions (that are contained within those ranges, and that match or define what's present on the robot) in the pipfiles. We couldn't do this because pipenv had problems with it. Now, however, we've upgraded pipenv, and that strategy works! And since I was going around bumping all the deps anyway, I could figure out what the actual functional dependency version boundaries were. So as part of this, opentrons (api/setup.py) and opentrons_shared_data (shared-data/python/setup.py) now have version ranges for all of their install_requires that aren't other opentrons packages, and I'm pretty sure about those version ranges. They may be smaller than would be ideal, but they're real. --- api/Pipfile | 40 +- api/Pipfile.lock | 1370 +++++++++-------- api/mypy.ini | 2 +- api/setup.py | 10 +- .../opentrons/calibration_storage/helpers.py | 7 +- .../calibration_storage/ot2/models/v1.py | 2 +- .../asyncio/communication/async_serial.py | 2 +- api/src/opentrons/drivers/rpi_drivers/gpio.py | 2 +- .../opentrons/drivers/serial_communication.py | 6 +- .../drivers/smoothie_drivers/driver_3_0.py | 2 +- .../drivers/smoothie_drivers/simulator.py | 4 +- .../hardware_control/backends/controller.py | 2 +- .../backends/ot3controller.py | 13 +- .../hardware_control/backends/ot3simulator.py | 2 +- .../hardware_control/execution_manager.py | 4 +- .../instruments/instrument_abc.py | 2 + .../hardware_control/ot3_calibration.py | 10 +- .../hardware_control/robot_calibration.py | 9 +- .../hardware_control/thread_manager.py | 18 +- .../opentrons/protocol_api/core/instrument.py | 5 + .../core/legacy/module_geometry.py | 6 +- .../protocol_engine/commands/__init__.py | 2 + .../commands/command_unions.py | 4 +- .../execution/command_executor.py | 11 +- .../protocol_engine/state/commands.py | 4 +- .../protocol_engine/state/geometry.py | 11 +- .../protocol_engine/state/modules.py | 7 +- .../opentrons/protocol_reader/input_file.py | 7 +- .../protocols/models/json_protocol.py | 2 +- api/src/opentrons/util/linal.py | 27 +- .../opentrons/commands/test_publisher.py | 8 +- .../config/test_advanced_settings.py | 2 +- .../test_advanced_settings_migration.py | 9 +- api/tests/opentrons/conftest.py | 11 +- .../communication/test_async_serial.py | 2 +- .../communication/test_serial_connection.py | 5 +- .../opentrons/drivers/rpi_drivers/test_usb.py | 8 +- .../drivers/smoothie_drivers/test_driver.py | 4 +- .../backends/test_ot3_controller.py | 50 +- .../backends/test_ot3_estop_state.py | 4 +- .../test_instrument_calibration.py | 2 +- .../instruments/test_nozzle_manager.py | 88 +- .../hardware_control/test_module_control.py | 5 +- .../hardware_control/test_simulator_setup.py | 6 +- .../core/engine/test_protocol_core.py | 2 +- .../core/legacy/test_module_geometry.py | 2 +- .../protocol_api/test_instrument_context.py | 2 +- .../protocol_api/test_instrument_context.py | 5 +- .../core/simulator/test_instrument_context.py | 11 +- .../core/simulator/test_protocol_context.py | 8 +- .../protocol_api_old/test_context.py | 35 +- .../protocol_api_old/test_labware.py | 3 +- .../execution/test_door_watcher.py | 6 +- .../test_labware_movement_handler.py | 4 +- .../test_deck_configuration_provider.py | 2 +- .../resources/test_deck_data_provider.py | 2 +- .../state/test_command_view.py | 2 +- .../state/test_module_store.py | 2 +- .../protocol_engine/state/test_module_view.py | 2 +- .../protocol_engine/state/test_state_store.py | 8 +- .../test_create_protocol_engine.py | 2 +- .../opentrons/protocol_reader/_input_file.py | 4 +- .../test_legacy_context_plugin.py | 8 +- .../protocol_runner/test_protocol_runner.py | 2 +- .../protocol_runner/test_task_queue.py | 18 +- api/tests/opentrons/test_execute.py | 5 +- api/tests/opentrons/test_simulate.py | 5 +- .../opentrons/util/test_async_helpers.py | 2 +- api/tests/opentrons/util/test_linal.py | 9 +- g-code-testing/Pipfile | 27 +- g-code-testing/Pipfile.lock | 594 +++---- .../g_code_functionality_def_base.py | 1 + hardware/Pipfile | 22 +- hardware/Pipfile.lock | 523 ++++--- .../drivers/binary_usb/bin_serial.py | 4 +- .../drivers/gpio/__init__.py | 2 +- .../utils/binary_serializable.py | 2 +- .../motion_planning/move_utils.py | 4 + .../opentrons_hardware/scripts/can_comm.py | 2 +- .../opentrons_hardware/scripts/sensors.py | 2 +- .../opentrons_hardware/scripts/usb_comm.py | 2 +- .../tests/firmware_integration/conftest.py | 12 +- .../tests/firmware_integration/test_eeprom.py | 6 +- .../firmware_integration/test_move_groups.py | 8 +- .../drivers/binary_usb/test_driver.py | 10 +- .../firmware_bindings/test_constants.py | 4 +- .../hardware_control/test_motion_plan.py | 102 +- .../hardware_control/tools/test_oneshot.py | 4 +- .../sensors/test_sensor_drivers.py | 2 +- robot-server/Config.in | 1 - robot-server/Pipfile | 56 +- robot-server/Pipfile.lock | 708 +++++---- robot-server/robot_server/app_setup.py | 3 +- robot-server/robot_server/commands/router.py | 3 + .../robot_server/deck_configuration/router.py | 8 +- .../instruments/instrument_models.py | 2 +- .../robot_server/instruments/router.py | 3 +- .../maintenance_runs/router/base_router.py | 12 +- .../router/commands_router.py | 9 +- .../maintenance_runs/router/labware_router.py | 6 +- robot-server/robot_server/modules/router.py | 9 +- robot-server/robot_server/protocols/router.py | 27 +- .../robot/calibration/check/user_flow.py | 6 +- .../robot/calibration/deck/user_flow.py | 4 +- .../robot/calibration/helper_classes.py | 16 +- .../calibration/pipette_offset/models.py | 2 +- .../calibration/pipette_offset/user_flow.py | 4 +- .../robot/calibration/tip_length/user_flow.py | 4 +- .../robot_server/robot/control/router.py | 15 +- .../runs/router/actions_router.py | 3 +- .../robot_server/runs/router/base_router.py | 15 +- .../runs/router/commands_router.py | 9 +- .../runs/router/labware_router.py | 9 +- .../robot_server/service/json_api/response.py | 77 +- .../robot_server/service/labware/router.py | 3 + .../service/legacy/models/control.py | 53 +- .../service/legacy/models/deck_calibration.py | 6 +- .../service/legacy/models/modules.py | 229 ++- .../service/legacy/models/networking.py | 73 +- .../service/legacy/models/settings.py | 8 +- .../service/legacy/routers/networking.py | 13 +- .../command_execution/callable_executor.py | 2 +- .../robot_server/subsystems/router.py | 35 +- robot-server/setup.py | 17 +- robot-server/tests/conftest.py | 10 +- .../runs/test_deck_slot_standardization.py | 2 +- .../test_deck_configuration.tavern.yaml | 3 +- .../tests/protocols/test_protocols_router.py | 20 +- .../service/legacy/models/test_modules.py | 8 +- .../service/legacy/routers/test_settings.py | 2 +- .../tests/service/session/test_router.py | 2 +- robot-server/tests/service/test_logging.py | 7 +- server-utils/Config.in | 1 - server-utils/Pipfile | 29 +- server-utils/Pipfile.lock | 743 ++++----- server-utils/server_utils/util.py | 2 +- server-utils/setup.py | 17 +- shared-data/command/schemas/8.json | 2 +- shared-data/python/Pipfile | 20 +- shared-data/python/Pipfile.lock | 567 ++++--- .../labware/labware_definition.py | 4 +- .../opentrons_shared_data/pipette/__init__.py | 2 +- .../pipette/pipette_definition.py | 2 +- .../pipette/scripts/build_json_script.py | 3 +- .../scripts/update_configuration_files.py | 2 +- shared-data/python/setup.py | 4 +- .../python/tests/deck/test_typechecks.py | 12 +- .../python/tests/labware/test_typechecks.py | 10 +- .../python/tests/module/test_typechecks.py | 14 +- .../python/tests/pipette/test_typechecks.py | 13 +- .../python/tests/protocol/test_typechecks.py | 13 +- .../python/tests/robot/test_typechecks.py | 9 +- system-server/Pipfile | 43 +- system-server/Pipfile.lock | 813 +++++----- system-server/setup.py | 2 +- system-server/system_server/__main__.py | 2 +- .../system_server/settings/settings.py | 5 +- .../tests/persistence/test_migrations.py | 2 +- update-server/Pipfile | 22 +- update-server/Pipfile.lock | 1059 ++++++------- update-server/setup.py | 2 +- .../buildroot/test_ssh_key_management.py | 2 +- .../name_management/test_name_synchronizer.py | 6 +- usb-bridge/Pipfile | 28 +- usb-bridge/Pipfile.lock | 624 ++++---- usb-bridge/ot3usb/listener.py | 2 +- usb-bridge/ot3usb/serial_thread.py | 2 +- usb-bridge/ot3usb/usb_config.py | 2 +- usb-bridge/ot3usb/usb_monitor.py | 2 +- usb-bridge/tests/test_listener.py | 2 +- usb-bridge/tests/test_tcp_conn.py | 3 +- usb-bridge/tests/test_usb_monitor.py | 2 +- 172 files changed, 4733 insertions(+), 4146 deletions(-) diff --git a/api/Pipfile b/api/Pipfile index 30420dac26c..710a5cb6f22 100755 --- a/api/Pipfile +++ b/api/Pipfile @@ -3,42 +3,48 @@ url = "https://pypi.python.org/simple" verify_ssl = true name = "pypi" +[packages] +jsonschema = "==4.17.3" +pydantic = "==1.10.12" +anyio = "==3.7.1" +opentrons-shared-data = { editable = true, path = "../shared-data/python" } +opentrons = { editable = true, path = "." } +opentrons-hardware = { editable = true, path = "./../hardware", extras=["FLEX"] } +numpy = "==1.22.3" + [dev-packages] # atomicwrites and colorama are pytest dependencies on windows, # spec'd here to force lockfile inclusion # https://github.com/pypa/pipenv/issues/4408#issuecomment-668324177 atomicwrites = { version = "==1.4.0", markers="sys_platform=='win32'" } colorama = { version = "==0.4.4", markers="sys_platform=='win32'" } -coverage = "==5.1" -mypy = "==0.981" +coverage = "==7.4.1" +mypy = "==1.8.0" numpydoc = "==0.9.1" -pytest = "==7.0.1" -pytest-asyncio = "~=0.16" -pytest-cov = "==2.10.1" +pytest = "==7.4.4" +pytest-asyncio = "~=0.23.0" +pytest-cov = "==4.1.0" pytest-lazy-fixture = "==0.6.3" pytest-xdist = "~=2.5.0" sphinx = "==5.0.1" twine = "==4.0.0" wheel = "==0.37.0" -typeguard = "==2.13.1" +typeguard = "==4.1.5" sphinx-substitution-extensions = "==2020.9.30.0" sphinxext-opengraph = "==0.8.1" sphinx-tabs = ">=3.4.1,<4" -mock = "~=4.0.3" -flake8 = "~=3.9.0" -flake8-annotations = "~=2.6.2" -flake8-docstrings = "~=1.6.0" -flake8-noqa = "~=1.2.1" -decoy = "~=1.11" +mock = "==5.1.0" +flake8 = "==7.0.0" +flake8-annotations = "~=3.0.1" +flake8-docstrings = "~=1.7.0" +flake8-noqa = "~=1.4.0" +decoy = "==2.1.1" black = "==22.3.0" -types-mock = "==4.0.1" +types-mock = "~=5.1.0" types-setuptools = "==57.0.2" -opentrons-shared-data = { editable = true, path = "../shared-data/python" } -opentrons = { editable = true, path = "." } -opentrons-hardware = { editable = true, path = "./../hardware", extras=["FLEX"] } # specify typing-extensions explicitly to force lockfile inclusion on Python >= 3.8 typing-extensions = ">=4.0.0,<5" pytest-profiling = "~=1.7.0" # TODO(mc, 2022-03-31): upgrade sphinx, remove this subdep pin jinja2 = ">=2.3,<3.1" -hypothesis = ">=6.36,<7" +hypothesis = "==6.96.1" diff --git a/api/Pipfile.lock b/api/Pipfile.lock index a519d9462e1..cc9f3163e51 100644 --- a/api/Pipfile.lock +++ b/api/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "85e6abfa7a1353756769cf234de3045eac2043749097a794e120eb3e32e2fccd" + "sha256": "f0d4979ecb4f125cef848e0ce31e3a5e9cded69abaf773ad90d00016f6d2a65d" }, "pipfile-spec": 6, "requires": {}, @@ -13,8 +13,7 @@ } ] }, - "default": {}, - "develop": { + "default": { "aionotify": { "hashes": [ "sha256:385e1becfaac2d9f4326673033d53912ef9565b6febdedbec593ee966df392c6", @@ -22,21 +21,373 @@ ], "version": "==0.2.0" }, - "alabaster": { + "anyio": { "hashes": [ - "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3", - "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2" + "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780", + "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5" ], - "markers": "python_version >= '3.6'", - "version": "==0.7.13" + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==3.7.1" }, - "anyio": { + "attrs": { "hashes": [ - "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b", - "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be" + "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", + "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" ], - "markers": "python_full_version >= '3.6.2'", - "version": "==3.6.1" + "markers": "python_version >= '3.7'", + "version": "==23.2.0" + }, + "click": { + "hashes": [ + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + ], + "markers": "python_version >= '3.7'", + "version": "==8.1.7" + }, + "exceptiongroup": { + "hashes": [ + "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", + "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + ], + "markers": "python_version < '3.11'", + "version": "==1.2.0" + }, + "idna": { + "hashes": [ + "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", + "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + ], + "markers": "python_version >= '3.5'", + "version": "==3.6" + }, + "jsonschema": { + "hashes": [ + "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d", + "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==4.17.3" + }, + "msgpack": { + "hashes": [ + "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862", + "sha256:0bfdd914e55e0d2c9e1526de210f6fe8ffe9705f2b1dfcc4aecc92a4cb4b533d", + "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3", + "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672", + "sha256:235a31ec7db685f5c82233bddf9858748b89b8119bf4538d514536c485c15fe0", + "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9", + "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee", + "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46", + "sha256:36e17c4592231a7dbd2ed09027823ab295d2791b3b1efb2aee874b10548b7524", + "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819", + "sha256:38949d30b11ae5f95c3c91917ee7a6b239f5ec276f271f28638dec9156f82cfc", + "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc", + "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1", + "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82", + "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81", + "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6", + "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d", + "sha256:4e71bc4416de195d6e9b4ee93ad3f2f6b2ce11d042b4d7a7ee00bbe0358bd0c2", + "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c", + "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87", + "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84", + "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e", + "sha256:5b6ccc0c85916998d788b295765ea0e9cb9aac7e4a8ed71d12e7d8ac31c23c95", + "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f", + "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b", + "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93", + "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf", + "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61", + "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c", + "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8", + "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d", + "sha256:8f5b234f567cf76ee489502ceb7165c2a5cecec081db2b37e35332b537f8157c", + "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4", + "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba", + "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415", + "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee", + "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d", + "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9", + "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075", + "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f", + "sha256:cab3db8bab4b7e635c1c97270d7a4b2a90c070b33cbc00c99ef3f9be03d3e1f7", + "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681", + "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329", + "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1", + "sha256:dc43f1ec66eb8440567186ae2f8c447d91e0372d793dfe8c222aec857b81a8cf", + "sha256:dd632777ff3beaaf629f1ab4396caf7ba0bdd075d948a69460d13d44357aca4c", + "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5", + "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b", + "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5", + "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e", + "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b", + "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad", + "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd", + "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7", + "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002", + "sha256:ff1d0899f104f3921d94579a5638847f783c9b04f2d5f229392ca77fba5b82fc" + ], + "markers": "platform_system != 'Windows'", + "version": "==1.0.7" + }, + "numpy": { + "hashes": [ + "sha256:07a8c89a04997625236c5ecb7afe35a02af3896c8aa01890a849913a2309c676", + "sha256:08d9b008d0156c70dc392bb3ab3abb6e7a711383c3247b410b39962263576cd4", + "sha256:201b4d0552831f7250a08d3b38de0d989d6f6e4658b709a02a73c524ccc6ffce", + "sha256:2c10a93606e0b4b95c9b04b77dc349b398fdfbda382d2a39ba5a822f669a0123", + "sha256:3ca688e1b9b95d80250bca34b11a05e389b1420d00e87a0d12dc45f131f704a1", + "sha256:48a3aecd3b997bf452a2dedb11f4e79bc5bfd21a1d4cc760e703c31d57c84b3e", + "sha256:568dfd16224abddafb1cbcce2ff14f522abe037268514dd7e42c6776a1c3f8e5", + "sha256:5bfb1bb598e8229c2d5d48db1860bcf4311337864ea3efdbe1171fb0c5da515d", + "sha256:639b54cdf6aa4f82fe37ebf70401bbb74b8508fddcf4797f9fe59615b8c5813a", + "sha256:8251ed96f38b47b4295b1ae51631de7ffa8260b5b087808ef09a39a9d66c97ab", + "sha256:92bfa69cfbdf7dfc3040978ad09a48091143cffb778ec3b03fa170c494118d75", + "sha256:97098b95aa4e418529099c26558eeb8486e66bd1e53a6b606d684d0c3616b168", + "sha256:a3bae1a2ed00e90b3ba5f7bd0a7c7999b55d609e0c54ceb2b076a25e345fa9f4", + "sha256:c34ea7e9d13a70bf2ab64a2532fe149a9aced424cd05a2c4ba662fd989e3e45f", + "sha256:dbc7601a3b7472d559dc7b933b18b4b66f9aa7452c120e87dfb33d02008c8a18", + "sha256:e7927a589df200c5e23c57970bafbd0cd322459aa7b1ff73b7c2e84d6e3eae62", + "sha256:f8c1f39caad2c896bc0018f699882b345b2a63708008be29b1f355ebf6f933fe", + "sha256:f950f8845b480cffe522913d35567e29dd381b0dc7e4ce6a4a9f9156417d2430", + "sha256:fade0d4f4d292b6f39951b6836d7a3c7ef5b2347f3c420cd9820a1d90d794802", + "sha256:fdf3c08bce27132395d3c3ba1503cac12e17282358cb4bddc25cc46b0aca07aa" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==1.22.3" + }, + "opentrons": { + "editable": true, + "path": "." + }, + "opentrons-hardware": { + "editable": true, + "extras": [ + "FLEX" + ], + "path": "./../hardware" + }, + "opentrons-shared-data": { + "editable": true, + "path": "../shared-data/python" + }, + "packaging": { + "hashes": [ + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + ], + "markers": "python_version >= '3.7'", + "version": "==23.2" + }, + "pydantic": { + "hashes": [ + "sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303", + "sha256:1289c180abd4bd4555bb927c42ee42abc3aee02b0fb2d1223fb7c6e5bef87dbe", + "sha256:1eb2085c13bce1612da8537b2d90f549c8cbb05c67e8f22854e201bde5d98a47", + "sha256:2031de0967c279df0d8a1c72b4ffc411ecd06bac607a212892757db7462fc494", + "sha256:2a7bac939fa326db1ab741c9d7f44c565a1d1e80908b3797f7f81a4f86bc8d33", + "sha256:2d5a58feb9a39f481eda4d5ca220aa8b9d4f21a41274760b9bc66bfd72595b86", + "sha256:2f9a6fab5f82ada41d56b0602606a5506aab165ca54e52bc4545028382ef1c5d", + "sha256:2fcfb5296d7877af406ba1547dfde9943b1256d8928732267e2653c26938cd9c", + "sha256:549a8e3d81df0a85226963611950b12d2d334f214436a19537b2efed61b7639a", + "sha256:598da88dfa127b666852bef6d0d796573a8cf5009ffd62104094a4fe39599565", + "sha256:5d1197e462e0364906cbc19681605cb7c036f2475c899b6f296104ad42b9f5fb", + "sha256:69328e15cfda2c392da4e713443c7dbffa1505bc9d566e71e55abe14c97ddc62", + "sha256:6a9dfa722316f4acf4460afdf5d41d5246a80e249c7ff475c43a3a1e9d75cf62", + "sha256:6b30bcb8cbfccfcf02acb8f1a261143fab622831d9c0989707e0e659f77a18e0", + "sha256:6c076be61cd0177a8433c0adcb03475baf4ee91edf5a4e550161ad57fc90f523", + "sha256:771735dc43cf8383959dc9b90aa281f0b6092321ca98677c5fb6125a6f56d58d", + "sha256:795e34e6cc065f8f498c89b894a3c6da294a936ee71e644e4bd44de048af1405", + "sha256:87afda5539d5140cb8ba9e8b8c8865cb5b1463924d38490d73d3ccfd80896b3f", + "sha256:8fb2aa3ab3728d950bcc885a2e9eff6c8fc40bc0b7bb434e555c215491bcf48b", + "sha256:a1fcb59f2f355ec350073af41d927bf83a63b50e640f4dbaa01053a28b7a7718", + "sha256:a5e7add47a5b5a40c49b3036d464e3c7802f8ae0d1e66035ea16aa5b7a3923ed", + "sha256:a73f489aebd0c2121ed974054cb2759af8a9f747de120acd2c3394cf84176ccb", + "sha256:ab26038b8375581dc832a63c948f261ae0aa21f1d34c1293469f135fa92972a5", + "sha256:b0d191db0f92dfcb1dec210ca244fdae5cbe918c6050b342d619c09d31eea0cc", + "sha256:b749a43aa51e32839c9d71dc67eb1e4221bb04af1033a32e3923d46f9effa942", + "sha256:b7ccf02d7eb340b216ec33e53a3a629856afe1c6e0ef91d84a4e6f2fb2ca70fe", + "sha256:ba5b2e6fe6ca2b7e013398bc7d7b170e21cce322d266ffcd57cca313e54fb246", + "sha256:ba5c4a8552bff16c61882db58544116d021d0b31ee7c66958d14cf386a5b5350", + "sha256:c79e6a11a07da7374f46970410b41d5e266f7f38f6a17a9c4823db80dadf4303", + "sha256:ca48477862372ac3770969b9d75f1bf66131d386dba79506c46d75e6b48c1e09", + "sha256:dea7adcc33d5d105896401a1f37d56b47d443a2b2605ff8a969a0ed5543f7e33", + "sha256:e0a16d274b588767602b7646fa05af2782576a6cf1022f4ba74cbb4db66f6ca8", + "sha256:e4129b528c6baa99a429f97ce733fff478ec955513630e61b49804b6cf9b224a", + "sha256:e5f805d2d5d0a41633651a73fa4ecdd0b3d7a49de4ec3fadf062fe16501ddbf1", + "sha256:ef6c96b2baa2100ec91a4b428f80d8f28a3c9e53568219b6c298c1125572ebc6", + "sha256:fdbdd1d630195689f325c9ef1a12900524dceb503b00a987663ff4f58669b93d" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==1.10.12" + }, + "pyrsistent": { + "hashes": [ + "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f", + "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e", + "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958", + "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34", + "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca", + "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d", + "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d", + "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4", + "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714", + "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf", + "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee", + "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8", + "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224", + "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d", + "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054", + "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656", + "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7", + "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423", + "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce", + "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e", + "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3", + "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0", + "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f", + "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b", + "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce", + "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a", + "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174", + "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86", + "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f", + "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b", + "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98", + "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022" + ], + "markers": "python_version >= '3.8'", + "version": "==0.20.0" + }, + "pyserial": { + "hashes": [ + "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb", + "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0" + ], + "version": "==3.5" + }, + "python-can": { + "hashes": [ + "sha256:6ad50f4613289f3c4d276b6d2ac8901d776dcb929994cce93f55a69e858c595f", + "sha256:7eea9b81b0ff908000a825db024313f622895bd578e8a17433e0474cd7d2da83" + ], + "markers": "python_version >= '3.7'", + "version": "==4.2.2" + }, + "setuptools": { + "hashes": [ + "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05", + "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78" + ], + "markers": "python_version >= '3.8'", + "version": "==69.0.3" + }, + "sniffio": { + "hashes": [ + "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", + "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.0" + }, + "typing-extensions": { + "hashes": [ + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" + ], + "markers": "python_version >= '3.8'", + "version": "==4.9.0" + }, + "wrapt": { + "hashes": [ + "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc", + "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81", + "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09", + "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e", + "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca", + "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0", + "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb", + "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487", + "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40", + "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c", + "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060", + "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202", + "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41", + "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9", + "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b", + "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664", + "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", + "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362", + "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00", + "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc", + "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1", + "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267", + "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956", + "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966", + "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1", + "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228", + "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72", + "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d", + "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292", + "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0", + "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0", + "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36", + "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c", + "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5", + "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f", + "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73", + "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b", + "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2", + "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593", + "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39", + "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389", + "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf", + "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf", + "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89", + "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c", + "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c", + "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f", + "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440", + "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465", + "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136", + "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b", + "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8", + "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3", + "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8", + "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6", + "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e", + "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f", + "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c", + "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e", + "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8", + "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2", + "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020", + "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35", + "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d", + "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3", + "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537", + "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809", + "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d", + "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a", + "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4" + ], + "markers": "python_version >= '3.6'", + "version": "==1.16.0" + } + }, + "develop": { + "alabaster": { + "hashes": [ + "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", + "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92" + ], + "markers": "python_version >= '3.9'", + "version": "==0.7.16" }, "atomicwrites": { "hashes": [ @@ -48,11 +399,11 @@ }, "attrs": { "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", + "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" ], "markers": "python_version >= '3.7'", - "version": "==23.1.0" + "version": "==23.2.0" }, "babel": { "hashes": [ @@ -263,42 +614,66 @@ "version": "==1.2.0" }, "coverage": { - "hashes": [ - "sha256:00f1d23f4336efc3b311ed0d807feb45098fc86dee1ca13b3d6768cdab187c8a", - "sha256:01333e1bd22c59713ba8a79f088b3955946e293114479bbfc2e37d522be03355", - "sha256:0cb4be7e784dcdc050fc58ef05b71aa8e89b7e6636b99967fadbdba694cf2b65", - "sha256:0e61d9803d5851849c24f78227939c701ced6704f337cad0a91e0972c51c1ee7", - "sha256:1601e480b9b99697a570cea7ef749e88123c04b92d84cedaa01e117436b4a0a9", - "sha256:2742c7515b9eb368718cd091bad1a1b44135cc72468c731302b3d641895b83d1", - "sha256:2d27a3f742c98e5c6b461ee6ef7287400a1956c11421eb574d843d9ec1f772f0", - "sha256:402e1744733df483b93abbf209283898e9f0d67470707e3c7516d84f48524f55", - "sha256:5c542d1e62eece33c306d66fe0a5c4f7f7b3c08fecc46ead86d7916684b36d6c", - "sha256:5f2294dbf7875b991c381e3d5af2bcc3494d836affa52b809c91697449d0eda6", - "sha256:6402bd2fdedabbdb63a316308142597534ea8e1895f4e7d8bf7476c5e8751fef", - "sha256:66460ab1599d3cf894bb6baee8c684788819b71a5dc1e8fa2ecc152e5d752019", - "sha256:782caea581a6e9ff75eccda79287daefd1d2631cc09d642b6ee2d6da21fc0a4e", - "sha256:79a3cfd6346ce6c13145731d39db47b7a7b859c0272f02cdb89a3bdcbae233a0", - "sha256:7a5bdad4edec57b5fb8dae7d3ee58622d626fd3a0be0dfceda162a7035885ecf", - "sha256:8fa0cbc7ecad630e5b0f4f35b0f6ad419246b02bc750de7ac66db92667996d24", - "sha256:a027ef0492ede1e03a8054e3c37b8def89a1e3c471482e9f046906ba4f2aafd2", - "sha256:a3f3654d5734a3ece152636aad89f58afc9213c6520062db3978239db122f03c", - "sha256:a82b92b04a23d3c8a581fc049228bafde988abacba397d57ce95fe95e0338ab4", - "sha256:acf3763ed01af8410fc36afea23707d4ea58ba7e86a8ee915dfb9ceff9ef69d0", - "sha256:adeb4c5b608574a3d647011af36f7586811a2c1197c861aedb548dd2453b41cd", - "sha256:b83835506dfc185a319031cf853fa4bb1b3974b1f913f5bb1a0f3d98bdcded04", - "sha256:bb28a7245de68bf29f6fb199545d072d1036a1917dca17a1e75bbb919e14ee8e", - "sha256:bf9cb9a9fd8891e7efd2d44deb24b86d647394b9705b744ff6f8261e6f29a730", - "sha256:c317eaf5ff46a34305b202e73404f55f7389ef834b8dbf4da09b9b9b37f76dd2", - "sha256:dbe8c6ae7534b5b024296464f387d57c13caa942f6d8e6e0346f27e509f0f768", - "sha256:de807ae933cfb7f0c7d9d981a053772452217df2bf38e7e6267c9cbf9545a796", - "sha256:dead2ddede4c7ba6cb3a721870f5141c97dc7d85a079edb4bd8d88c3ad5b20c7", - "sha256:dec5202bfe6f672d4511086e125db035a52b00f1648d6407cc8e526912c0353a", - "sha256:e1ea316102ea1e1770724db01998d1603ed921c54a86a2efcb03428d5417e489", - "sha256:f90bfc4ad18450c80b024036eaf91e4a246ae287701aaa88eaebebf150868052" + "extras": [ + "toml" + ], + "hashes": [ + "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61", + "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1", + "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7", + "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7", + "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75", + "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd", + "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35", + "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04", + "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6", + "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042", + "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166", + "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1", + "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d", + "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c", + "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66", + "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70", + "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1", + "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676", + "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630", + "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a", + "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74", + "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad", + "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19", + "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6", + "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448", + "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018", + "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218", + "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756", + "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54", + "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45", + "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628", + "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968", + "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d", + "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25", + "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60", + "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950", + "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06", + "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295", + "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b", + "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c", + "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc", + "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74", + "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1", + "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee", + "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011", + "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156", + "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766", + "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5", + "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581", + "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016", + "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c", + "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==5.1" + "markers": "python_version >= '3.8'", + "version": "==7.4.1" }, "cycler": { "hashes": [ @@ -310,12 +685,12 @@ }, "decoy": { "hashes": [ - "sha256:57327a6ec24c4f4804d978f9c770cb0ff778d2ed751a45ffc61226bf10fc9f90", - "sha256:dea3634ed92eca686f71e66dfd43350adc1a96c814fb5492a08d3c251c531149" + "sha256:575bdbe81afb4c152cd99a34568a9aa4369461f79d6172c678279c5d5585befe", + "sha256:7ddcc08b8ce991f7705cee76fae9061dcb17352e0a1ca2d9a0d4a0306ebd51cd" ], "index": "pypi", - "markers": "python_version >= '3.6' and python_version < '4.0'", - "version": "==1.11.3" + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==2.1.1" }, "docutils": { "hashes": [ @@ -343,86 +718,87 @@ }, "flake8": { "hashes": [ - "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", - "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" + "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132", + "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.9.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==7.0.0" }, "flake8-annotations": { "hashes": [ - "sha256:0d6cd2e770b5095f09689c9d84cc054c51b929c41a68969ea1beb4b825cac515", - "sha256:d10c4638231f8a50c0a597c4efce42bd7b7d85df4f620a0ddaca526138936a4f" + "sha256:af78e3216ad800d7e144745ece6df706c81b3255290cbf870e54879d495e8ade", + "sha256:ff37375e71e3b83f2a5a04d443c41e2c407de557a884f3300a7fa32f3c41cb0a" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1' and python_full_version < '4.0.0'", - "version": "==2.6.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==3.0.1" }, "flake8-docstrings": { "hashes": [ - "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde", - "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b" + "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af", + "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75" ], "index": "pypi", - "version": "==1.6.0" + "markers": "python_version >= '3.7'", + "version": "==1.7.0" }, "flake8-noqa": { "hashes": [ - "sha256:26d92ca6b72dec732d294e587a2bdeb66dab01acc609ed6a064693d6baa4e789", - "sha256:445618162e0bbae1b9d983326d4e39066c5c6de71ba0c444ca2d4d1fa5b2cdb7" + "sha256:4465e16a19be433980f6f563d05540e2e54797eb11facb9feb50fed60624dc45", + "sha256:771765ab27d1efd157528379acd15131147f9ae578a72d17fb432ca197881243" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.2.9" + "version": "==1.4.0" }, "fonttools": { "hashes": [ - "sha256:084511482dd265bce6dca24c509894062f0117e4e6869384d853f46c0e6d43be", - "sha256:1193fb090061efa2f9e2d8d743ae9850c77b66746a3b32792324cdce65784154", - "sha256:174995f7b057e799355b393e97f4f93ef1f2197cbfa945e988d49b2a09ecbce8", - "sha256:253bb46bab970e8aae254cebf2ae3db98a4ef6bd034707aa68a239027d2b198d", - "sha256:2a78dba8c2a1e9d53a0fb5382979f024200dc86adc46a56cbb668a2249862fda", - "sha256:2d2404107626f97a221dc1a65b05396d2bb2ce38e435f64f26ed2369f68675d9", - "sha256:40bdbe90b33897d9cc4a39f8e415b0fcdeae4c40a99374b8a4982f127ff5c767", - "sha256:495369c660e0c27233e3c572269cbe520f7f4978be675f990f4005937337d391", - "sha256:4a9a51745c0439516d947480d4d884fa18bd1458e05b829e482b9269afa655bc", - "sha256:511482df31cfea9f697930f61520f6541185fa5eeba2fa760fe72e8eee5af88b", - "sha256:52c82df66201f3a90db438d9d7b337c7c98139de598d0728fb99dab9fd0495ca", - "sha256:562681188c62c024fe2c611b32e08b8de2afa00c0c4e72bed47c47c318e16d5c", - "sha256:59a6c8b71a245800e923cb684a2dc0eac19c56493e2f896218fcf2571ed28984", - "sha256:5dde0eab40faaa5476133123f6a622a1cc3ac9b7af45d65690870620323308b4", - "sha256:61df4dee5d38ab65b26da8efd62d859a1eef7a34dcbc331299a28e24d04c59a7", - "sha256:62d8ddb058b8e87018e5dc26f3258e2c30daad4c87262dfeb0e2617dd84750e6", - "sha256:66c92ec7f95fd9732550ebedefcd190a8d81beaa97e89d523a0d17198a8bda4d", - "sha256:843509ae9b93db5aaf1a6302085e30bddc1111d31e11d724584818f5b698f500", - "sha256:854421e328d47d70aa5abceacbe8eef231961b162c71cbe7ff3f47e235e2e5c5", - "sha256:97620c4af36e4c849e52661492e31dc36916df12571cb900d16960ab8e92a980", - "sha256:9acfa1cdc479e0dde528b61423855913d949a7f7fe09e276228298fef4589540", - "sha256:a77a60315c33393b2bd29d538d1ef026060a63d3a49a9233b779261bad9c3f71", - "sha256:b4fabb8cc9422efae1a925160083fdcbab8fdc96a8483441eb7457235df625bd", - "sha256:bf1810635c00f7c45d93085611c995fc130009cec5abdc35b327156aa191f982", - "sha256:c01f409be619a9a0f5590389e37ccb58b47264939f0e8d58bfa1f3ba07d22671", - "sha256:c59227d7ba5b232281c26ae04fac2c73a79ad0e236bca5c44aae904a18f14faf", - "sha256:c75e19971209fbbce891ebfd1b10c37320a5a28e8d438861c21d35305aedb81c", - "sha256:ce0e2c88c8c985b7b9a7efcd06511fb0a1fe3ddd9a6cd2895ef1dbf9059719d7", - "sha256:d6477ba902dd2d7adda7f0fd3bfaeb92885d45993c9e1928c9f28fc3961415f7", - "sha256:d986b66ff722ef675b7ee22fbe5947a41f60a61a4da15579d5e276d897fbc7fa", - "sha256:dd23848f877c3754f53a4903fb7a593ed100924f9b4bff7d5a4e2e8a7001ae11", - "sha256:e3f4d61f3a8195eac784f1d0c16c0a3105382c1b9a74d99ac4ba421da39a8826", - "sha256:e6b968543fde4119231c12c2a953dcf83349590ca631ba8216a8edf9cd4d36a9", - "sha256:e77bdf52185bdaf63d39f3e1ac3212e6cfa3ab07d509b94557a8902ce9c13c82", - "sha256:e79f1a3970d25f692bbb8c8c2637e621a66c0d60c109ab48d4a160f50856deff", - "sha256:e7a0a8848726956e9d9fb18c977a279013daadf0cbb6725d2015a6dd57527992", - "sha256:e869da810ae35afb3019baa0d0306cdbab4760a54909c89ad8904fa629991812", - "sha256:e8acf6dd0434b211b3bd30d572d9e019831aae17a54016629fa8224783b22df8", - "sha256:e8fa20748de55d0021f83754b371432dca0439e02847962fc4c42a0e444c2d78", - "sha256:ea592e6a09b71cb7a7661dd93ac0b877a6228e2d677ebacbad0a4d118494c86d", - "sha256:ec13a10715eef0e031858c1c23bfaee6cba02b97558e4a7bfa089dba4a8c2ebf", - "sha256:f4da089f6dfdb822293bde576916492cd708c37c2501c3651adde39804630538" + "sha256:0255dbc128fee75fb9be364806b940ed450dd6838672a150d501ee86523ac61e", + "sha256:0a00bd0e68e88987dcc047ea31c26d40a3c61185153b03457956a87e39d43c37", + "sha256:0a1d313a415eaaba2b35d6cd33536560deeebd2ed758b9bfb89ab5d97dc5deac", + "sha256:0f750037e02beb8b3569fbff701a572e62a685d2a0e840d75816592280e5feae", + "sha256:13819db8445a0cec8c3ff5f243af6418ab19175072a9a92f6cc8ca7d1452754b", + "sha256:254d9a6f7be00212bf0c3159e0a420eb19c63793b2c05e049eb337f3023c5ecc", + "sha256:29495d6d109cdbabe73cfb6f419ce67080c3ef9ea1e08d5750240fd4b0c4763b", + "sha256:32ab2e9702dff0dd4510c7bb958f265a8d3dd5c0e2547e7b5f7a3df4979abb07", + "sha256:3480eeb52770ff75140fe7d9a2ec33fb67b07efea0ab5129c7e0c6a639c40c70", + "sha256:3a808f3c1d1df1f5bf39be869b6e0c263570cdafb5bdb2df66087733f566ea71", + "sha256:3b629108351d25512d4ea1a8393a2dba325b7b7d7308116b605ea3f8e1be88df", + "sha256:3d71606c9321f6701642bd4746f99b6089e53d7e9817fc6b964e90d9c5f0ecc6", + "sha256:3e2b95dce2ead58fb12524d0ca7d63a63459dd489e7e5838c3cd53557f8933e1", + "sha256:4a5a5318ba5365d992666ac4fe35365f93004109d18858a3e18ae46f67907670", + "sha256:4c811d3c73b6abac275babb8aa439206288f56fdb2c6f8835e3d7b70de8937a7", + "sha256:4e743935139aa485fe3253fc33fe467eab6ea42583fa681223ea3f1a93dd01e6", + "sha256:4ec558c543609e71b2275c4894e93493f65d2f41c15fe1d089080c1d0bb4d635", + "sha256:5465df494f20a7d01712b072ae3ee9ad2887004701b95cb2cc6dcb9c2c97a899", + "sha256:5b60e3afa9635e3dfd3ace2757039593e3bd3cf128be0ddb7a1ff4ac45fa5a50", + "sha256:63fbed184979f09a65aa9c88b395ca539c94287ba3a364517698462e13e457c9", + "sha256:69731e8bea0578b3c28fdb43dbf95b9386e2d49a399e9a4ad736b8e479b08085", + "sha256:6dd58cc03016b281bd2c74c84cdaa6bd3ce54c5a7f47478b7657b930ac3ed8eb", + "sha256:740947906590a878a4bde7dd748e85fefa4d470a268b964748403b3ab2aeed6c", + "sha256:7df26dd3650e98ca45f1e29883c96a0b9f5bb6af8d632a6a108bc744fa0bd9b3", + "sha256:7eb7ad665258fba68fd22228a09f347469d95a97fb88198e133595947a20a184", + "sha256:7ee48bd9d6b7e8f66866c9090807e3a4a56cf43ffad48962725a190e0dd774c8", + "sha256:86e0427864c6c91cf77f16d1fb9bf1bbf7453e824589e8fb8461b6ee1144f506", + "sha256:8f57ecd742545362a0f7186774b2d1c53423ed9ece67689c93a1055b236f638c", + "sha256:90f898cdd67f52f18049250a6474185ef6544c91f27a7bee70d87d77a8daf89c", + "sha256:94208ea750e3f96e267f394d5588579bb64cc628e321dbb1d4243ffbc291b18b", + "sha256:a1c154bb85dc9a4cf145250c88d112d88eb414bad81d4cb524d06258dea1bdc0", + "sha256:a5d77479fb885ef38a16a253a2f4096bc3d14e63a56d6246bfdb56365a12b20c", + "sha256:a86a5ab2873ed2575d0fcdf1828143cfc6b977ac448e3dc616bb1e3d20efbafa", + "sha256:ac71e2e201df041a2891067dc36256755b1229ae167edbdc419b16da78732c2f", + "sha256:b3e1304e5f19ca861d86a72218ecce68f391646d85c851742d265787f55457a4", + "sha256:b8be28c036b9f186e8c7eaf8a11b42373e7e4949f9e9f370202b9da4c4c3f56c", + "sha256:c19044256c44fe299d9a73456aabee4b4d06c6b930287be93b533b4737d70aa1", + "sha256:d49ce3ea7b7173faebc5664872243b40cf88814ca3eb135c4a3cdff66af71946", + "sha256:e040f905d542362e07e72e03612a6270c33d38281fd573160e1003e43718d68d", + "sha256:eabae77a07c41ae0b35184894202305c3ad211a93b2eb53837c2a1143c8bc952", + "sha256:f791446ff297fd5f1e2247c188de53c1bfb9dd7f0549eba55b73a3c2087a2703", + "sha256:f83a4daef6d2a202acb9bf572958f91cfde5b10c8ee7fb1d09a4c81e5d851fd8" ], "markers": "python_version >= '3.8'", - "version": "==4.47.0" + "version": "==4.47.2" }, "gprof2dot": { "hashes": [ @@ -434,12 +810,12 @@ }, "hypothesis": { "hashes": [ - "sha256:3cba76a7389bd7245c350fcf7234663314dc81a5be0bbef72a07d8c249bfc210", - "sha256:fa755ded526e50b7e2f642cdc5d64519f88d4e4ee71d9d29ec3eb2f2fddf1274" + "sha256:848ea0952f0bdfd02eac59e41b03f1cbba8fa2cffeffa8db328bbd6cfe159974", + "sha256:955a57e56be4607c81c17ca53e594af54aadeed91e07b88bb7f84e8208ea7739" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==6.92.1" + "version": "==6.96.1" }, "idna": { "hashes": [ @@ -459,11 +835,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:7fc841f8b8332803464e5dc1c63a2e59121f46ca186c0e2e182e80bf8c1319f7", - "sha256:d97503976bb81f40a193d41ee6570868479c69d5068651eb039c40d850c59d67" + "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e", + "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc" ], "markers": "python_version >= '3.8'", - "version": "==7.0.0" + "version": "==7.0.1" }, "iniconfig": { "hashes": [ @@ -490,13 +866,6 @@ "markers": "python_version >= '3.6'", "version": "==3.0.3" }, - "jsonschema": { - "hashes": [ - "sha256:5f9c0a719ca2ce14c5de2fd350a64fd2d13e8539db29836a86adc990bb1a068f", - "sha256:8d4a2b7b6c2237e0199c8ea1a6d3e05bf118e289ae2b9d7ba444182a2959560d" - ], - "version": "==3.0.2" - }, "keyring": { "hashes": [ "sha256:4446d35d636e6a10b8bce7caa66913dd9eca5fd222ca03a3d42c38608ac30836", @@ -625,69 +994,69 @@ }, "markupsafe": { "hashes": [ - "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", - "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", - "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", - "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", - "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c", - "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", - "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", - "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb", - "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939", - "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", - "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", - "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", - "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", - "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", - "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", - "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", - "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd", - "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", - "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", - "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", - "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", - "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", - "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", - "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", - "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", - "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007", - "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", - "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", - "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", - "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0", - "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", - "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", - "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", - "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1", - "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", - "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", - "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c", - "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", - "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823", - "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", - "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", - "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", - "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", - "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", - "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc", - "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", - "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48", - "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", - "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e", - "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b", - "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", - "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5", - "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e", - "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", - "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", - "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", - "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", - "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc", - "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2", - "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11" + "sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69", + "sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0", + "sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d", + "sha256:15866d7f2dc60cfdde12ebb4e75e41be862348b4728300c36cdf405e258415ec", + "sha256:1c98c33ffe20e9a489145d97070a435ea0679fddaabcafe19982fe9c971987d5", + "sha256:21e7af8091007bf4bebf4521184f4880a6acab8df0df52ef9e513d8e5db23411", + "sha256:23984d1bdae01bee794267424af55eef4dfc038dc5d1272860669b2aa025c9e3", + "sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74", + "sha256:3583a3a3ab7958e354dc1d25be74aee6228938312ee875a22330c4dc2e41beb0", + "sha256:36d7626a8cca4d34216875aee5a1d3d654bb3dac201c1c003d182283e3205949", + "sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d", + "sha256:3a66c36a3864df95e4f62f9167c734b3b1192cb0851b43d7cc08040c074c6279", + "sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f", + "sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6", + "sha256:47bb5f0142b8b64ed1399b6b60f700a580335c8e1c57f2f15587bd072012decc", + "sha256:49a3b78a5af63ec10d8604180380c13dcd870aba7928c1fe04e881d5c792dc4e", + "sha256:4df98d4a9cd6a88d6a585852f56f2155c9cdb6aec78361a19f938810aa020954", + "sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656", + "sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc", + "sha256:54635102ba3cf5da26eb6f96c4b8c53af8a9c0d97b64bdcb592596a6255d8518", + "sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56", + "sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc", + "sha256:698e84142f3f884114ea8cf83e7a67ca8f4ace8454e78fe960646c6c91c63bfa", + "sha256:6aa5e2e7fc9bc042ae82d8b79d795b9a62bd8f15ba1e7594e3db243f158b5565", + "sha256:7653fa39578957bc42e5ebc15cf4361d9e0ee4b702d7d5ec96cdac860953c5b4", + "sha256:765f036a3d00395a326df2835d8f86b637dbaf9832f90f5d196c3b8a7a5080cb", + "sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250", + "sha256:7a07f40ef8f0fbc5ef1000d0c78771f4d5ca03b4953fc162749772916b298fc4", + "sha256:8b570a1537367b52396e53325769608f2a687ec9a4363647af1cded8928af959", + "sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc", + "sha256:9896fca4a8eb246defc8b2a7ac77ef7553b638e04fbf170bff78a40fa8a91474", + "sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863", + "sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8", + "sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f", + "sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2", + "sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e", + "sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e", + "sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb", + "sha256:b0fe73bac2fed83839dbdbe6da84ae2a31c11cfc1c777a40dbd8ac8a6ed1560f", + "sha256:b6f14a9cd50c3cb100eb94b3273131c80d102e19bb20253ac7bd7336118a673a", + "sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26", + "sha256:b835aba863195269ea358cecc21b400276747cc977492319fd7682b8cd2c253d", + "sha256:bf1196dcc239e608605b716e7b166eb5faf4bc192f8a44b81e85251e62584bd2", + "sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131", + "sha256:c7556bafeaa0a50e2fe7dc86e0382dea349ebcad8f010d5a7dc6ba568eaaa789", + "sha256:c8f253a84dbd2c63c19590fa86a032ef3d8cc18923b8049d91bcdeeb2581fbf6", + "sha256:d18b66fe626ac412d96c2ab536306c736c66cf2a31c243a45025156cc190dc8a", + "sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858", + "sha256:d5c31fe855c77cad679b302aabc42d724ed87c043b1432d457f4976add1c2c3e", + "sha256:d6e427c7378c7f1b2bef6a344c925b8b63623d3321c09a237b7cc0e77dd98ceb", + "sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e", + "sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84", + "sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7", + "sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea", + "sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b", + "sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6", + "sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475", + "sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74", + "sha256:fc1a75aa8f11b87910ffd98de62b29d6520b6d6e8a3de69a70ca34dea85d2a8a", + "sha256:fe8512ed897d5daf089e5bd010c3dc03bb1bdae00b35588c49b98268d4a01e00" ], "markers": "python_version >= '3.7'", - "version": "==2.1.3" + "version": "==2.1.4" }, "matplotlib": { "hashes": [ @@ -725,10 +1094,11 @@ }, "mccabe": { "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "version": "==0.6.1" + "markers": "python_version >= '3.6'", + "version": "==0.7.0" }, "mdurl": { "hashes": [ @@ -740,113 +1110,54 @@ }, "mock": { "hashes": [ - "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62", - "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc" + "sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744", + "sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d" ], "index": "pypi", "markers": "python_version >= '3.6'", - "version": "==4.0.3" + "version": "==5.1.0" }, "more-itertools": { "hashes": [ - "sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a", - "sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6" + "sha256:686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "sha256:8fccb480c43d3e99a00087634c06dd02b0d50fbf088b380de5a41a015ec239e1" ], "markers": "python_version >= '3.8'", - "version": "==10.1.0" - }, - "msgpack": { - "hashes": [ - "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862", - "sha256:0bfdd914e55e0d2c9e1526de210f6fe8ffe9705f2b1dfcc4aecc92a4cb4b533d", - "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3", - "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672", - "sha256:235a31ec7db685f5c82233bddf9858748b89b8119bf4538d514536c485c15fe0", - "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9", - "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee", - "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46", - "sha256:36e17c4592231a7dbd2ed09027823ab295d2791b3b1efb2aee874b10548b7524", - "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819", - "sha256:38949d30b11ae5f95c3c91917ee7a6b239f5ec276f271f28638dec9156f82cfc", - "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc", - "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1", - "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82", - "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81", - "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6", - "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d", - "sha256:4e71bc4416de195d6e9b4ee93ad3f2f6b2ce11d042b4d7a7ee00bbe0358bd0c2", - "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c", - "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87", - "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84", - "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e", - "sha256:5b6ccc0c85916998d788b295765ea0e9cb9aac7e4a8ed71d12e7d8ac31c23c95", - "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f", - "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b", - "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93", - "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf", - "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61", - "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c", - "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8", - "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d", - "sha256:8f5b234f567cf76ee489502ceb7165c2a5cecec081db2b37e35332b537f8157c", - "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4", - "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba", - "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415", - "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee", - "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d", - "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9", - "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075", - "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f", - "sha256:cab3db8bab4b7e635c1c97270d7a4b2a90c070b33cbc00c99ef3f9be03d3e1f7", - "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681", - "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329", - "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1", - "sha256:dc43f1ec66eb8440567186ae2f8c447d91e0372d793dfe8c222aec857b81a8cf", - "sha256:dd632777ff3beaaf629f1ab4396caf7ba0bdd075d948a69460d13d44357aca4c", - "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5", - "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b", - "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5", - "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e", - "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b", - "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad", - "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd", - "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7", - "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002", - "sha256:ff1d0899f104f3921d94579a5638847f783c9b04f2d5f229392ca77fba5b82fc" - ], - "markers": "platform_system != 'Windows'", - "version": "==1.0.7" + "version": "==10.2.0" }, "mypy": { "hashes": [ - "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", - "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", - "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", - "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", - "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", - "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", - "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", - "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", - "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", - "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", - "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", - "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", - "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", - "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", - "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", - "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", - "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", - "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", - "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", - "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", - "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", - "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", - "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", - "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" + "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6", + "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d", + "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02", + "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d", + "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3", + "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3", + "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3", + "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66", + "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259", + "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835", + "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd", + "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d", + "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8", + "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07", + "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b", + "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e", + "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6", + "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae", + "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9", + "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d", + "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a", + "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592", + "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218", + "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817", + "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4", + "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410", + "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.981" + "markers": "python_version >= '3.8'", + "version": "==1.8.0" }, "mypy-extensions": { "hashes": [ @@ -879,45 +1190,30 @@ }, "numpy": { "hashes": [ - "sha256:06fa1ed84aa60ea6ef9f91ba57b5ed963c3729534e6e54055fc151fad0423f0a", - "sha256:174a8880739c16c925799c018f3f55b8130c1f7c8e75ab0a6fa9d41cab092fd6", - "sha256:1a13860fdcd95de7cf58bd6f8bc5a5ef81c0b0625eb2c9a783948847abbef2c2", - "sha256:1cc3d5029a30fb5f06704ad6b23b35e11309491c999838c31f124fee32107c79", - "sha256:22f8fc02fdbc829e7a8c578dd8d2e15a9074b630d4da29cda483337e300e3ee9", - "sha256:26c9d33f8e8b846d5a65dd068c14e04018d05533b348d9eaeef6c1bd787f9919", - "sha256:2b3fca8a5b00184828d12b073af4d0fc5fdd94b1632c2477526f6bd7842d700d", - "sha256:2beef57fb031dcc0dc8fa4fe297a742027b954949cabb52a2a376c144e5e6060", - "sha256:36340109af8da8805d8851ef1d74761b3b88e81a9bd80b290bbfed61bd2b4f75", - "sha256:3703fc9258a4a122d17043e57b35e5ef1c5a5837c3db8be396c82e04c1cf9b0f", - "sha256:3ced40d4e9e18242f70dd02d739e44698df3dcb010d31f495ff00a31ef6014fe", - "sha256:4a06263321dfd3598cacb252f51e521a8cb4b6df471bb12a7ee5cbab20ea9167", - "sha256:4eb8df4bf8d3d90d091e0146f6c28492b0be84da3e409ebef54349f71ed271ef", - "sha256:5d5244aabd6ed7f312268b9247be47343a654ebea52a60f002dc70c769048e75", - "sha256:64308ebc366a8ed63fd0bf426b6a9468060962f1a4339ab1074c228fa6ade8e3", - "sha256:6a3cdb4d9c70e6b8c0814239ead47da00934666f668426fc6e94cce869e13fd7", - "sha256:854ab91a2906ef29dc3925a064fcd365c7b4da743f84b123002f6139bcb3f8a7", - "sha256:94cc3c222bb9fb5a12e334d0479b97bb2df446fbe622b470928f5284ffca3f8d", - "sha256:96ca5482c3dbdd051bcd1fce8034603d6ebfc125a7bd59f55b40d8f5d246832b", - "sha256:a2bbc29fcb1771cd7b7425f98b05307776a6baf43035d3b80c4b0f29e9545186", - "sha256:a4cd6ed4a339c21f1d1b0fdf13426cb3b284555c27ac2f156dfdaaa7e16bfab0", - "sha256:aa18428111fb9a591d7a9cc1b48150097ba6a7e8299fb56bdf574df650e7d1f1", - "sha256:aa317b2325f7aa0a9471663e6093c210cb2ae9c0ad824732b307d2c51983d5b6", - "sha256:b04f5dc6b3efdaab541f7857351aac359e6ae3c126e2edb376929bd3b7f92d7e", - "sha256:b272d4cecc32c9e19911891446b72e986157e6a1809b7b56518b4f3755267523", - "sha256:b361d369fc7e5e1714cf827b731ca32bff8d411212fccd29ad98ad622449cc36", - "sha256:b96e7b9c624ef3ae2ae0e04fa9b460f6b9f17ad8b4bec6d7756510f1f6c0c841", - "sha256:baf8aab04a2c0e859da118f0b38617e5ee65d75b83795055fb66c0d5e9e9b818", - "sha256:bcc008217145b3d77abd3e4d5ef586e3bdfba8fe17940769f8aa09b99e856c00", - "sha256:bd3f0091e845164a20bd5a326860c840fe2af79fa12e0469a12768a3ec578d80", - "sha256:cc392fdcbd21d4be6ae1bb4475a03ce3b025cd49a9be5345d76d7585aea69440", - "sha256:d73a3abcac238250091b11caef9ad12413dab01669511779bc9b29261dd50210", - "sha256:f43740ab089277d403aa07567be138fc2a89d4d9892d113b76153e0e412409f8", - "sha256:f65738447676ab5777f11e6bbbdb8ce11b785e105f690bc45966574816b6d3ea", - "sha256:f79b231bf5c16b1f39c7f4875e1ded36abee1591e98742b05d8a0fb55d8a3eec", - "sha256:fe6b44fb8fcdf7eda4ef4461b97b3f63c466b27ab151bec2366db8b197387841" + "sha256:07a8c89a04997625236c5ecb7afe35a02af3896c8aa01890a849913a2309c676", + "sha256:08d9b008d0156c70dc392bb3ab3abb6e7a711383c3247b410b39962263576cd4", + "sha256:201b4d0552831f7250a08d3b38de0d989d6f6e4658b709a02a73c524ccc6ffce", + "sha256:2c10a93606e0b4b95c9b04b77dc349b398fdfbda382d2a39ba5a822f669a0123", + "sha256:3ca688e1b9b95d80250bca34b11a05e389b1420d00e87a0d12dc45f131f704a1", + "sha256:48a3aecd3b997bf452a2dedb11f4e79bc5bfd21a1d4cc760e703c31d57c84b3e", + "sha256:568dfd16224abddafb1cbcce2ff14f522abe037268514dd7e42c6776a1c3f8e5", + "sha256:5bfb1bb598e8229c2d5d48db1860bcf4311337864ea3efdbe1171fb0c5da515d", + "sha256:639b54cdf6aa4f82fe37ebf70401bbb74b8508fddcf4797f9fe59615b8c5813a", + "sha256:8251ed96f38b47b4295b1ae51631de7ffa8260b5b087808ef09a39a9d66c97ab", + "sha256:92bfa69cfbdf7dfc3040978ad09a48091143cffb778ec3b03fa170c494118d75", + "sha256:97098b95aa4e418529099c26558eeb8486e66bd1e53a6b606d684d0c3616b168", + "sha256:a3bae1a2ed00e90b3ba5f7bd0a7c7999b55d609e0c54ceb2b076a25e345fa9f4", + "sha256:c34ea7e9d13a70bf2ab64a2532fe149a9aced424cd05a2c4ba662fd989e3e45f", + "sha256:dbc7601a3b7472d559dc7b933b18b4b66f9aa7452c120e87dfb33d02008c8a18", + "sha256:e7927a589df200c5e23c57970bafbd0cd322459aa7b1ff73b7c2e84d6e3eae62", + "sha256:f8c1f39caad2c896bc0018f699882b345b2a63708008be29b1f355ebf6f933fe", + "sha256:f950f8845b480cffe522913d35567e29dd381b0dc7e4ce6a4a9f9156417d2430", + "sha256:fade0d4f4d292b6f39951b6836d7a3c7ef5b2347f3c420cd9820a1d90d794802", + "sha256:fdf3c08bce27132395d3c3ba1503cac12e17282358cb4bddc25cc46b0aca07aa" ], - "markers": "python_version >= '3.9'", - "version": "==1.26.2" + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==1.22.3" }, "numpydoc": { "hashes": [ @@ -926,23 +1222,6 @@ "index": "pypi", "version": "==0.9.1" }, - "opentrons": { - "editable": true, - "markers": "python_version >= '3.7'", - "path": "." - }, - "opentrons-hardware": { - "editable": true, - "extras": [ - "FLEX" - ], - "path": "./../hardware" - }, - "opentrons-shared-data": { - "editable": true, - "markers": "python_version >= '3.7'", - "path": "../shared-data/python" - }, "packaging": { "hashes": [ "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", @@ -961,63 +1240,77 @@ }, "pillow": { "hashes": [ - "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d", - "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de", - "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616", - "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839", - "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099", - "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a", - "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219", - "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106", - "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b", - "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412", - "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b", - "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7", - "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2", - "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7", - "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14", - "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f", - "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27", - "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57", - "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262", - "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28", - "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610", - "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172", - "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273", - "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e", - "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d", - "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818", - "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f", - "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9", - "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01", - "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7", - "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651", - "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312", - "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80", - "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666", - "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061", - "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b", - "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992", - "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593", - "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4", - "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db", - "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba", - "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd", - "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e", - "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212", - "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb", - "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2", - "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34", - "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256", - "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f", - "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2", - "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38", - "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996", - "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a", - "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793" + "sha256:0304004f8067386b477d20a518b50f3fa658a28d44e4116970abfcd94fac34a8", + "sha256:0689b5a8c5288bc0504d9fcee48f61a6a586b9b98514d7d29b840143d6734f39", + "sha256:0eae2073305f451d8ecacb5474997c08569fb4eb4ac231ffa4ad7d342fdc25ac", + "sha256:0fb3e7fc88a14eacd303e90481ad983fd5b69c761e9e6ef94c983f91025da869", + "sha256:11fa2e5984b949b0dd6d7a94d967743d87c577ff0b83392f17cb3990d0d2fd6e", + "sha256:127cee571038f252a552760076407f9cff79761c3d436a12af6000cd182a9d04", + "sha256:154e939c5f0053a383de4fd3d3da48d9427a7e985f58af8e94d0b3c9fcfcf4f9", + "sha256:15587643b9e5eb26c48e49a7b33659790d28f190fc514a322d55da2fb5c2950e", + "sha256:170aeb00224ab3dc54230c797f8404507240dd868cf52066f66a41b33169bdbe", + "sha256:1b5e1b74d1bd1b78bc3477528919414874748dd363e6272efd5abf7654e68bef", + "sha256:1da3b2703afd040cf65ec97efea81cfba59cdbed9c11d8efc5ab09df9509fc56", + "sha256:1e23412b5c41e58cec602f1135c57dfcf15482013ce6e5f093a86db69646a5aa", + "sha256:2247178effb34a77c11c0e8ac355c7a741ceca0a732b27bf11e747bbc950722f", + "sha256:257d8788df5ca62c980314053197f4d46eefedf4e6175bc9412f14412ec4ea2f", + "sha256:3031709084b6e7852d00479fd1d310b07d0ba82765f973b543c8af5061cf990e", + "sha256:322209c642aabdd6207517e9739c704dc9f9db943015535783239022002f054a", + "sha256:322bdf3c9b556e9ffb18f93462e5f749d3444ce081290352c6070d014c93feb2", + "sha256:33870dc4653c5017bf4c8873e5488d8f8d5f8935e2f1fb9a2208c47cdd66efd2", + "sha256:35bb52c37f256f662abdfa49d2dfa6ce5d93281d323a9af377a120e89a9eafb5", + "sha256:3c31822339516fb3c82d03f30e22b1d038da87ef27b6a78c9549888f8ceda39a", + "sha256:3eedd52442c0a5ff4f887fab0c1c0bb164d8635b32c894bc1faf4c618dd89df2", + "sha256:3ff074fc97dd4e80543a3e91f69d58889baf2002b6be64347ea8cf5533188213", + "sha256:47c0995fc4e7f79b5cfcab1fc437ff2890b770440f7696a3ba065ee0fd496563", + "sha256:49d9ba1ed0ef3e061088cd1e7538a0759aab559e2e0a80a36f9fd9d8c0c21591", + "sha256:51f1a1bffc50e2e9492e87d8e09a17c5eea8409cda8d3f277eb6edc82813c17c", + "sha256:52a50aa3fb3acb9cf7213573ef55d31d6eca37f5709c69e6858fe3bc04a5c2a2", + "sha256:54f1852cd531aa981bc0965b7d609f5f6cc8ce8c41b1139f6ed6b3c54ab82bfb", + "sha256:609448742444d9290fd687940ac0b57fb35e6fd92bdb65386e08e99af60bf757", + "sha256:69ffdd6120a4737710a9eee73e1d2e37db89b620f702754b8f6e62594471dee0", + "sha256:6fad5ff2f13d69b7e74ce5b4ecd12cc0ec530fcee76356cac6742785ff71c452", + "sha256:7049e301399273a0136ff39b84c3678e314f2158f50f517bc50285fb5ec847ad", + "sha256:70c61d4c475835a19b3a5aa42492409878bbca7438554a1f89d20d58a7c75c01", + "sha256:716d30ed977be8b37d3ef185fecb9e5a1d62d110dfbdcd1e2a122ab46fddb03f", + "sha256:753cd8f2086b2b80180d9b3010dd4ed147efc167c90d3bf593fe2af21265e5a5", + "sha256:773efe0603db30c281521a7c0214cad7836c03b8ccff897beae9b47c0b657d61", + "sha256:7823bdd049099efa16e4246bdf15e5a13dbb18a51b68fa06d6c1d4d8b99a796e", + "sha256:7c8f97e8e7a9009bcacbe3766a36175056c12f9a44e6e6f2d5caad06dcfbf03b", + "sha256:823ef7a27cf86df6597fa0671066c1b596f69eba53efa3d1e1cb8b30f3533068", + "sha256:8373c6c251f7ef8bda6675dd6d2b3a0fcc31edf1201266b5cf608b62a37407f9", + "sha256:83b2021f2ade7d1ed556bc50a399127d7fb245e725aa0113ebd05cfe88aaf588", + "sha256:870ea1ada0899fd0b79643990809323b389d4d1d46c192f97342eeb6ee0b8483", + "sha256:8d12251f02d69d8310b046e82572ed486685c38f02176bd08baf216746eb947f", + "sha256:9c23f307202661071d94b5e384e1e1dc7dfb972a28a2310e4ee16103e66ddb67", + "sha256:9d189550615b4948f45252d7f005e53c2040cea1af5b60d6f79491a6e147eef7", + "sha256:a086c2af425c5f62a65e12fbf385f7c9fcb8f107d0849dba5839461a129cf311", + "sha256:a2b56ba36e05f973d450582fb015594aaa78834fefe8dfb8fcd79b93e64ba4c6", + "sha256:aebb6044806f2e16ecc07b2a2637ee1ef67a11840a66752751714a0d924adf72", + "sha256:b1b3020d90c2d8e1dae29cf3ce54f8094f7938460fb5ce8bc5c01450b01fbaf6", + "sha256:b4b6b1e20608493548b1f32bce8cca185bf0480983890403d3b8753e44077129", + "sha256:b6f491cdf80ae540738859d9766783e3b3c8e5bd37f5dfa0b76abdecc5081f13", + "sha256:b792a349405fbc0163190fde0dc7b3fef3c9268292586cf5645598b48e63dc67", + "sha256:b7c2286c23cd350b80d2fc9d424fc797575fb16f854b831d16fd47ceec078f2c", + "sha256:babf5acfede515f176833ed6028754cbcd0d206f7f614ea3447d67c33be12516", + "sha256:c365fd1703040de1ec284b176d6af5abe21b427cb3a5ff68e0759e1e313a5e7e", + "sha256:c4225f5220f46b2fde568c74fca27ae9771536c2e29d7c04f4fb62c83275ac4e", + "sha256:c570f24be1e468e3f0ce7ef56a89a60f0e05b30a3669a459e419c6eac2c35364", + "sha256:c6dafac9e0f2b3c78df97e79af707cdc5ef8e88208d686a4847bab8266870023", + "sha256:c8de2789052ed501dd829e9cae8d3dcce7acb4777ea4a479c14521c942d395b1", + "sha256:cb28c753fd5eb3dd859b4ee95de66cc62af91bcff5db5f2571d32a520baf1f04", + "sha256:cb4c38abeef13c61d6916f264d4845fab99d7b711be96c326b84df9e3e0ff62d", + "sha256:d1b35bcd6c5543b9cb547dee3150c93008f8dd0f1fef78fc0cd2b141c5baf58a", + "sha256:d8e6aeb9201e655354b3ad049cb77d19813ad4ece0df1249d3c793de3774f8c7", + "sha256:d8ecd059fdaf60c1963c58ceb8997b32e9dc1b911f5da5307aab614f1ce5c2fb", + "sha256:da2b52b37dad6d9ec64e653637a096905b258d2fc2b984c41ae7d08b938a67e4", + "sha256:e87f0b2c78157e12d7686b27d63c070fd65d994e8ddae6f328e0dcf4a0cd007e", + "sha256:edca80cbfb2b68d7b56930b84a0e45ae1694aeba0541f798e908a49d66b837f1", + "sha256:f379abd2f1e3dddb2b61bc67977a6b5a0a3f7485538bcc6f39ec76163891ee48", + "sha256:fe4c15f6c9285dc54ce6553a3ce908ed37c8f3825b5a51a15c91442bb955b868" ], "markers": "python_version >= '3.8'", - "version": "==10.1.0" + "version": "==10.2.0" }, "pkginfo": { "hashes": [ @@ -1029,19 +1322,19 @@ }, "platformdirs": { "hashes": [ - "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", - "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", + "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "pluggy": { "hashes": [ - "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", - "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981", + "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be" ], "markers": "python_version >= '3.8'", - "version": "==1.3.0" + "version": "==1.4.0" }, "py": { "hashes": [ @@ -1053,52 +1346,11 @@ }, "pycodestyle": { "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" + "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.7.0" - }, - "pydantic": { - "hashes": [ - "sha256:1061c6ee6204f4f5a27133126854948e3b3d51fcc16ead2e5d04378c199b2f44", - "sha256:19b5686387ea0d1ea52ecc4cffb71abb21702c5e5b2ac626fd4dbaa0834aa49d", - "sha256:2bd446bdb7755c3a94e56d7bdfd3ee92396070efa8ef3a34fab9579fe6aa1d84", - "sha256:328558c9f2eed77bd8fffad3cef39dbbe3edc7044517f4625a769d45d4cf7555", - "sha256:32e0b4fb13ad4db4058a7c3c80e2569adbd810c25e6ca3bbd8b2a9cc2cc871d7", - "sha256:3ee0d69b2a5b341fc7927e92cae7ddcfd95e624dfc4870b32a85568bd65e6131", - "sha256:4aafd4e55e8ad5bd1b19572ea2df546ccace7945853832bb99422a79c70ce9b8", - "sha256:4b3946f87e5cef3ba2e7bd3a4eb5a20385fe36521d6cc1ebf3c08a6697c6cfb3", - "sha256:4de71c718c9756d679420c69f216776c2e977459f77e8f679a4a961dc7304a56", - "sha256:5565a49effe38d51882cb7bac18bda013cdb34d80ac336428e8908f0b72499b0", - "sha256:5803ad846cdd1ed0d97eb00292b870c29c1f03732a010e66908ff48a762f20e4", - "sha256:5da164119602212a3fe7e3bc08911a89db4710ae51444b4224c2382fd09ad453", - "sha256:615661bfc37e82ac677543704437ff737418e4ea04bef9cf11c6d27346606044", - "sha256:78a4d6bdfd116a559aeec9a4cfe77dda62acc6233f8b56a716edad2651023e5e", - "sha256:7d0f183b305629765910eaad707800d2f47c6ac5bcfb8c6397abdc30b69eeb15", - "sha256:7ead3cd020d526f75b4188e0a8d71c0dbbe1b4b6b5dc0ea775a93aca16256aeb", - "sha256:84d76ecc908d917f4684b354a39fd885d69dd0491be175f3465fe4b59811c001", - "sha256:8cb0bc509bfb71305d7a59d00163d5f9fc4530f0881ea32c74ff4f74c85f3d3d", - "sha256:91089b2e281713f3893cd01d8e576771cd5bfdfbff5d0ed95969f47ef6d676c3", - "sha256:9c9e04a6cdb7a363d7cb3ccf0efea51e0abb48e180c0d31dca8d247967d85c6e", - "sha256:a8c5360a0297a713b4123608a7909e6869e1b56d0e96eb0d792c27585d40757f", - "sha256:afacf6d2a41ed91fc631bade88b1d319c51ab5418870802cedb590b709c5ae3c", - "sha256:b34ba24f3e2d0b39b43f0ca62008f7ba962cff51efa56e64ee25c4af6eed987b", - "sha256:bd67cb2c2d9602ad159389c29e4ca964b86fa2f35c2faef54c3eb28b4efd36c8", - "sha256:c0f5e142ef8217019e3eef6ae1b6b55f09a7a15972958d44fbd228214cede567", - "sha256:cdb4272678db803ddf94caa4f94f8672e9a46bae4a44f167095e4d06fec12979", - "sha256:d70916235d478404a3fa8c997b003b5f33aeac4686ac1baa767234a0f8ac2326", - "sha256:d8ce3fb0841763a89322ea0432f1f59a2d3feae07a63ea2c958b2315e1ae8adb", - "sha256:e0b214e57623a535936005797567231a12d0da0c29711eb3514bc2b3cd008d0f", - "sha256:e631c70c9280e3129f071635b81207cad85e6c08e253539467e4ead0e5b219aa", - "sha256:e78578f0c7481c850d1c969aca9a65405887003484d24f6110458fb02cca7747", - "sha256:f0ca86b525264daa5f6b192f216a0d1e860b7383e3da1c65a1908f9c02f42801", - "sha256:f1a68f4f65a9ee64b6ccccb5bf7e17db07caebd2730109cb8a95863cfa9c4e55", - "sha256:fafe841be1103f340a24977f61dee76172e4ae5f647ab9e7fd1e1fca51524f08", - "sha256:ff68fc85355532ea77559ede81f35fff79a6a5543477e168ab3a381887caea76" - ], - "markers": "python_full_version >= '3.6.1'", - "version": "==1.9.2" + "markers": "python_version >= '3.8'", + "version": "==2.11.1" }, "pydocstyle": { "hashes": [ @@ -1110,11 +1362,11 @@ }, "pyflakes": { "hashes": [ - "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", - "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" + "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", + "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.3.1" + "markers": "python_version >= '3.8'", + "version": "==3.2.0" }, "pygments": { "hashes": [ @@ -1132,77 +1384,32 @@ "markers": "python_full_version >= '3.6.8'", "version": "==3.1.1" }, - "pyrsistent": { - "hashes": [ - "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f", - "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e", - "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958", - "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34", - "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca", - "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d", - "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d", - "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4", - "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714", - "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf", - "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee", - "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8", - "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224", - "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d", - "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054", - "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656", - "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7", - "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423", - "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce", - "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e", - "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3", - "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0", - "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f", - "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b", - "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce", - "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a", - "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174", - "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86", - "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f", - "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b", - "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98", - "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022" - ], - "markers": "python_version >= '3.8'", - "version": "==0.20.0" - }, - "pyserial": { - "hashes": [ - "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb", - "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0" - ], - "version": "==3.5" - }, "pytest": { "hashes": [ - "sha256:9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db", - "sha256:e30905a0c131d3d94b89624a1cc5afec3e0ba2fbdb151867d8e0ebd49850f171" + "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", + "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==7.0.1" + "markers": "python_version >= '3.7'", + "version": "==7.4.4" }, "pytest-asyncio": { "hashes": [ - "sha256:c16052382554c7b22d48782ab3438d5b10f8cf7a4bdcae7f0f67f097d95beecc", - "sha256:ea9021364e32d58f0be43b91c6233fb8d2224ccef2398d6837559e587682808f" + "sha256:2143d9d9375bf372a73260e4114541485e84fca350b0b6b92674ca56ff5f7ea2", + "sha256:b0079dfac14b60cd1ce4691fbfb1748fe939db7d0234b5aba97197d10fbe0fef" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==0.23.2" + "version": "==0.23.4" }, "pytest-cov": { "hashes": [ - "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191", - "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e" + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.10.1" + "markers": "python_version >= '3.7'", + "version": "==4.1.0" }, "pytest-forked": { "hashes": [ @@ -1239,13 +1446,6 @@ "markers": "python_version >= '3.6'", "version": "==2.5.0" }, - "python-can": { - "hashes": [ - "sha256:6ad50f4613289f3c4d276b6d2ac8901d776dcb929994cce93f55a69e858c595f", - "sha256:7eea9b81b0ff908000a825db024313f622895bd578e8a17433e0474cd7d2da83" - ], - "version": "==4.2.2" - }, "python-dateutil": { "hashes": [ "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", @@ -1294,14 +1494,6 @@ "markers": "python_full_version >= '3.7.0'", "version": "==13.7.0" }, - "setuptools": { - "hashes": [ - "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2", - "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6" - ], - "markers": "python_version >= '3.8'", - "version": "==69.0.2" - }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -1310,14 +1502,6 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, - "sniffio": { - "hashes": [ - "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", - "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384" - ], - "markers": "python_version >= '3.7'", - "version": "==1.3.0" - }, "snowballstemmer": { "hashes": [ "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", @@ -1357,36 +1541,36 @@ }, "sphinx-tabs": { "hashes": [ - "sha256:85939b689a0b0a24bf0da418b9acf14b0b0fca7a7a5cd35461ee452a2d4e716b", - "sha256:f1b72c4f23d1ba9cdcaf880fd883524bc70689f561b9785719b8b3c3c5ed0aca" + "sha256:92cc9473e2ecf1828ca3f6617d0efc0aa8acb06b08c56ba29d1413f2f0f6cf09", + "sha256:ba9d0c1e3e37aaadd4b5678449eb08176770e0fc227e769b6ce747df3ceea531" ], "index": "pypi", "markers": "python_version ~= '3.7'", - "version": "==3.4.4" + "version": "==3.4.5" }, "sphinxcontrib-applehelp": { "hashes": [ - "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d", - "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa" + "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619", + "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4" ], "markers": "python_version >= '3.9'", - "version": "==1.0.7" + "version": "==1.0.8" }, "sphinxcontrib-devhelp": { "hashes": [ - "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212", - "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f" + "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f", + "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3" ], "markers": "python_version >= '3.9'", - "version": "==1.0.5" + "version": "==1.0.6" }, "sphinxcontrib-htmlhelp": { "hashes": [ - "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a", - "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9" + "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015", + "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04" ], "markers": "python_version >= '3.9'", - "version": "==2.0.4" + "version": "==2.0.5" }, "sphinxcontrib-jsmath": { "hashes": [ @@ -1398,19 +1582,19 @@ }, "sphinxcontrib-qthelp": { "hashes": [ - "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d", - "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4" + "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6", + "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182" ], "markers": "python_version >= '3.9'", - "version": "==1.0.6" + "version": "==1.0.7" }, "sphinxcontrib-serializinghtml": { "hashes": [ - "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54", - "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1" + "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7", + "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f" ], "markers": "python_version >= '3.9'", - "version": "==1.1.9" + "version": "==1.1.10" }, "sphinxext-opengraph": { "hashes": [ @@ -1440,20 +1624,21 @@ }, "typeguard": { "hashes": [ - "sha256:33545edfd616f414690203fe431159b30f971c43b47e0caea8b81fa10e1e943e", - "sha256:6db5b8f03d8d34ce2acd6b9bc3035cd19f8050d91e170df45607e81ab964a746" + "sha256:8923e55f8873caec136c892c3bed1f676eae7be57cdb94819281b3d3bc9c0953", + "sha256:ea0a113bbc111bcffc90789ebb215625c963411f7096a7e9062d4e4630c155fd" ], "index": "pypi", - "markers": "python_full_version >= '3.5.3'", - "version": "==2.13.1" + "markers": "python_version >= '3.8'", + "version": "==4.1.5" }, "types-mock": { "hashes": [ - "sha256:1a470543be8de673e2ea14739622de3bfb8c9b10429f50338ba9ca1e868c15e9", - "sha256:1ad09970f4f5ec45a138ab1e88d032f010e851bccef7765b34737ed390bbc5c8" + "sha256:13ca379d5710ccb3f18f69ade5b08881874cb83383d8fb49b1d4dac9d5c5d090", + "sha256:3d116955495935b0bcba14954b38d97e507cd43eca3e3700fc1b8e4f5c6bf2c7" ], "index": "pypi", - "version": "==4.0.1" + "markers": "python_version >= '3.8'", + "version": "==5.1.0.20240106" }, "types-setuptools": { "hashes": [ @@ -1468,17 +1653,16 @@ "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], - "index": "pypi", "markers": "python_version >= '3.8'", "version": "==4.9.0" }, "urllib3": { "hashes": [ - "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", - "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" + "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20", + "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224" ], "markers": "python_version >= '3.8'", - "version": "==2.1.0" + "version": "==2.2.0" }, "wheel": { "hashes": [ @@ -1489,82 +1673,6 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.37.0" }, - "wrapt": { - "hashes": [ - "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc", - "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81", - "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09", - "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e", - "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca", - "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0", - "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb", - "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487", - "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40", - "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c", - "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060", - "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202", - "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41", - "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9", - "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b", - "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664", - "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", - "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362", - "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00", - "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc", - "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1", - "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267", - "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956", - "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966", - "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1", - "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228", - "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72", - "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d", - "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292", - "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0", - "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0", - "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36", - "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c", - "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5", - "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f", - "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73", - "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b", - "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2", - "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593", - "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39", - "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389", - "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf", - "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf", - "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89", - "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c", - "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c", - "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f", - "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440", - "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465", - "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136", - "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b", - "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8", - "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3", - "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8", - "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6", - "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e", - "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f", - "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c", - "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e", - "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8", - "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2", - "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020", - "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35", - "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d", - "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3", - "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537", - "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809", - "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d", - "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a", - "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4" - ], - "markers": "python_version >= '3.6'", - "version": "==1.16.0" - }, "zipp": { "hashes": [ "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", diff --git a/api/mypy.ini b/api/mypy.ini index 4e02621d6a5..6cbbea90d34 100644 --- a/api/mypy.ini +++ b/api/mypy.ini @@ -4,7 +4,7 @@ show_error_codes = True warn_unused_configs = True strict = True # TODO(mc, 2021-09-12): work through and remove these exclusions -exclude = tests/opentrons/(hardware_control/test_(?!ot3).*py|hardware_control/integration/|hardware_control/emulation/|hardware_control/modules/|protocols/advanced_control/|protocols/api_support/|protocols/duration/|protocols/execution/|protocols/fixtures/|protocols/geometry/) +exclude = tests/opentrons/(hardware_control/test_(?!(ot3|module_control)).*py|hardware_control/integration/|hardware_control/emulation/|hardware_control/modules/|protocols/advanced_control/|protocols/api_support/|protocols/duration/|protocols/execution/|protocols/fixtures/|protocols/geometry/) [pydantic-mypy] init_forbid_extra = True diff --git a/api/setup.py b/api/setup.py index 818a3c88ee7..ae53321ca22 100755 --- a/api/setup.py +++ b/api/setup.py @@ -60,11 +60,11 @@ def get_version(): INSTALL_REQUIRES = [ f"opentrons-shared-data=={VERSION}", "aionotify==0.2.0", - "anyio==3.6.1", - "jsonschema==3.0.2", - "numpy>=1.15.1,<2", - "pydantic==1.9.2", - "pyserial==3.5", + "anyio>=3.6.1,<4.0.0", + "jsonschema>=3.0.1,<4.18.0", + "numpy>=1.20.0,<2", + "pydantic>=1.10.9,<2.0.0", + "pyserial>=3.5", "typing-extensions>=4.0.0,<5", "click>=8.0.0,<9", 'importlib-metadata >= 1.0 ; python_version < "3.8"', diff --git a/api/src/opentrons/calibration_storage/helpers.py b/api/src/opentrons/calibration_storage/helpers.py index 011c3401bd3..b4cc6afe777 100644 --- a/api/src/opentrons/calibration_storage/helpers.py +++ b/api/src/opentrons/calibration_storage/helpers.py @@ -5,7 +5,7 @@ labware calibration to its designated file location. """ import json -from typing import Any, Union, List, Dict, TYPE_CHECKING, cast +from typing import Any, Union, List, Dict, TYPE_CHECKING, cast, Tuple from dataclasses import is_dataclass, asdict @@ -18,10 +18,7 @@ from opentrons_shared_data.pipette.dev_types import LabwareUri -DictionaryFactoryType = Union[List, Dict] - - -def dict_filter_none(data: DictionaryFactoryType) -> Dict[str, Any]: +def dict_filter_none(data: List[Tuple[str, Any]]) -> Dict[str, Any]: """ Helper function to filter out None keys from a dataclass before saving to file. diff --git a/api/src/opentrons/calibration_storage/ot2/models/v1.py b/api/src/opentrons/calibration_storage/ot2/models/v1.py index d70f5731d41..98f7dadca1c 100644 --- a/api/src/opentrons/calibration_storage/ot2/models/v1.py +++ b/api/src/opentrons/calibration_storage/ot2/models/v1.py @@ -51,7 +51,7 @@ class DeckCalibrationModel(BaseModel): attitude: types.AttitudeMatrix = Field( ..., description="Attitude matrix for deck found from calibration." ) - last_modified: datetime = Field( + last_modified: typing.Optional[datetime] = Field( default=None, description="The last time this deck was calibrated." ) source: types.SourceType = Field( diff --git a/api/src/opentrons/drivers/asyncio/communication/async_serial.py b/api/src/opentrons/drivers/asyncio/communication/async_serial.py index 9910b73215f..8d2db0ddda7 100644 --- a/api/src/opentrons/drivers/asyncio/communication/async_serial.py +++ b/api/src/opentrons/drivers/asyncio/communication/async_serial.py @@ -7,7 +7,7 @@ from typing import Optional, AsyncGenerator, Union from typing_extensions import Literal -from serial import Serial, serial_for_url # type: ignore[import] +from serial import Serial, serial_for_url # type: ignore[import-untyped] TimeoutProperties = Union[Literal["write_timeout"], Literal["timeout"]] diff --git a/api/src/opentrons/drivers/rpi_drivers/gpio.py b/api/src/opentrons/drivers/rpi_drivers/gpio.py index 69eb2d49b41..d692fa1f795 100755 --- a/api/src/opentrons/drivers/rpi_drivers/gpio.py +++ b/api/src/opentrons/drivers/rpi_drivers/gpio.py @@ -7,7 +7,7 @@ from . import RevisionPinsError from .types import gpio_group, PinDir, GPIOPin -import gpiod # type: ignore[import] +import gpiod # type: ignore[import-not-found] """ Raspberry Pi GPIO control module diff --git a/api/src/opentrons/drivers/serial_communication.py b/api/src/opentrons/drivers/serial_communication.py index 854921c35a6..9e2ee465504 100755 --- a/api/src/opentrons/drivers/serial_communication.py +++ b/api/src/opentrons/drivers/serial_communication.py @@ -1,12 +1,12 @@ from typing import List, Optional, Iterator -import serial # type: ignore[import] +import serial # type: ignore[import-untyped] from serial import Serial -from serial.tools import list_ports # type: ignore[import] +from serial.tools import list_ports # type: ignore[import-untyped] import contextlib import logging -from serial.tools.list_ports_common import ListPortInfo # type: ignore[import] +from serial.tools.list_ports_common import ListPortInfo # type: ignore[import-untyped] log = logging.getLogger(__name__) diff --git a/api/src/opentrons/drivers/smoothie_drivers/driver_3_0.py b/api/src/opentrons/drivers/smoothie_drivers/driver_3_0.py index c9958691e16..c43f8d3f13d 100755 --- a/api/src/opentrons/drivers/smoothie_drivers/driver_3_0.py +++ b/api/src/opentrons/drivers/smoothie_drivers/driver_3_0.py @@ -18,7 +18,7 @@ from math import isclose from opentrons.drivers.serial_communication import get_ports_by_name -from serial.serialutil import SerialException # type: ignore[import] +from serial.serialutil import SerialException # type: ignore[import-untyped] from opentrons.drivers.smoothie_drivers.connection import SmoothieConnection from opentrons.drivers.smoothie_drivers.constants import ( diff --git a/api/src/opentrons/drivers/smoothie_drivers/simulator.py b/api/src/opentrons/drivers/smoothie_drivers/simulator.py index ad1197f4aa5..4db3c28adf7 100644 --- a/api/src/opentrons/drivers/smoothie_drivers/simulator.py +++ b/api/src/opentrons/drivers/smoothie_drivers/simulator.py @@ -57,11 +57,11 @@ async def update_pipette_config( - endstop debounce M365.2 (NOT for zprobe debounce) - retract from endstop distance M365.3 """ - pass + return {} @property def current(self) -> Dict[str, float]: - pass + return {} @property def speed(self) -> None: diff --git a/api/src/opentrons/hardware_control/backends/controller.py b/api/src/opentrons/hardware_control/backends/controller.py index eb75389869d..f35d6092134 100644 --- a/api/src/opentrons/hardware_control/backends/controller.py +++ b/api/src/opentrons/hardware_control/backends/controller.py @@ -19,7 +19,7 @@ from pathlib import Path try: - import aionotify # type: ignore[import] + import aionotify # type: ignore[import-untyped] except (OSError, ModuleNotFoundError): aionotify = None diff --git a/api/src/opentrons/hardware_control/backends/ot3controller.py b/api/src/opentrons/hardware_control/backends/ot3controller.py index 96b503dbcdb..3b15a66e318 100644 --- a/api/src/opentrons/hardware_control/backends/ot3controller.py +++ b/api/src/opentrons/hardware_control/backends/ot3controller.py @@ -54,7 +54,7 @@ from .tip_presence_manager import TipPresenceManager try: - import aionotify # type: ignore[import] + import aionotify # type: ignore[import-untyped] except (OSError, ModuleNotFoundError): aionotify = None @@ -653,6 +653,7 @@ async def move( if not self._feature_flags.stall_detection_enabled else False, ) + mounts_moving = [ k for k in moving_axes_in_move_group(move_group) @@ -1218,7 +1219,6 @@ async def probe(self, axis: Axis, distance: float) -> OT3AxisMap[float]: async def clean_up(self) -> None: """Clean up.""" - try: loop = asyncio.get_event_loop() except RuntimeError: @@ -1227,6 +1227,15 @@ async def clean_up(self) -> None: if hasattr(self, "_event_watcher"): if loop.is_running() and self._event_watcher: self._event_watcher.close() + + messenger = getattr(self, "_messenger", None) + if messenger: + await messenger.stop() + + usb_messenger = getattr(self, "_usb_messenger", None) + if usb_messenger: + await usb_messenger.stop() + return None @staticmethod diff --git a/api/src/opentrons/hardware_control/backends/ot3simulator.py b/api/src/opentrons/hardware_control/backends/ot3simulator.py index d877efb5b5b..07eaaadda00 100644 --- a/api/src/opentrons/hardware_control/backends/ot3simulator.py +++ b/api/src/opentrons/hardware_control/backends/ot3simulator.py @@ -446,7 +446,7 @@ async def home_tip_motors( def _attached_to_mount( self, mount: OT3Mount, expected_instr: Optional[PipetteName] ) -> OT3AttachedInstruments: - init_instr = self._attached_instruments.get(mount, {"model": None, "id": None}) # type: ignore + init_instr = self._attached_instruments.get(mount, {"model": None, "id": None}) if mount is OT3Mount.GRIPPER: return self._attached_gripper_to_mount(cast(GripperSpec, init_instr)) return self._attached_pipette_to_mount( diff --git a/api/src/opentrons/hardware_control/execution_manager.py b/api/src/opentrons/hardware_control/execution_manager.py index b64f2525303..7e4f570933f 100644 --- a/api/src/opentrons/hardware_control/execution_manager.py +++ b/api/src/opentrons/hardware_control/execution_manager.py @@ -74,7 +74,9 @@ async def wait_for_is_running(self) -> None: async with self._condition: if self._state == ExecutionState.PAUSED: await self._condition.wait() - if self._state == ExecutionState.CANCELLED: + # type-ignore needed because this is a reentrant function and narrowing cannot + # apply + if self._state == ExecutionState.CANCELLED: # type: ignore[comparison-overlap] raise ExecutionCancelledError elif self._state == ExecutionState.CANCELLED: raise ExecutionCancelledError diff --git a/api/src/opentrons/hardware_control/instruments/instrument_abc.py b/api/src/opentrons/hardware_control/instruments/instrument_abc.py index 46b4810e22f..1411c1b2b1d 100644 --- a/api/src/opentrons/hardware_control/instruments/instrument_abc.py +++ b/api/src/opentrons/hardware_control/instruments/instrument_abc.py @@ -12,11 +12,13 @@ class AbstractInstrument(ABC, Generic[InstrumentConfig]): """Defines the common methods of an instrument.""" @property + @abstractmethod def model(self) -> str: """Return model of the instrument.""" ... @property + @abstractmethod def config(self) -> InstrumentConfig: """Instrument config in dataclass format.""" ... diff --git a/api/src/opentrons/hardware_control/ot3_calibration.py b/api/src/opentrons/hardware_control/ot3_calibration.py index 6c63b3d68d9..e49b4de171f 100644 --- a/api/src/opentrons/hardware_control/ot3_calibration.py +++ b/api/src/opentrons/hardware_control/ot3_calibration.py @@ -9,7 +9,7 @@ from enum import Enum from math import floor, copysign from logging import getLogger -from opentrons.util.linal import solve_attitude, SolvePoints +from opentrons.util.linal import solve_attitude, SolvePoints, DoubleMatrix from .types import OT3Mount, Axis, GripperProbe from opentrons.types import Point @@ -952,8 +952,10 @@ def apply_machine_transform( ------- Attitude matrix with regards to machine coordinate system. """ - belt_attitude_arr = np.array(belt_attitude) - machine_transform_arr = np.array(defaults_ot3.DEFAULT_MACHINE_TRANSFORM) + belt_attitude_arr: DoubleMatrix = np.array(belt_attitude) + machine_transform_arr: DoubleMatrix = np.array( + defaults_ot3.DEFAULT_MACHINE_TRANSFORM + ) deck_attitude_arr = np.dot(belt_attitude_arr, machine_transform_arr) deck_attitude = deck_attitude_arr.round(4).tolist() return deck_attitude # type: ignore[no-any-return] @@ -991,7 +993,7 @@ def validate_attitude_deck_calibration( TODO(pm, 5/9/2023): As with the OT2, expand on this method, or create another method to diagnose bad instrument offset data """ - curr_cal = np.array(deck_cal.attitude) + curr_cal: DoubleMatrix = np.array(deck_cal.attitude) row, _ = curr_cal.shape rank: int = np.linalg.matrix_rank(curr_cal) if row != rank: diff --git a/api/src/opentrons/hardware_control/robot_calibration.py b/api/src/opentrons/hardware_control/robot_calibration.py index 0d0f00f2479..270344fff2f 100644 --- a/api/src/opentrons/hardware_control/robot_calibration.py +++ b/api/src/opentrons/hardware_control/robot_calibration.py @@ -4,6 +4,7 @@ from datetime import datetime from dataclasses import dataclass from typing import Optional, List, Any, cast +from numpy.typing import NDArray from opentrons import config @@ -49,7 +50,7 @@ def validate_attitude_deck_calibration( TODO(lc, 8/10/2020): As with the OT2, expand on this method, or create another method to diagnose bad instrument offset data """ - curr_cal = np.array(deck_cal.attitude) + curr_cal: linal.DoubleMatrix = np.array(deck_cal.attitude) row, _ = curr_cal.shape rank: int = np.linalg.matrix_rank(curr_cal) if row != rank: @@ -68,7 +69,7 @@ def validate_gantry_calibration(gantry_cal: List[List[float]]) -> DeckTransformS This function determines whether the gantry calibration is valid or not based on the following use-cases: """ - curr_cal = np.array(gantry_cal) + curr_cal: linal.DoubleMatrix = np.array(gantry_cal) row, _ = curr_cal.shape rank: int = np.linalg.matrix_rank(curr_cal) @@ -95,7 +96,7 @@ def validate_gantry_calibration(gantry_cal: List[List[float]]) -> DeckTransformS def migrate_affine_xy_to_attitude( gantry_cal: List[List[float]], ) -> types.AttitudeMatrix: - masked_transform = np.array( + masked_transform: NDArray[np.bool_] = np.array( [ [True, True, True, False], [True, True, True, False], @@ -108,7 +109,7 @@ def migrate_affine_xy_to_attitude( ] = np.ma.masked_array( # type: ignore gantry_cal, ~masked_transform ) - attitude_array = np.zeros((3, 3)) + attitude_array: linal.DoubleMatrix = np.zeros((3, 3)) np.put(attitude_array, [0, 1, 2], masked_array[0].compressed()) np.put(attitude_array, [3, 4, 5], masked_array[1].compressed()) np.put(attitude_array, 8, 1) diff --git a/api/src/opentrons/hardware_control/thread_manager.py b/api/src/opentrons/hardware_control/thread_manager.py index 3e189c57a49..c72ec3857b9 100644 --- a/api/src/opentrons/hardware_control/thread_manager.py +++ b/api/src/opentrons/hardware_control/thread_manager.py @@ -18,6 +18,7 @@ AsyncGenerator, Union, Type, + ParamSpec, ) from .adapters import SynchronousAdapter from .modules.mod_abc import AbstractModule @@ -34,17 +35,14 @@ class ThreadManagerException(Exception): WrappedReturn = TypeVar("WrappedReturn", contravariant=True) WrappedYield = TypeVar("WrappedYield", contravariant=True) -WrappedCoro = TypeVar("WrappedCoro", bound=Callable[..., Awaitable[WrappedReturn]]) -WrappedAGenFunc = TypeVar( - "WrappedAGenFunc", bound=Callable[..., AsyncGenerator[WrappedYield, None]] -) +P = ParamSpec("P") async def call_coroutine_threadsafe( loop: asyncio.AbstractEventLoop, - coro: WrappedCoro, - *args: Sequence[Any], - **kwargs: Mapping[str, Any], + coro: Callable[P, Awaitable[WrappedReturn]], + *args: P.args, + **kwargs: P.kwargs, ) -> WrappedReturn: fut = cast( "asyncio.Future[WrappedReturn]", @@ -56,9 +54,9 @@ async def call_coroutine_threadsafe( async def execute_asyncgen_threadsafe( loop: asyncio.AbstractEventLoop, - agenfunc: WrappedAGenFunc, - *args: Sequence[Any], - **kwargs: Mapping[str, Any], + agenfunc: Callable[P, AsyncGenerator[WrappedYield, None]], + *args: P.args, + **kwargs: P.kwargs, ) -> AsyncGenerator[WrappedYield, None]: # This function should bridge an async generator function between two asyncio diff --git a/api/src/opentrons/protocol_api/core/instrument.py b/api/src/opentrons/protocol_api/core/instrument.py index 6c034adb4a5..e6bf63347b2 100644 --- a/api/src/opentrons/protocol_api/core/instrument.py +++ b/api/src/opentrons/protocol_api/core/instrument.py @@ -239,6 +239,7 @@ def get_dispense_flow_rate(self, rate: float = 1.0) -> float: def get_blow_out_flow_rate(self, rate: float = 1.0) -> float: ... + @abstractmethod def set_flow_rate( self, aspirate: Optional[float] = None, @@ -247,6 +248,7 @@ def set_flow_rate( ) -> None: ... + @abstractmethod def configure_for_volume(self, volume: float) -> None: """Configure the pipette for a specific volume. @@ -255,10 +257,12 @@ def configure_for_volume(self, volume: float) -> None: """ ... + @abstractmethod def prepare_to_aspirate(self) -> None: """Prepare the pipette to aspirate.""" ... + @abstractmethod def configure_nozzle_layout( self, style: NozzleLayout, @@ -274,6 +278,7 @@ def configure_nozzle_layout( """ ... + @abstractmethod def is_tip_tracking_available(self) -> bool: """Return whether auto tip tracking is available for the pipette's current nozzle configuration.""" ... diff --git a/api/src/opentrons/protocol_api/core/legacy/module_geometry.py b/api/src/opentrons/protocol_api/core/legacy/module_geometry.py index 78d1a7577e7..839154a76d1 100644 --- a/api/src/opentrons/protocol_api/core/legacy/module_geometry.py +++ b/api/src/opentrons/protocol_api/core/legacy/module_geometry.py @@ -13,6 +13,7 @@ from typing import TYPE_CHECKING, Optional import numpy as np +from numpy.typing import NDArray from opentrons_shared_data import module from opentrons_shared_data.module.dev_types import ModuleDefinitionV3 @@ -33,7 +34,6 @@ ThermocyclerModuleModel, ) - if TYPE_CHECKING: from opentrons.protocol_api.labware import Labware @@ -440,7 +440,7 @@ def create_geometry( display_name = definition["displayName"] if module_model == ThermocyclerModuleModel.THERMOCYCLER_V2: - pre_transform = np.array( + pre_transform: NDArray[np.double] = np.array( ( OLD_TC_GEN2_LABWARE_OFFSET["x"], OLD_TC_GEN2_LABWARE_OFFSET["y"], @@ -480,7 +480,7 @@ def create_geometry( xform_ser = xforms_ser["labwareOffset"] # apply the slot transform if any - xform = np.array(xform_ser) + xform: NDArray[np.double] = np.array(xform_ser) xformed = np.dot(xform, pre_transform) labware_offset = Point(xformed[0], xformed[1], xformed[2]) diff --git a/api/src/opentrons/protocol_engine/commands/__init__.py b/api/src/opentrons/protocol_engine/commands/__init__.py index d401c9bdde7..3dfe6eaf51f 100644 --- a/api/src/opentrons/protocol_engine/commands/__init__.py +++ b/api/src/opentrons/protocol_engine/commands/__init__.py @@ -37,6 +37,7 @@ CommandResult, CommandType, CommandPrivateResult, + CommandT, ) from .aspirate import ( @@ -323,6 +324,7 @@ "CommandResult", "CommandType", "CommandPrivateResult", + "CommandT", # base interfaces "AbstractCommandImpl", "AbstractCommandWithPrivateResultImpl", diff --git a/api/src/opentrons/protocol_engine/commands/command_unions.py b/api/src/opentrons/protocol_engine/commands/command_unions.py index 1c80f6c14f5..dc4cc18c35a 100644 --- a/api/src/opentrons/protocol_engine/commands/command_unions.py +++ b/api/src/opentrons/protocol_engine/commands/command_unions.py @@ -1,6 +1,6 @@ """Union types of concrete command definitions.""" -from typing import Union +from typing import Union, TypeVar from typing_extensions import Annotated from pydantic import Field @@ -610,3 +610,5 @@ ConfigureForVolumePrivateResult, ConfigureNozzleLayoutPrivateResult, ] + +CommandT = TypeVar("CommandT", bound=Command) diff --git a/api/src/opentrons/protocol_engine/execution/command_executor.py b/api/src/opentrons/protocol_engine/execution/command_executor.py index 828d060b9d3..7334d96e170 100644 --- a/api/src/opentrons/protocol_engine/execution/command_executor.py +++ b/api/src/opentrons/protocol_engine/execution/command_executor.py @@ -13,7 +13,12 @@ from ..state import StateStore from ..resources import ModelUtils -from ..commands import CommandStatus, AbstractCommandImpl +from ..commands import ( + CommandStatus, + AbstractCommandImpl, + CommandResult, + CommandPrivateResult, +) from ..actions import ActionDispatcher, UpdateCommandAction, FailCommandAction from ..errors import RunStoppedError from ..errors.exceptions import EStopActivatedError as PE_EStopActivatedError @@ -108,8 +113,8 @@ async def execute(self, command_id: str) -> None: f"Executing {command.id}, {command.commandType}, {command.params}" ) if isinstance(command_impl, AbstractCommandImpl): - result = await command_impl.execute(command.params) # type: ignore[arg-type] - private_result = None + result: CommandResult = await command_impl.execute(command.params) # type: ignore[arg-type] + private_result: Optional[CommandPrivateResult] = None else: result, private_result = await command_impl.execute(command.params) # type: ignore[arg-type] diff --git a/api/src/opentrons/protocol_engine/state/commands.py b/api/src/opentrons/protocol_engine/state/commands.py index 9ebef474c84..97c15345721 100644 --- a/api/src/opentrons/protocol_engine/state/commands.py +++ b/api/src/opentrons/protocol_engine/state/commands.py @@ -4,7 +4,7 @@ from enum import Enum from dataclasses import dataclass from datetime import datetime -from typing import Dict, List, Mapping, Optional, Union +from typing import Dict, List, Optional, Union from opentrons_shared_data.errors import EnumeratedError, ErrorCodes, PythonException @@ -197,8 +197,6 @@ def __init__( def handle_action(self, action: Action) -> None: # noqa: C901 """Modify state in reaction to an action.""" - errors_by_id: Mapping[str, ErrorOccurrence] - if isinstance(action, QueueCommandAction): assert action.command_id not in self._state.commands_by_id diff --git a/api/src/opentrons/protocol_engine/state/geometry.py b/api/src/opentrons/protocol_engine/state/geometry.py index 88fb7861b98..adfa5474d18 100644 --- a/api/src/opentrons/protocol_engine/state/geometry.py +++ b/api/src/opentrons/protocol_engine/state/geometry.py @@ -1,6 +1,7 @@ """Geometry state getters.""" import enum -from numpy import array, dot +from numpy import array, dot, double as npdouble +from numpy.typing import NDArray from typing import Optional, List, Tuple, Union, cast, TypeVar, Dict from opentrons.types import Point, DeckSlotName, StagingSlotName, MountType @@ -296,8 +297,10 @@ def _normalize_module_calibration_offset( # Check if the module has moved from one side of the deck to the other if calibrated_slot_column != current_slot_column: # Since the module was rotated, the calibration offset vector needs to be rotated by 180 degrees along the z axis - saved_offset = array([offset.x, offset.y, offset.z]) - rotation_matrix = array([[-1, 0, 0], [0, -1, 0], [0, 0, 1]]) + saved_offset: NDArray[npdouble] = array([offset.x, offset.y, offset.z]) + rotation_matrix: NDArray[npdouble] = array( + [[-1, 0, 0], [0, -1, 0], [0, 0, 1]] + ) new_offset = dot(saved_offset, rotation_matrix) offset = ModuleOffsetVector( x=new_offset[0], y=new_offset[1], z=new_offset[2] @@ -603,7 +606,7 @@ def ensure_location_not_occupied( self._labware.raise_if_labware_in_location(location) if isinstance(location, DeckSlotLocation): self._modules.raise_if_module_in_location(location) - return cast(_LabwareLocation, location) + return location def get_labware_grip_point( self, diff --git a/api/src/opentrons/protocol_engine/state/modules.py b/api/src/opentrons/protocol_engine/state/modules.py index d7cfeecef14..124915baeeb 100644 --- a/api/src/opentrons/protocol_engine/state/modules.py +++ b/api/src/opentrons/protocol_engine/state/modules.py @@ -14,7 +14,8 @@ Union, overload, ) -from numpy import array, dot +from numpy import array, dot, double as npdouble +from numpy.typing import NDArray from opentrons.hardware_control.modules.magdeck import ( OFFSET_TO_LABWARE_BOTTOM as MAGNETIC_MODULE_OFFSET_TO_LABWARE_BOTTOM, @@ -661,7 +662,7 @@ def get_nominal_module_offset( definition = self.get_definition(module_id) slot = self.get_location(module_id).slotName.id - pre_transform = array( + pre_transform: NDArray[npdouble] = array( ( definition.labwareOffset.x, definition.labwareOffset.y, @@ -676,7 +677,7 @@ def get_nominal_module_offset( xforms_ser_offset = xforms_ser["labwareOffset"] # Apply the slot transform, if any - xform = array(xforms_ser_offset) + xform: NDArray[npdouble] = array(xforms_ser_offset) xformed = dot(xform, pre_transform) return LabwareOffsetVector( x=xformed[0], diff --git a/api/src/opentrons/protocol_reader/input_file.py b/api/src/opentrons/protocol_reader/input_file.py index 86390accf83..0ab1fe1dad9 100644 --- a/api/src/opentrons/protocol_reader/input_file.py +++ b/api/src/opentrons/protocol_reader/input_file.py @@ -1,10 +1,9 @@ """Input file value objects.""" from __future__ import annotations -from typing import IO -from typing_extensions import Protocol as InterfaceShape +from typing import BinaryIO, Protocol -class AbstractInputFile(InterfaceShape): +class AbstractInputFile(Protocol): """An individual file to be read as part of a protocol. Properties: @@ -14,4 +13,4 @@ class AbstractInputFile(InterfaceShape): """ filename: str - file: IO[bytes] + file: BinaryIO diff --git a/api/src/opentrons/protocols/models/json_protocol.py b/api/src/opentrons/protocols/models/json_protocol.py index c600f03ca8c..6cd7c32aa2d 100644 --- a/api/src/opentrons/protocols/models/json_protocol.py +++ b/api/src/opentrons/protocols/models/json_protocol.py @@ -673,7 +673,7 @@ class Model(BaseModel): None, description="All modules used in this protocol" ) commands: List[AllCommands] = Field( - None, + ..., description="An array of command objects representing steps to be executed " "on the robot", ) diff --git a/api/src/opentrons/util/linal.py b/api/src/opentrons/util/linal.py index cc82b5794b2..9456b2d80e1 100644 --- a/api/src/opentrons/util/linal.py +++ b/api/src/opentrons/util/linal.py @@ -3,7 +3,8 @@ import numpy as np from numpy import insert, dot from numpy.linalg import inv -from typing import TYPE_CHECKING, List, Tuple, Union +from numpy.typing import NDArray +from typing import List, Tuple, Union from opentrons.calibration_storage.types import AttitudeMatrix @@ -17,12 +18,8 @@ Tuple[float, float, float], Tuple[float, float, float], Tuple[float, float, float] ] -# TODO(mc, 2022-02-23): numpy.typing is not available on the version -# of numpy we ship on the OT-2. We should update that numpy version. -if TYPE_CHECKING: - import numpy.typing as npt - - DoubleArray = npt.NDArray[np.double] +DoubleArray = NDArray[np.double] +DoubleMatrix = NDArray[np.double] def identity_deck_transform() -> DoubleArray: @@ -31,11 +28,11 @@ def identity_deck_transform() -> DoubleArray: def solve_attitude(expected: SolvePoints, actual: SolvePoints) -> AttitudeMatrix: - ex = np.array([list(point) for point in expected]).transpose() - ac = np.array([list(point) for point in actual]).transpose() + ex: DoubleMatrix = np.array([list(point) for point in expected]).transpose() + ac: DoubleMatrix = np.array([list(point) for point in actual]).transpose() t = np.dot(ac, inv(ex)) - mask_transform = np.array( + mask_transform: NDArray[np.bool_] = np.array( [[True, True, False], [True, True, False], [False, False, False]] ) masked_array = np.ma.masked_array(t, ~mask_transform) # type: ignore[var-annotated, no-untyped-call] @@ -97,9 +94,9 @@ def solve( # [ (x1, y1), # (x2, y2), # (x3, y3) ] - ex = np.array([list(point) + [1] for point in expected]).transpose() + ex: DoubleMatrix = np.array([list(point) + [1] for point in expected]).transpose() - ac = np.array([list(point) + [1] for point in actual]).transpose() + ac: DoubleMatrix = np.array([list(point) + [1] for point in actual]).transpose() # Shape of `ex` and `ac`: # [ x1 x2 x3 ] # [ y1 y2 y3 ] @@ -139,7 +136,7 @@ def add_z(xy: DoubleArray, z: float) -> DoubleArray: # [ 0 0 0 1 ] # Then, insert the z row to create a properly formed 3-D transform matrix: - xyz = insert(interm, 2, [0, 0, 1, z], axis=0) + xyz: DoubleMatrix = insert(interm, 2, [0, 0, 1, z], axis=0) # Result: # [ 1 0 0 x ] # [ 0 1 0 y ] @@ -155,7 +152,7 @@ def add_matrices( """ Simple method to convert tuples to numpy arrays and add them. """ - return tuple(np.asarray(t1) + np.asarray(t2)) # type: ignore + return tuple(np.asarray(t1) + np.asarray(t2)) def apply_transform( @@ -170,7 +167,7 @@ def apply_transform( :param pos: XYZ point in space A :return: corresponding XYZ point in space B """ - return tuple(dot(t, list(pos))[:3]) # type: ignore + return tuple(dot(t, list(pos))[:3]) def apply_reverse( diff --git a/api/tests/opentrons/commands/test_publisher.py b/api/tests/opentrons/commands/test_publisher.py index f38142984bf..a88e6c04523 100644 --- a/api/tests/opentrons/commands/test_publisher.py +++ b/api/tests/opentrons/commands/test_publisher.py @@ -17,7 +17,7 @@ def broker(decoy: Decoy) -> LegacyBroker: def test_publish_decorator(decoy: Decoy, broker: LegacyBroker) -> None: """It should publish "before" and "after" messages for decorated methods.""" - _act = decoy.mock() + _act = decoy.mock(name="_act") def _get_command_payload(foo: str, bar: int) -> CommandDict: return cast( @@ -73,7 +73,7 @@ def test_publish_decorator_with_arg_defaults( decoy: Decoy, broker: LegacyBroker ) -> None: """It should pass method argument defaults to the command creator.""" - _act = decoy.mock() + _act = decoy.mock(name="_act") def _get_command_payload(foo: str, bar: int) -> CommandDict: return cast( @@ -175,7 +175,7 @@ def test_publish_decorator_remaps_instrument( decoy: Decoy, broker: LegacyBroker ) -> None: """It should pass "self" to command creator arguments named "instrument".""" - _act = decoy.mock() + _act = decoy.mock(name="_act") def _get_command_payload(foo: str, instrument: _Subject) -> Dict[str, Any]: return { @@ -226,7 +226,7 @@ def act(self, foo: str) -> None: def test_publish_context(decoy: Decoy, broker: LegacyBroker) -> None: - _act = decoy.mock() + _act = decoy.mock(name="_act") command = cast( CommandDict, diff --git a/api/tests/opentrons/config/test_advanced_settings.py b/api/tests/opentrons/config/test_advanced_settings.py index 606d691b1a9..b81b9149c67 100644 --- a/api/tests/opentrons/config/test_advanced_settings.py +++ b/api/tests/opentrons/config/test_advanced_settings.py @@ -1,5 +1,5 @@ import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from typing import Dict, Generator, Optional from unittest.mock import MagicMock, patch diff --git a/api/tests/opentrons/config/test_advanced_settings_migration.py b/api/tests/opentrons/config/test_advanced_settings_migration.py index 14725e94390..1070654e14d 100644 --- a/api/tests/opentrons/config/test_advanced_settings_migration.py +++ b/api/tests/opentrons/config/test_advanced_settings_migration.py @@ -1,7 +1,8 @@ -from typing import Any, Dict +from typing import Any, Dict, cast import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from _pytest.fixtures import SubRequest +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from opentrons.config.advanced_settings import _migrate, _ensure @@ -402,8 +403,8 @@ def v30_config(v29_config: Dict[str, Any]) -> Dict[str, Any]: lazy_fixture("v30_config"), ], ) -def old_settings(request: pytest.FixtureRequest) -> Dict[str, Any]: - return request.param # type: ignore[attr-defined, no-any-return] +def old_settings(request: SubRequest) -> Dict[str, Any]: + return cast(Dict[str, Any], request.param) def test_migrations( diff --git a/api/tests/opentrons/conftest.py b/api/tests/opentrons/conftest.py index f1328716f63..dcf6b6c4e37 100755 --- a/api/tests/opentrons/conftest.py +++ b/api/tests/opentrons/conftest.py @@ -23,12 +23,13 @@ from typing_extensions import TypedDict import pytest +from _pytest.fixtures import SubRequest from decoy import Decoy from opentrons.protocol_engine.types import PostRunHardwareState try: - import aionotify # type: ignore[import] + import aionotify # type: ignore[import-untyped] except (OSError, ModuleNotFoundError): aionotify = None @@ -156,11 +157,11 @@ def virtual_smoothie_env(monkeypatch: pytest.MonkeyPatch) -> None: @pytest.fixture(params=["ot2", "ot3"]) async def machine_variant_ffs( - request: pytest.FixtureRequest, + request: SubRequest, decoy: Decoy, mock_feature_flags: None, ) -> None: - device_param = request.param # type: ignore[attr-defined] + device_param = request.param if request.node.get_closest_marker("ot3_only") and device_param == "ot2": pytest.skip() @@ -229,7 +230,7 @@ async def robot_model( mock_feature_flags: None, virtual_smoothie_env: None, ) -> AsyncGenerator[RobotModel, None]: - which_machine = cast(RobotModel, request.param) # type: ignore[attr-defined] + which_machine = cast(RobotModel, request.param) if request.node.get_closest_marker("ot2_only") and which_machine == "OT-3 Standard": pytest.skip("test requests only ot-2") if request.node.get_closest_marker("ot3_only") and which_machine == "OT-2 Standard": @@ -266,7 +267,7 @@ def legacy_deck_definition(deck_definition_name: str) -> DeckDefinitionV3: @pytest.fixture() async def hardware( - request: pytest.FixtureRequest, + request: SubRequest, decoy: Decoy, mock_feature_flags: None, virtual_smoothie_env: None, diff --git a/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py b/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py index 16399ce5d5d..d75ea01592f 100644 --- a/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py +++ b/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py @@ -4,7 +4,7 @@ import pytest from mock import MagicMock, PropertyMock, call -from serial import Serial # type: ignore[import] +from serial import Serial # type: ignore[import-untyped] from opentrons.drivers.asyncio.communication import AsyncSerial diff --git a/api/tests/opentrons/drivers/asyncio/communication/test_serial_connection.py b/api/tests/opentrons/drivers/asyncio/communication/test_serial_connection.py index 7fc16241684..0acf47af3d5 100644 --- a/api/tests/opentrons/drivers/asyncio/communication/test_serial_connection.py +++ b/api/tests/opentrons/drivers/asyncio/communication/test_serial_connection.py @@ -1,6 +1,7 @@ from typing import Type, Union import pytest +from _pytest.fixtures import SubRequest from mock import AsyncMock, call import mock @@ -35,10 +36,10 @@ def ack() -> str: params=[AsyncResponseSerialConnection, SerialConnection], # type: ignore[return] ) async def subject( - request: pytest.FixtureRequest, mock_serial_port: AsyncMock, ack: str + request: SubRequest, mock_serial_port: AsyncMock, ack: str ) -> SerialKind: """Create the test subject.""" - serial_class = request.param # type: ignore[attr-defined] + serial_class = request.param serial_class.RETRY_WAIT_TIME = 0 if serial_class == AsyncResponseSerialConnection: return serial_class( # type: ignore[no-any-return] diff --git a/api/tests/opentrons/drivers/rpi_drivers/test_usb.py b/api/tests/opentrons/drivers/rpi_drivers/test_usb.py index cad9a40b9b9..1f409181a50 100644 --- a/api/tests/opentrons/drivers/rpi_drivers/test_usb.py +++ b/api/tests/opentrons/drivers/rpi_drivers/test_usb.py @@ -84,7 +84,7 @@ def test_modify_module_list(revision: BoardRevision, usb_bus: USBBus): # TODO(mc, 2022-03-01): partial patching the class under test creates # a contaminated test subject that reduces the value of these tests # https://github.com/testdouble/contributing-tests/wiki/Partial-Mock - usb_bus._read_symlink = MagicMock(return_value="ttyACM1") # type: ignore[assignment] + usb_bus._read_symlink = MagicMock(return_value="ttyACM1") # type: ignore[method-assign] mod_at_port_list = [ ModuleAtPort( name="temperature module", port="dev/ot_module_temperature_module" @@ -123,7 +123,7 @@ def test_modify_module_list(revision: BoardRevision, usb_bus: USBBus): hub_port=None, ) - usb_bus._read_symlink = MagicMock(return_value="ttyACM2") # type: ignore[assignment] + usb_bus._read_symlink = MagicMock(return_value="ttyACM2") # type: ignore[method-assign] mod_at_port_list = [ ModuleAtPort(name="magnetic module", port="dev/ot_module_magnetic_module"), ] @@ -161,7 +161,7 @@ def test_modify_module_list(revision: BoardRevision, usb_bus: USBBus): ) if revision == BoardRevision.FLEX_B2: - usb_bus._read_symlink = MagicMock(return_value="ttyACM4") # type: ignore[assignment] + usb_bus._read_symlink = MagicMock(return_value="ttyACM4") # type: ignore[method-assign] mod_at_port_list = [ ModuleAtPort( name="heater-shaker module", port="dev/ot_module_heater_shaker_module" @@ -178,7 +178,7 @@ def test_modify_module_list(revision: BoardRevision, usb_bus: USBBus): hub_port=None, ) - usb_bus._read_symlink = MagicMock(return_value="ttyACM5") # type: ignore[assignment] + usb_bus._read_symlink = MagicMock(return_value="ttyACM5") # type: ignore[method-assign] mod_at_port_list = [ ModuleAtPort( name="thermocycler module", port="dev/ot_module_thermocycler_module" diff --git a/api/tests/opentrons/drivers/smoothie_drivers/test_driver.py b/api/tests/opentrons/drivers/smoothie_drivers/test_driver.py index c94668204fe..8821c491a6d 100755 --- a/api/tests/opentrons/drivers/smoothie_drivers/test_driver.py +++ b/api/tests/opentrons/drivers/smoothie_drivers/test_driver.py @@ -272,7 +272,7 @@ async def test_home_flagged_axes( expected: str, ) -> None: """It should only home un-homed axes.""" - smoothie.home = AsyncMock() # type: ignore[assignment] + smoothie.home = AsyncMock() # type: ignore[method-assign] await smoothie.update_homed_flags(home_flags) await smoothie.home_flagged_axes(axes_string=axis_string) @@ -292,7 +292,7 @@ async def test_home_flagged_axes_no_call( smoothie: driver_3_0.SmoothieDriver, home_flags: Dict[str, bool], axis_string: str ) -> None: """It should not home homed axes.""" - smoothie.home = AsyncMock() # type: ignore[assignment] + smoothie.home = AsyncMock() # type: ignore[method-assign] await smoothie.update_homed_flags(home_flags) await smoothie.home_flagged_axes(axes_string=axis_string) diff --git a/api/tests/opentrons/hardware_control/backends/test_ot3_controller.py b/api/tests/opentrons/hardware_control/backends/test_ot3_controller.py index 3462fa2d9db..8720b2d1b08 100644 --- a/api/tests/opentrons/hardware_control/backends/test_ot3_controller.py +++ b/api/tests/opentrons/hardware_control/backends/test_ot3_controller.py @@ -1,8 +1,12 @@ import mock import pytest from decoy import Decoy +import asyncio -from contextlib import nullcontext as does_not_raise, AbstractContextManager +from contextlib import ( + nullcontext as does_not_raise, + AbstractContextManager, +) from typing import ( cast, Dict, @@ -155,9 +159,9 @@ def controller( mock_config: OT3Config, mock_can_driver: AbstractCanDriver, mock_eeprom_driver: EEPROMDriver, -) -> Iterator[OT3Controller]: +) -> OT3Controller: with (mock.patch("opentrons.hardware_control.backends.ot3controller.OT3GPIO")): - yield OT3Controller( + return OT3Controller( mock_config, mock_can_driver, eeprom_driver=mock_eeprom_driver ) @@ -199,6 +203,25 @@ def mock_move_group_run() -> Iterator[mock.AsyncMock]: yield mock_mgr_run +@pytest.fixture +def mock_check_overpressure() -> Iterator[mock.AsyncMock]: + with mock.patch( + "opentrons.hardware_control.backends.ot3controller.check_overpressure", + autospec=True, + ) as mock_check_overpressure: + queue: asyncio.Queue[Any] = asyncio.Queue() + + class FakeOverpressure: + async def __aenter__(self) -> asyncio.Queue[Any]: + return queue + + async def __aexit__(self, *args: Any, **kwargs: Any) -> None: + pass + + mock_check_overpressure.return_value = lambda: FakeOverpressure() + yield mock_check_overpressure + + def _device_info_entry(subsystem: SubSystem) -> Tuple[SubSystem, DeviceInfoCache]: return subsystem, DeviceInfoCache( target=subsystem_to_target(subsystem), @@ -339,11 +362,12 @@ async def test_home_execute( controller: OT3Controller, axes: List[Axis], mock_present_devices: None, + mock_check_overpressure: None, ) -> None: config = {"run.side_effect": move_group_run_side_effect(controller, axes)} with mock.patch( # type: ignore [call-overload] "opentrons.hardware_control.backends.ot3controller.MoveGroupRunner", - spec=mock.Mock(MoveGroupRunner), + spec=MoveGroupRunner, **config ) as mock_runner: present_axes = set(ax for ax in axes if controller.axis_is_present(ax)) @@ -351,7 +375,6 @@ async def test_home_execute( # nothing has been homed assert not controller._motor_status await controller.home(axes, GantryLoad.LOW_THROUGHPUT) - all_groups = [ group for arg in mock_runner.call_args_list @@ -394,7 +417,7 @@ async def test_home_gantry_order( ) -> None: with mock.patch( "opentrons.hardware_control.backends.ot3controller.MoveGroupRunner", - spec=mock.Mock(MoveGroupRunner), + spec=MoveGroupRunner, ) as mock_runner: controller._build_home_gantry_z_runner(axes, GantryLoad.LOW_THROUGHPUT) has_mount = len(set(Axis.ot3_mount_axes()) & set(axes)) > 0 @@ -446,6 +469,7 @@ async def test_home_only_present_devices( mock_move_group_run: mock.AsyncMock, axes: List[Axis], mock_present_devices: None, + mock_check_overpressure: None, ) -> None: starting_position = { NodeId.head_l: 20.0, @@ -1061,19 +1085,6 @@ async def fake_src( await controller.set_active_current({Axis.X: 2}) -async def test_monitor_pressure( - controller: OT3Controller, - mock_move_group_run: mock.AsyncMock, - mock_present_devices: None, -) -> None: - mount = NodeId.pipette_left - mock_move_group_run.side_effect = move_group_run_side_effect(controller, [Axis.P_L]) - async with controller._monitor_overpressure([mount]): - await controller.home([Axis.P_L], GantryLoad.LOW_THROUGHPUT) - - mock_move_group_run.assert_called_once() - - @pytest.mark.parametrize( "estop_state, expectation", [ @@ -1089,6 +1100,7 @@ async def test_requires_estop( decoy: Decoy, estop_state: EstopState, expectation: ContextManager[None], + mock_check_overpressure: None, ) -> None: """Test that the estop state machine raises properly.""" decoy.when(mock_estop_state_machine.state).then_return(estop_state) diff --git a/api/tests/opentrons/hardware_control/backends/test_ot3_estop_state.py b/api/tests/opentrons/hardware_control/backends/test_ot3_estop_state.py index e179f29417c..1d4a86a1343 100644 --- a/api/tests/opentrons/hardware_control/backends/test_ot3_estop_state.py +++ b/api/tests/opentrons/hardware_control/backends/test_ot3_estop_state.py @@ -1,6 +1,6 @@ import pytest from decoy import Decoy -from typing import List, Tuple, Optional +from typing import List, Tuple, Optional, cast from opentrons.hardware_control.backends.estop_state import EstopStateMachine from opentrons_hardware.hardware_control.estop.detector import ( @@ -59,7 +59,7 @@ async def test_estop_state_no_detector( subject.subscribe_to_detector(detector=mock_estop_detector) - assert subject.state == EstopState.PHYSICALLY_ENGAGED + assert cast(EstopState, subject.state) == EstopState.PHYSICALLY_ENGAGED assert ( subject.get_physical_status(EstopAttachLocation.LEFT) == EstopPhysicalStatus.NOT_PRESENT diff --git a/api/tests/opentrons/hardware_control/instruments/test_instrument_calibration.py b/api/tests/opentrons/hardware_control/instruments/test_instrument_calibration.py index ac97947bfff..b850803ba61 100644 --- a/api/tests/opentrons/hardware_control/instruments/test_instrument_calibration.py +++ b/api/tests/opentrons/hardware_control/instruments/test_instrument_calibration.py @@ -3,7 +3,7 @@ from typing import Union, cast import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from decoy import Decoy from opentrons_shared_data.labware.dev_types import ( diff --git a/api/tests/opentrons/hardware_control/instruments/test_nozzle_manager.py b/api/tests/opentrons/hardware_control/instruments/test_nozzle_manager.py index b87c542b07e..dc06ce9ea62 100644 --- a/api/tests/opentrons/hardware_control/instruments/test_nozzle_manager.py +++ b/api/tests/opentrons/hardware_control/instruments/test_nozzle_manager.py @@ -1,5 +1,5 @@ import pytest -from typing import Dict, List, Tuple, Union, Iterator +from typing import Dict, List, Tuple, Union, Iterator, cast from opentrons.hardware_control import nozzle_manager @@ -132,6 +132,7 @@ def test_multi_config_identification( pipette_details[0], PipetteChannelType.EIGHT_CHANNEL, pipette_details[1] ) subject = nozzle_manager.NozzleConfigurationManager.build_from_config(config) + assert ( subject.current_configuration.configuration == nozzle_manager.NozzleConfigurationType.FULL @@ -151,25 +152,37 @@ def test_multi_config_identification( subject.update_nozzle_configuration("A1", "D1", "A1") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.COLUMN ) subject.update_nozzle_configuration("A1", "A1", "A1") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.SINGLE ) subject.update_nozzle_configuration("H1", "H1", "H1") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.SINGLE ) subject.update_nozzle_configuration("C1", "F1", "C1") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.COLUMN ) @@ -328,70 +341,109 @@ def test_96_config_identification( ) subject.update_nozzle_configuration("A1", "H1") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.COLUMN ) subject.update_nozzle_configuration("A12", "H12") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.COLUMN ) subject.update_nozzle_configuration("A8", "H8") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.COLUMN ) subject.update_nozzle_configuration("A1", "A12") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.ROW ) subject.update_nozzle_configuration("H1", "H12") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.ROW ) subject.update_nozzle_configuration("D1", "D12") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.ROW ) subject.update_nozzle_configuration("E1", "H6") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.SUBRECT ) subject.update_nozzle_configuration("E7", "H12") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.SUBRECT ) subject.update_nozzle_configuration("C4", "F9") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.SUBRECT ) subject.update_nozzle_configuration("A1", "D12") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.SUBRECT ) subject.update_nozzle_configuration("E1", "H12") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.SUBRECT ) subject.update_nozzle_configuration("A1", "H6") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.SUBRECT ) subject.update_nozzle_configuration("A7", "H12") assert ( - subject.current_configuration.configuration + cast( + nozzle_manager.NozzleConfigurationType, + subject.current_configuration.configuration, + ) == nozzle_manager.NozzleConfigurationType.SUBRECT ) diff --git a/api/tests/opentrons/hardware_control/test_module_control.py b/api/tests/opentrons/hardware_control/test_module_control.py index b683f12d590..eed809bdb55 100644 --- a/api/tests/opentrons/hardware_control/test_module_control.py +++ b/api/tests/opentrons/hardware_control/test_module_control.py @@ -34,7 +34,10 @@ def build_module(decoy: Decoy) -> Callable[..., Awaitable[AbstractModule]]: `AttachedModulesControl` is doing too much work _and_ these tests are too brittle and of questionable value. """ - return cast(Callable[..., Awaitable[AbstractModule]], decoy.mock(is_async=True)) + return cast( + Callable[..., Awaitable[AbstractModule]], + decoy.mock(name="build_module", is_async=True), + ) @pytest.fixture() diff --git a/api/tests/opentrons/hardware_control/test_simulator_setup.py b/api/tests/opentrons/hardware_control/test_simulator_setup.py index 0c23412a834..422375f1bf6 100644 --- a/api/tests/opentrons/hardware_control/test_simulator_setup.py +++ b/api/tests/opentrons/hardware_control/test_simulator_setup.py @@ -61,7 +61,7 @@ async def test_with_magdeck(setup_klass: Type[simulator_setup.SimulatorSetup]) - ) simulator = await simulator_setup.create_simulator(setup) - assert type(simulator.attached_modules[0]) == MagDeck + assert isinstance(simulator.attached_modules[0], MagDeck) assert simulator.attached_modules[0].live_data == { "data": {"engaged": True, "height": 3}, "status": "engaged", @@ -89,7 +89,7 @@ async def test_with_thermocycler( ) simulator = await simulator_setup.create_simulator(setup) - assert type(simulator.attached_modules[0]) == Thermocycler + assert isinstance(simulator.attached_modules[0], Thermocycler) assert simulator.attached_modules[0].live_data == { "data": { "currentCycleIndex": None, @@ -125,7 +125,7 @@ async def test_with_tempdeck(setup_klass: Type[simulator_setup.SimulatorSetup]) ) simulator = await simulator_setup.create_simulator(setup) - assert type(simulator.attached_modules[0]) == TempDeck + assert isinstance(simulator.attached_modules[0], TempDeck) assert simulator.attached_modules[0].live_data == { "data": {"currentTemp": 23, "targetTemp": 23}, "status": "holding at target", diff --git a/api/tests/opentrons/protocol_api/core/engine/test_protocol_core.py b/api/tests/opentrons/protocol_api/core/engine/test_protocol_core.py index 51fa22e9d98..a8f83d63a7e 100644 --- a/api/tests/opentrons/protocol_api/core/engine/test_protocol_core.py +++ b/api/tests/opentrons/protocol_api/core/engine/test_protocol_core.py @@ -3,7 +3,7 @@ from typing import Optional, Type, cast, Tuple import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from decoy import Decoy from opentrons_shared_data.deck import load as load_deck diff --git a/api/tests/opentrons/protocol_api/core/legacy/test_module_geometry.py b/api/tests/opentrons/protocol_api/core/legacy/test_module_geometry.py index 22e787baab7..744235ea03a 100644 --- a/api/tests/opentrons/protocol_api/core/legacy/test_module_geometry.py +++ b/api/tests/opentrons/protocol_api/core/legacy/test_module_geometry.py @@ -3,7 +3,7 @@ import mock from typing import ContextManager, Any, Optional -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from contextlib import nullcontext as does_not_raise from opentrons.types import Location, Point diff --git a/api/tests/opentrons/protocol_api/test_instrument_context.py b/api/tests/opentrons/protocol_api/test_instrument_context.py index 78369be3f95..be45907ab31 100644 --- a/api/tests/opentrons/protocol_api/test_instrument_context.py +++ b/api/tests/opentrons/protocol_api/test_instrument_context.py @@ -2,7 +2,7 @@ import inspect import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from decoy import Decoy from opentrons.legacy_broker import LegacyBroker diff --git a/api/tests/opentrons/protocol_api_old/core/protocol_api/test_instrument_context.py b/api/tests/opentrons/protocol_api_old/core/protocol_api/test_instrument_context.py index 77438c1f4ed..7cea4113e28 100644 --- a/api/tests/opentrons/protocol_api_old/core/protocol_api/test_instrument_context.py +++ b/api/tests/opentrons/protocol_api_old/core/protocol_api/test_instrument_context.py @@ -2,6 +2,7 @@ from typing import cast import pytest +from _pytest.fixtures import SubRequest from decoy import Decoy from opentrons.types import Mount @@ -18,9 +19,9 @@ @pytest.fixture(params=[Mount.LEFT, Mount.RIGHT]) -def mount(request: pytest.FixtureRequest) -> Mount: +def mount(request: SubRequest) -> Mount: """Set the subject's mount.""" - return cast(Mount, request.param) # type: ignore[attr-defined] + return cast(Mount, request.param) @pytest.fixture diff --git a/api/tests/opentrons/protocol_api_old/core/simulator/test_instrument_context.py b/api/tests/opentrons/protocol_api_old/core/simulator/test_instrument_context.py index d0916dd4108..c9bd57c0997 100644 --- a/api/tests/opentrons/protocol_api_old/core/simulator/test_instrument_context.py +++ b/api/tests/opentrons/protocol_api_old/core/simulator/test_instrument_context.py @@ -1,8 +1,9 @@ """Test instrument context simulation.""" -from typing import Callable +from typing import Callable, cast import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from _pytest.fixtures import SubRequest +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from opentrons.protocol_api.core.common import InstrumentCore, LabwareCore from opentrons.types import Location, Point @@ -23,8 +24,8 @@ lazy_fixture("simulating_instrument_context"), ] ) -def subject(request: pytest.FixtureRequest) -> InstrumentCore: - return request.param # type: ignore[attr-defined, no-any-return] +def subject(request: SubRequest) -> InstrumentCore: + return cast(InstrumentCore, request.param) def test_same_pipette( @@ -269,7 +270,7 @@ def _aspirate_blowout(i: InstrumentCore, labware: LabwareCore) -> None: @pytest.mark.parametrize( argnames=["side_effector"], argvalues=[ - [lambda i, l: None], + [lambda i, l: None], # noqa: E741 [_aspirate], [_aspirate_dispense], [_aspirate_blowout], diff --git a/api/tests/opentrons/protocol_api_old/core/simulator/test_protocol_context.py b/api/tests/opentrons/protocol_api_old/core/simulator/test_protocol_context.py index 4ddfd65ec3e..022ce3e5853 100644 --- a/api/tests/opentrons/protocol_api_old/core/simulator/test_protocol_context.py +++ b/api/tests/opentrons/protocol_api_old/core/simulator/test_protocol_context.py @@ -1,6 +1,8 @@ """Test instrument context simulation.""" +from typing import cast import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from _pytest.fixtures import SubRequest +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from opentrons_shared_data.pipette.dev_types import PipetteNameType @@ -14,8 +16,8 @@ lazy_fixture("simulating_protocol_context"), ] ) -def subject(request: pytest.FixtureRequest) -> ProtocolCore: - return request.param # type: ignore[attr-defined, no-any-return] +def subject(request: SubRequest) -> ProtocolCore: + return cast(ProtocolCore, request.param) @pytest.mark.ot2_only diff --git a/api/tests/opentrons/protocol_api_old/test_context.py b/api/tests/opentrons/protocol_api_old/test_context.py index fcb7004d4bc..bb8b8f6c7ca 100644 --- a/api/tests/opentrons/protocol_api_old/test_context.py +++ b/api/tests/opentrons/protocol_api_old/test_context.py @@ -876,46 +876,47 @@ def fake_execute_transfer(xfer_plan): def test_flow_rate(ctx, monkeypatch): - old_sfm = ctx._core.get_hardware() + instr = ctx.load_instrument("p300_single", Mount.RIGHT) + old_sfm = instr._core.set_flow_rate - def pass_on(mount, aspirate=None, dispense=None, blow_out=None): - old_sfm(mount, aspirate=None, dispense=None, blow_out=None) + def pass_on(aspirate=None, dispense=None, blow_out=None): + old_sfm(aspirate=aspirate, dispense=dispense, blow_out=blow_out) set_flow_rate = mock.Mock(side_effect=pass_on) - monkeypatch.setattr(ctx._core.get_hardware(), "set_flow_rate", set_flow_rate) - instr = ctx.load_instrument("p300_single", Mount.RIGHT) + monkeypatch.setattr(instr._core, "set_flow_rate", set_flow_rate) ctx.home() instr.flow_rate.aspirate = 1 - assert set_flow_rate.called_once_with(Mount.RIGHT, aspirate=1) + set_flow_rate.assert_called_once_with(aspirate=1) set_flow_rate.reset_mock() instr.flow_rate.dispense = 10 - assert set_flow_rate.called_once_with(Mount.RIGHT, dispense=10) + set_flow_rate.assert_called_once_with(dispense=10) set_flow_rate.reset_mock() instr.flow_rate.blow_out = 2 - assert set_flow_rate.called_once_with(Mount.RIGHT, blow_out=2) + set_flow_rate.assert_called_once_with(blow_out=2) assert instr.flow_rate.aspirate == 1 assert instr.flow_rate.dispense == 10 assert instr.flow_rate.blow_out == 2 def test_pipette_speed(ctx, monkeypatch): - old_sfm = ctx._core.get_hardware() + instr = ctx.load_instrument("p300_single", Mount.RIGHT) + old_sfm = instr._core.set_pipette_speed - def pass_on(mount, aspirate=None, dispense=None, blow_out=None): - old_sfm(aspirate=None, dispense=None, blow_out=None) + def pass_on(aspirate=None, dispense=None, blow_out=None): + old_sfm(aspirate=aspirate, dispense=dispense, blow_out=blow_out) set_speed = mock.Mock(side_effect=pass_on) - monkeypatch.setattr(ctx._core.get_hardware(), "set_pipette_speed", set_speed) - instr = ctx.load_instrument("p300_single", Mount.RIGHT) - + monkeypatch.setattr(instr._core, "set_pipette_speed", set_speed) ctx.home() instr.speed.aspirate = 1 - assert set_speed.called_once_with(Mount.RIGHT, dispense=1) + set_speed.assert_called_once_with(aspirate=1) + set_speed.reset_mock() instr.speed.dispense = 10 + set_speed.assert_called_once_with(dispense=10) + set_speed.reset_mock() instr.speed.blow_out = 2 - assert set_speed.called_with(Mount.RIGHT, dispense=10) - assert set_speed.called_with(Mount.RIGHT, blow_out=2) + set_speed.assert_called_once_with(blow_out=2) assert instr.speed.aspirate == 1 assert instr.speed.dispense == 10 assert instr.speed.blow_out == 2 diff --git a/api/tests/opentrons/protocol_api_old/test_labware.py b/api/tests/opentrons/protocol_api_old/test_labware.py index a245fb5be5f..c72c8a87346 100644 --- a/api/tests/opentrons/protocol_api_old/test_labware.py +++ b/api/tests/opentrons/protocol_api_old/test_labware.py @@ -15,6 +15,7 @@ from opentrons.protocols.api_support.types import APIVersion from opentrons.protocol_api import labware, validation from opentrons.protocol_api.core.labware import AbstractLabware +from opentrons.protocol_api.core.well import AbstractWellCore from opentrons.protocol_api.core.legacy import module_geometry from opentrons.protocol_api.core.legacy.legacy_labware_core import LegacyLabwareCore from opentrons.protocol_api.core.legacy.legacy_well_core import LegacyWellCore @@ -652,7 +653,7 @@ def test_labware_hash_func_diff_implementation_same_version( def test_set_offset(decoy: Decoy) -> None: """It should set the labware's offset using the implementation.""" - labware_impl = decoy.mock(cls=AbstractLabware) + labware_impl: AbstractLabware[AbstractWellCore] = decoy.mock(cls=AbstractLabware) decoy.when(labware_impl.get_well_columns()).then_return([]) subject = labware.Labware( core=labware_impl, diff --git a/api/tests/opentrons/protocol_engine/execution/test_door_watcher.py b/api/tests/opentrons/protocol_engine/execution/test_door_watcher.py index fd326b04920..1e252650957 100644 --- a/api/tests/opentrons/protocol_engine/execution/test_door_watcher.py +++ b/api/tests/opentrons/protocol_engine/execution/test_door_watcher.py @@ -68,7 +68,7 @@ async def test_event_forwarding( ) -> None: """It should forward events that come from a different thread.""" handler_captor = matchers.Captor() - unsubscribe_callback = decoy.mock() + unsubscribe_callback = decoy.mock(name="unsubscribe_callback") decoy.when(hardware_control_api.register_callback(handler_captor)).then_return( unsubscribe_callback ) @@ -104,8 +104,8 @@ async def test_one_subscribe_one_unsubscribe( subject: DoorWatcher, ) -> None: """Multiple start()s and stop()s should be collapsed.""" - unsubscribe = decoy.mock() - wrong_unsubscribe = decoy.mock() + unsubscribe = decoy.mock(name="unsubscribe_callback") + wrong_unsubscribe = decoy.mock(name="wrong_unsubscribe") decoy.when(hardware_control_api.register_callback(matchers.Anything())).then_return( unsubscribe, wrong_unsubscribe diff --git a/api/tests/opentrons/protocol_engine/execution/test_labware_movement_handler.py b/api/tests/opentrons/protocol_engine/execution/test_labware_movement_handler.py index 23126e3f99e..58619647f54 100644 --- a/api/tests/opentrons/protocol_engine/execution/test_labware_movement_handler.py +++ b/api/tests/opentrons/protocol_engine/execution/test_labware_movement_handler.py @@ -195,7 +195,7 @@ async def test_raise_error_if_gripper_pickup_failed( starting_location = DeckSlotLocation(slotName=DeckSlotName.SLOT_1) to_location = DeckSlotLocation(slotName=DeckSlotName.SLOT_2) - mock_tc_context_manager = decoy.mock() + mock_tc_context_manager = decoy.mock(name="mock_tc_context_manager") decoy.when( thermocycler_plate_lifter.lift_plate_for_labware_movement( labware_location=starting_location @@ -343,7 +343,7 @@ async def test_move_labware_with_gripper( labware_id="my-teleporting-labware", location=to_location ) ).then_return(Point(201, 202, 219.5)) - mock_tc_context_manager = decoy.mock() + mock_tc_context_manager = decoy.mock(name="mock_tc_context_manager") decoy.when( thermocycler_plate_lifter.lift_plate_for_labware_movement( labware_location=from_location diff --git a/api/tests/opentrons/protocol_engine/resources/test_deck_configuration_provider.py b/api/tests/opentrons/protocol_engine/resources/test_deck_configuration_provider.py index 68c856c6024..8071cc98a66 100644 --- a/api/tests/opentrons/protocol_engine/resources/test_deck_configuration_provider.py +++ b/api/tests/opentrons/protocol_engine/resources/test_deck_configuration_provider.py @@ -2,7 +2,7 @@ from typing import List, Set import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from opentrons_shared_data.deck import load as load_deck from opentrons_shared_data.deck.dev_types import DeckDefinitionV4 diff --git a/api/tests/opentrons/protocol_engine/resources/test_deck_data_provider.py b/api/tests/opentrons/protocol_engine/resources/test_deck_data_provider.py index 2e01abb3119..f587d7ce5dd 100644 --- a/api/tests/opentrons/protocol_engine/resources/test_deck_data_provider.py +++ b/api/tests/opentrons/protocol_engine/resources/test_deck_data_provider.py @@ -1,6 +1,6 @@ """Test deck data provider.""" import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from decoy import Decoy from opentrons_shared_data.deck.dev_types import DeckDefinitionV4 diff --git a/api/tests/opentrons/protocol_engine/state/test_command_view.py b/api/tests/opentrons/protocol_engine/state/test_command_view.py index 985ae5050f9..46f431e8c63 100644 --- a/api/tests/opentrons/protocol_engine/state/test_command_view.py +++ b/api/tests/opentrons/protocol_engine/state/test_command_view.py @@ -463,7 +463,7 @@ def test_validate_action_allowed( """It should validate allowed play/pause/stop actions.""" expectation = pytest.raises(expected_error) if expected_error else does_not_raise() - with expectation: # type: ignore[attr-defined] + with expectation: result = subject.validate_action_allowed(action) if expected_error is None: diff --git a/api/tests/opentrons/protocol_engine/state/test_module_store.py b/api/tests/opentrons/protocol_engine/state/test_module_store.py index ffeca3dba2c..ff7a75859e9 100644 --- a/api/tests/opentrons/protocol_engine/state/test_module_store.py +++ b/api/tests/opentrons/protocol_engine/state/test_module_store.py @@ -1,6 +1,6 @@ """Module state store tests.""" import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from opentrons.types import DeckSlotName from opentrons.protocol_engine import commands, actions diff --git a/api/tests/opentrons/protocol_engine/state/test_module_view.py b/api/tests/opentrons/protocol_engine/state/test_module_view.py index 586423a0d86..c93d3fdbdc7 100644 --- a/api/tests/opentrons/protocol_engine/state/test_module_view.py +++ b/api/tests/opentrons/protocol_engine/state/test_module_view.py @@ -1,7 +1,7 @@ """Tests for module state accessors in the protocol engine state store.""" import pytest from math import isclose -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from contextlib import nullcontext as does_not_raise from typing import ContextManager, Dict, NamedTuple, Optional, Type, Union, Any diff --git a/api/tests/opentrons/protocol_engine/state/test_state_store.py b/api/tests/opentrons/protocol_engine/state/test_state_store.py index 41148eb006c..dd32bbec591 100644 --- a/api/tests/opentrons/protocol_engine/state/test_state_store.py +++ b/api/tests/opentrons/protocol_engine/state/test_state_store.py @@ -86,7 +86,7 @@ async def test_wait_for_state( subject: StateStore, ) -> None: """It should return an awaitable that signals state changes.""" - check_condition: Callable[..., Optional[str]] = decoy.mock() + check_condition: Callable[..., Optional[str]] = decoy.mock(name="check_condition") decoy.when(check_condition("foo", bar="baz")).then_return( None, @@ -106,7 +106,7 @@ async def test_wait_for_state_short_circuit( change_notifier: ChangeNotifier, ) -> None: """It should short-circuit the change notifier if condition is satisfied.""" - check_condition: Callable[..., Optional[str]] = decoy.mock() + check_condition: Callable[..., Optional[str]] = decoy.mock(name="check_condition") decoy.when(check_condition("foo", bar="baz")).then_return("hello world") @@ -118,14 +118,14 @@ async def test_wait_for_state_short_circuit( async def test_wait_for_already_true(decoy: Decoy, subject: StateStore) -> None: """It should signal immediately if condition is already met.""" - check_condition = decoy.mock() + check_condition = decoy.mock(name="check_condition") decoy.when(check_condition()).then_return(True) await subject.wait_for(check_condition) async def test_wait_for_raises(decoy: Decoy, subject: StateStore) -> None: """It should raise if the condition function raises.""" - check_condition = decoy.mock() + check_condition = decoy.mock(name="check_condition") decoy.when(check_condition()).then_raise(ValueError("oh no")) diff --git a/api/tests/opentrons/protocol_engine/test_create_protocol_engine.py b/api/tests/opentrons/protocol_engine/test_create_protocol_engine.py index c099b0c4521..b509946de75 100644 --- a/api/tests/opentrons/protocol_engine/test_create_protocol_engine.py +++ b/api/tests/opentrons/protocol_engine/test_create_protocol_engine.py @@ -1,6 +1,6 @@ """Smoke tests for the ProtocolEngine creation factory.""" import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from opentrons_shared_data.deck.dev_types import DeckDefinitionV4 from opentrons_shared_data.robot.dev_types import RobotType diff --git a/api/tests/opentrons/protocol_reader/_input_file.py b/api/tests/opentrons/protocol_reader/_input_file.py index 85939ecc0bc..d28d994f981 100644 --- a/api/tests/opentrons/protocol_reader/_input_file.py +++ b/api/tests/opentrons/protocol_reader/_input_file.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from io import BytesIO -from typing import IO +from typing import BinaryIO from opentrons.protocol_reader import AbstractInputFile @@ -12,7 +12,7 @@ class InputFile(AbstractInputFile): """An implementation of AbstractInputFile to use for test input.""" filename: str - file: IO[bytes] + file: BinaryIO @classmethod def make(cls, filename: str, contents: bytes) -> InputFile: diff --git a/api/tests/opentrons/protocol_runner/test_legacy_context_plugin.py b/api/tests/opentrons/protocol_runner/test_legacy_context_plugin.py index ac9a46112ff..e86f959ff2e 100644 --- a/api/tests/opentrons/protocol_runner/test_legacy_context_plugin.py +++ b/api/tests/opentrons/protocol_runner/test_legacy_context_plugin.py @@ -93,7 +93,9 @@ async def test_broker_subscribe_unsubscribe( subject: LegacyContextPlugin, ) -> None: """It should subscribe to the brokers on setup and unsubscribe on teardown.""" - command_broker_unsubscribe: Callable[[], None] = decoy.mock() + command_broker_unsubscribe: Callable[[], None] = decoy.mock( + name="command_broker_unsubscribe" + ) equipment_broker_subscription_context = decoy.mock(cls=_ContextManager) decoy.when( @@ -132,7 +134,7 @@ async def test_command_broker_messages( command_handler_captor = matchers.Captor() decoy.when( mock_legacy_broker.subscribe(topic="command", handler=command_handler_captor) - ).then_return(decoy.mock()) + ).then_return(decoy.mock(name="command_broker_unsubscribe")) decoy.when( mock_equipment_broker.subscribed(callback=matchers.Anything()) ).then_enter_with(None) @@ -185,7 +187,7 @@ async def test_equipment_broker_messages( labware_handler_captor = matchers.Captor() decoy.when( mock_legacy_broker.subscribe(topic="command", handler=matchers.Anything()) - ).then_return(decoy.mock()) + ).then_return(decoy.mock(name="command_broker_unsubscribe")) decoy.when( mock_equipment_broker.subscribed(callback=labware_handler_captor) ).then_enter_with(None) diff --git a/api/tests/opentrons/protocol_runner/test_protocol_runner.py b/api/tests/opentrons/protocol_runner/test_protocol_runner.py index 0e4f4ec31ca..1a37c05b82a 100644 --- a/api/tests/opentrons/protocol_runner/test_protocol_runner.py +++ b/api/tests/opentrons/protocol_runner/test_protocol_runner.py @@ -1,6 +1,6 @@ """Tests for the PythonAndLegacyRunner, JsonRunner & LiveRunner classes.""" import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from decoy import Decoy, matchers from pathlib import Path from typing import List, cast, Optional, Union, Type diff --git a/api/tests/opentrons/protocol_runner/test_task_queue.py b/api/tests/opentrons/protocol_runner/test_task_queue.py index 92cd5f52765..6bf5cb90c7a 100644 --- a/api/tests/opentrons/protocol_runner/test_task_queue.py +++ b/api/tests/opentrons/protocol_runner/test_task_queue.py @@ -6,8 +6,8 @@ async def test_set_run_func(decoy: Decoy) -> None: """It should be able to add a task for the "run" phase.""" - run_func = decoy.mock(is_async=True) - cleanup_func = decoy.mock(is_async=True) + run_func = decoy.mock(name="run_func", is_async=True) + cleanup_func = decoy.mock(name="cleanup_func", is_async=True) subject = TaskQueue() # cleanup_func=cleanup_func) subject.set_cleanup_func(func=cleanup_func) @@ -23,8 +23,8 @@ async def test_set_run_func(decoy: Decoy) -> None: async def test_passes_args(decoy: Decoy) -> None: """It should pass kwargs to the run phase function.""" - run_func = decoy.mock(is_async=True) - cleanup_func = decoy.mock(is_async=True) + run_func = decoy.mock(name="run_func", is_async=True) + cleanup_func = decoy.mock(name="cleanup_func", is_async=True) subject = TaskQueue() # cleanup_func=cleanup_func) subject.set_cleanup_func(func=cleanup_func) @@ -37,8 +37,8 @@ async def test_passes_args(decoy: Decoy) -> None: async def test_cleanup_gets_run_error(decoy: Decoy) -> None: """It should verify "cleanup" func gets error raised in "run" func.""" - run_func = decoy.mock(is_async=True) - cleanup_func = decoy.mock(is_async=True) + run_func = decoy.mock(name="run_func", is_async=True) + cleanup_func = decoy.mock(name="cleanup_func", is_async=True) error = RuntimeError("Oh no!") decoy.when(await run_func()).then_raise(error) @@ -54,7 +54,7 @@ async def test_cleanup_gets_run_error(decoy: Decoy) -> None: async def test_join_waits_for_start(decoy: Decoy) -> None: """It should wait until the queue is started when join is called.""" - cleanup_func = decoy.mock(is_async=True) + cleanup_func = decoy.mock(name="cleanup_func", is_async=True) subject = TaskQueue() # cleanup_func=cleanup_func) subject.set_cleanup_func(func=cleanup_func) join_task = asyncio.create_task(subject.join()) @@ -68,8 +68,8 @@ async def test_join_waits_for_start(decoy: Decoy) -> None: async def test_start_runs_stuff_once(decoy: Decoy) -> None: """Calling `start` should no-op if already started.""" - run_func = decoy.mock(is_async=True) - cleanup_func = decoy.mock(is_async=True) + run_func = decoy.mock(name="run_func", is_async=True) + cleanup_func = decoy.mock(name="cleanup_func", is_async=True) subject = TaskQueue() # leanup_func=cleanup_func) subject.set_cleanup_func(func=cleanup_func) diff --git a/api/tests/opentrons/test_execute.py b/api/tests/opentrons/test_execute.py index 71dd37a0bea..77563083337 100644 --- a/api/tests/opentrons/test_execute.py +++ b/api/tests/opentrons/test_execute.py @@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Any, Callable, Generator, List, TextIO, cast import pytest +from _pytest.fixtures import SubRequest from opentrons_shared_data import get_shared_data_root, load_shared_data from opentrons_shared_data.pipette.dev_types import PipetteModel @@ -31,13 +32,13 @@ @pytest.fixture(params=[APIVersion(2, 0), ENGINE_CORE_API_VERSION]) -def api_version(request: pytest.FixtureRequest) -> APIVersion: +def api_version(request: SubRequest) -> APIVersion: """Return an API version to test with. Newer API versions execute through Protocol Engine, and older API versions don't. The two codepaths are very different, so we need to test them both. """ - return request.param # type: ignore[attr-defined,no-any-return] + return cast(APIVersion, request.param) @pytest.fixture diff --git a/api/tests/opentrons/test_simulate.py b/api/tests/opentrons/test_simulate.py index 598d46bba0e..b4a51838cce 100644 --- a/api/tests/opentrons/test_simulate.py +++ b/api/tests/opentrons/test_simulate.py @@ -8,6 +8,7 @@ from typing import TYPE_CHECKING, Callable, Generator, List, TextIO, cast import pytest +from _pytest.fixtures import SubRequest from opentrons_shared_data import get_shared_data_root, load_shared_data @@ -26,13 +27,13 @@ @pytest.fixture(params=[APIVersion(2, 0), ENGINE_CORE_API_VERSION]) -def api_version(request: pytest.FixtureRequest) -> APIVersion: +def api_version(request: SubRequest) -> APIVersion: """Return an API version to test with. Newer API versions execute through Protocol Engine, and older API versions don't. The two codepaths are very different, so we need to test them both. """ - return request.param # type: ignore[attr-defined,no-any-return] + return cast(APIVersion, request.param) @pytest.mark.parametrize( diff --git a/api/tests/opentrons/util/test_async_helpers.py b/api/tests/opentrons/util/test_async_helpers.py index 14f9e1a0436..d33293eb75e 100644 --- a/api/tests/opentrons/util/test_async_helpers.py +++ b/api/tests/opentrons/util/test_async_helpers.py @@ -85,7 +85,7 @@ async def __aexit__( ).result() # The loop should be closed and unusable now that the context manager has exited. - assert loop_in_thread.is_closed + assert loop_in_thread.is_closed() with pytest.raises(RuntimeError, match="Event loop is closed"): loop_in_thread.call_soon_threadsafe(lambda: None) diff --git a/api/tests/opentrons/util/test_linal.py b/api/tests/opentrons/util/test_linal.py index 38c5cf8e2d3..5c186d20903 100755 --- a/api/tests/opentrons/util/test_linal.py +++ b/api/tests/opentrons/util/test_linal.py @@ -2,6 +2,7 @@ from opentrons.util.linal import solve, add_z, apply_transform, solve_attitude from numpy.linalg import inv import numpy as np +from numpy.typing import NDArray def test_solve() -> None: @@ -22,7 +23,7 @@ def test_solve() -> None: X = solve(expected, actual) - expected2 = np.array( + expected2: NDArray[np.double] = np.array( [cos(theta + pi / 2) * scale + 0.5, sin(theta + pi / 2) * scale + 0.25, 1] ) result = np.dot(X, np.array([[0], [1], [1]])).transpose() @@ -35,9 +36,11 @@ def test_add_z() -> None: y = 10 z = 20 - xy_array = np.array([[1, 0, x], [0, 1, y], [0, 0, 1]]) + xy_array: NDArray[np.double] = np.array([[1, 0, x], [0, 1, y], [0, 0, 1]]) - expected = np.array([[1, 0, 0, x], [0, 1, 0, y], [0, 0, 1, z], [0, 0, 0, 1]]) + expected: NDArray[np.double] = np.array( + [[1, 0, 0, x], [0, 1, 0, y], [0, 0, 1, z], [0, 0, 0, 1]] + ) result = add_z(xy_array, z) assert (result == expected).all() diff --git a/g-code-testing/Pipfile b/g-code-testing/Pipfile index 2e6b4a1720b..80f83a4561a 100644 --- a/g-code-testing/Pipfile +++ b/g-code-testing/Pipfile @@ -10,26 +10,27 @@ server-utils = { editable = true, path = "./../server-utils" } opentrons-shared-data = { editable = true, path = "../shared-data/python" } opentrons_hardware = { editable = true, path = "../hardware" } g-code-testing = { editable = true, path = "." } -anyio = "==3.6.1" -pydantic = "==1.9.2" +anyio = "==3.7.1" +pydantic = "==1.10.12" # opentrons dependency on linux, spec'd here to force lockfile inclusion # https://github.com/pypa/pipenv/issues/4408#issuecomment-668324177 systemd-python = { version = "==234", markers="sys_platform=='linux'" } [dev-packages] -diff-match-patch = "==20200713" -pytest = "~=7.1" -pytest-aiohttp = "==0.3.0" -pytest-cov = "==2.10.1" +diff-match-patch = "==20230430" +pytest = "~=7.4.4" +pytest-aiohttp = "==1.0.5" +pytest-cov = "==4.1.0" pytest-xdist = "~=2.5.0" -mock = "~=4.0.3" -mypy = "==0.981" -flake8 = "~=3.9.0" -flake8-annotations = "~=2.6.2" -flake8-docstrings = "~=1.6.0" -flake8-noqa = "~=1.2.1" +mock = "~=5.1.0" +types-mock = "~=5.1.0" +mypy = "==1.8.0" +flake8 = "~=7.0.0" +flake8-annotations = "~=3.0.1" +flake8-docstrings = "~=1.7.0" +flake8-noqa = "~=1.4.0" black = "==22.3.0" -decoy = "~=1.10.0" +decoy = "~=2.1.1" [requires] python_version = "3.10" diff --git a/g-code-testing/Pipfile.lock b/g-code-testing/Pipfile.lock index c2277bd2000..ad7aa98a701 100644 --- a/g-code-testing/Pipfile.lock +++ b/g-code-testing/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "7154f080cb358736d8d99282591f1d23e5614eeae4e3c2a076f0b0b0dd6dff60" + "sha256": "2454d48b1b831db24fb96b42516e1ac204d98ea0ed929307858ee32ac793fb20" }, "pipfile-spec": 6, "requires": { @@ -25,28 +25,20 @@ }, "aiosqlite": { "hashes": [ - "sha256:6c49dc6d3405929b1d08eeccc72306d3677503cc5e5e43771efc1e00232e8231", - "sha256:f0e6acc24bc4864149267ac82fb46dfb3be4455f99fe21df82609cc6e6baee51" + "sha256:95ee77b91c8d2808bd08a59fbebf66270e9090c3d92ffbf260dc0db0b979577d", + "sha256:edba222e03453e094a3ce605db1b970c4b3376264e56f32e2a4959f948d66a96" ], - "markers": "python_version >= '3.6'", - "version": "==0.17.0" + "markers": "python_version >= '3.7'", + "version": "==0.19.0" }, "anyio": { "hashes": [ - "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b", - "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be" + "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780", + "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5" ], "index": "pypi", - "markers": "python_full_version >= '3.6.2'", - "version": "==3.6.1" - }, - "asgiref": { - "hashes": [ - "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e", - "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed" - ], "markers": "python_version >= '3.7'", - "version": "==3.7.2" + "version": "==3.7.1" }, "attrs": { "hashes": [ @@ -64,13 +56,21 @@ "markers": "python_version >= '3.7'", "version": "==8.1.7" }, + "exceptiongroup": { + "hashes": [ + "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", + "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + ], + "markers": "python_version < '3.11'", + "version": "==1.2.0" + }, "fastapi": { "hashes": [ - "sha256:644bb815bae326575c4b2842469fb83053a4b974b82fa792ff9283d17fbbd99d", - "sha256:94d2820906c36b9b8303796fb7271337ec89c74223229e3cfcf056b5a7d59e23" + "sha256:976df7bab51ac7beda9f68c4513b8c4490b5c1135c72aafd0a5ee4023ec5282e", + "sha256:ac78f717cd80d657bd183f94d33b9bda84aa376a46a9dab513586b8eef1dc6fc" ], - "markers": "python_version >= '3.6'", - "version": "==0.68.1" + "markers": "python_version >= '3.7'", + "version": "==0.99.1" }, "g-code-testing": { "editable": true, @@ -94,10 +94,11 @@ }, "jsonschema": { "hashes": [ - "sha256:5f9c0a719ca2ce14c5de2fd350a64fd2d13e8539db29836a86adc990bb1a068f", - "sha256:8d4a2b7b6c2237e0199c8ea1a6d3e05bf118e289ae2b9d7ba444182a2959560d" + "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d", + "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6" ], - "version": "==3.0.2" + "markers": "python_version >= '3.7'", + "version": "==4.17.3" }, "numpy": { "hashes": [ @@ -163,45 +164,46 @@ }, "pydantic": { "hashes": [ - "sha256:1061c6ee6204f4f5a27133126854948e3b3d51fcc16ead2e5d04378c199b2f44", - "sha256:19b5686387ea0d1ea52ecc4cffb71abb21702c5e5b2ac626fd4dbaa0834aa49d", - "sha256:2bd446bdb7755c3a94e56d7bdfd3ee92396070efa8ef3a34fab9579fe6aa1d84", - "sha256:328558c9f2eed77bd8fffad3cef39dbbe3edc7044517f4625a769d45d4cf7555", - "sha256:32e0b4fb13ad4db4058a7c3c80e2569adbd810c25e6ca3bbd8b2a9cc2cc871d7", - "sha256:3ee0d69b2a5b341fc7927e92cae7ddcfd95e624dfc4870b32a85568bd65e6131", - "sha256:4aafd4e55e8ad5bd1b19572ea2df546ccace7945853832bb99422a79c70ce9b8", - "sha256:4b3946f87e5cef3ba2e7bd3a4eb5a20385fe36521d6cc1ebf3c08a6697c6cfb3", - "sha256:4de71c718c9756d679420c69f216776c2e977459f77e8f679a4a961dc7304a56", - "sha256:5565a49effe38d51882cb7bac18bda013cdb34d80ac336428e8908f0b72499b0", - "sha256:5803ad846cdd1ed0d97eb00292b870c29c1f03732a010e66908ff48a762f20e4", - "sha256:5da164119602212a3fe7e3bc08911a89db4710ae51444b4224c2382fd09ad453", - "sha256:615661bfc37e82ac677543704437ff737418e4ea04bef9cf11c6d27346606044", - "sha256:78a4d6bdfd116a559aeec9a4cfe77dda62acc6233f8b56a716edad2651023e5e", - "sha256:7d0f183b305629765910eaad707800d2f47c6ac5bcfb8c6397abdc30b69eeb15", - "sha256:7ead3cd020d526f75b4188e0a8d71c0dbbe1b4b6b5dc0ea775a93aca16256aeb", - "sha256:84d76ecc908d917f4684b354a39fd885d69dd0491be175f3465fe4b59811c001", - "sha256:8cb0bc509bfb71305d7a59d00163d5f9fc4530f0881ea32c74ff4f74c85f3d3d", - "sha256:91089b2e281713f3893cd01d8e576771cd5bfdfbff5d0ed95969f47ef6d676c3", - "sha256:9c9e04a6cdb7a363d7cb3ccf0efea51e0abb48e180c0d31dca8d247967d85c6e", - "sha256:a8c5360a0297a713b4123608a7909e6869e1b56d0e96eb0d792c27585d40757f", - "sha256:afacf6d2a41ed91fc631bade88b1d319c51ab5418870802cedb590b709c5ae3c", - "sha256:b34ba24f3e2d0b39b43f0ca62008f7ba962cff51efa56e64ee25c4af6eed987b", - "sha256:bd67cb2c2d9602ad159389c29e4ca964b86fa2f35c2faef54c3eb28b4efd36c8", - "sha256:c0f5e142ef8217019e3eef6ae1b6b55f09a7a15972958d44fbd228214cede567", - "sha256:cdb4272678db803ddf94caa4f94f8672e9a46bae4a44f167095e4d06fec12979", - "sha256:d70916235d478404a3fa8c997b003b5f33aeac4686ac1baa767234a0f8ac2326", - "sha256:d8ce3fb0841763a89322ea0432f1f59a2d3feae07a63ea2c958b2315e1ae8adb", - "sha256:e0b214e57623a535936005797567231a12d0da0c29711eb3514bc2b3cd008d0f", - "sha256:e631c70c9280e3129f071635b81207cad85e6c08e253539467e4ead0e5b219aa", - "sha256:e78578f0c7481c850d1c969aca9a65405887003484d24f6110458fb02cca7747", - "sha256:f0ca86b525264daa5f6b192f216a0d1e860b7383e3da1c65a1908f9c02f42801", - "sha256:f1a68f4f65a9ee64b6ccccb5bf7e17db07caebd2730109cb8a95863cfa9c4e55", - "sha256:fafe841be1103f340a24977f61dee76172e4ae5f647ab9e7fd1e1fca51524f08", - "sha256:ff68fc85355532ea77559ede81f35fff79a6a5543477e168ab3a381887caea76" + "sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303", + "sha256:1289c180abd4bd4555bb927c42ee42abc3aee02b0fb2d1223fb7c6e5bef87dbe", + "sha256:1eb2085c13bce1612da8537b2d90f549c8cbb05c67e8f22854e201bde5d98a47", + "sha256:2031de0967c279df0d8a1c72b4ffc411ecd06bac607a212892757db7462fc494", + "sha256:2a7bac939fa326db1ab741c9d7f44c565a1d1e80908b3797f7f81a4f86bc8d33", + "sha256:2d5a58feb9a39f481eda4d5ca220aa8b9d4f21a41274760b9bc66bfd72595b86", + "sha256:2f9a6fab5f82ada41d56b0602606a5506aab165ca54e52bc4545028382ef1c5d", + "sha256:2fcfb5296d7877af406ba1547dfde9943b1256d8928732267e2653c26938cd9c", + "sha256:549a8e3d81df0a85226963611950b12d2d334f214436a19537b2efed61b7639a", + "sha256:598da88dfa127b666852bef6d0d796573a8cf5009ffd62104094a4fe39599565", + "sha256:5d1197e462e0364906cbc19681605cb7c036f2475c899b6f296104ad42b9f5fb", + "sha256:69328e15cfda2c392da4e713443c7dbffa1505bc9d566e71e55abe14c97ddc62", + "sha256:6a9dfa722316f4acf4460afdf5d41d5246a80e249c7ff475c43a3a1e9d75cf62", + "sha256:6b30bcb8cbfccfcf02acb8f1a261143fab622831d9c0989707e0e659f77a18e0", + "sha256:6c076be61cd0177a8433c0adcb03475baf4ee91edf5a4e550161ad57fc90f523", + "sha256:771735dc43cf8383959dc9b90aa281f0b6092321ca98677c5fb6125a6f56d58d", + "sha256:795e34e6cc065f8f498c89b894a3c6da294a936ee71e644e4bd44de048af1405", + "sha256:87afda5539d5140cb8ba9e8b8c8865cb5b1463924d38490d73d3ccfd80896b3f", + "sha256:8fb2aa3ab3728d950bcc885a2e9eff6c8fc40bc0b7bb434e555c215491bcf48b", + "sha256:a1fcb59f2f355ec350073af41d927bf83a63b50e640f4dbaa01053a28b7a7718", + "sha256:a5e7add47a5b5a40c49b3036d464e3c7802f8ae0d1e66035ea16aa5b7a3923ed", + "sha256:a73f489aebd0c2121ed974054cb2759af8a9f747de120acd2c3394cf84176ccb", + "sha256:ab26038b8375581dc832a63c948f261ae0aa21f1d34c1293469f135fa92972a5", + "sha256:b0d191db0f92dfcb1dec210ca244fdae5cbe918c6050b342d619c09d31eea0cc", + "sha256:b749a43aa51e32839c9d71dc67eb1e4221bb04af1033a32e3923d46f9effa942", + "sha256:b7ccf02d7eb340b216ec33e53a3a629856afe1c6e0ef91d84a4e6f2fb2ca70fe", + "sha256:ba5b2e6fe6ca2b7e013398bc7d7b170e21cce322d266ffcd57cca313e54fb246", + "sha256:ba5c4a8552bff16c61882db58544116d021d0b31ee7c66958d14cf386a5b5350", + "sha256:c79e6a11a07da7374f46970410b41d5e266f7f38f6a17a9c4823db80dadf4303", + "sha256:ca48477862372ac3770969b9d75f1bf66131d386dba79506c46d75e6b48c1e09", + "sha256:dea7adcc33d5d105896401a1f37d56b47d443a2b2605ff8a969a0ed5543f7e33", + "sha256:e0a16d274b588767602b7646fa05af2782576a6cf1022f4ba74cbb4db66f6ca8", + "sha256:e4129b528c6baa99a429f97ce733fff478ec955513630e61b49804b6cf9b224a", + "sha256:e5f805d2d5d0a41633651a73fa4ecdd0b3d7a49de4ec3fadf062fe16501ddbf1", + "sha256:ef6c96b2baa2100ec91a4b428f80d8f28a3c9e53568219b6c298c1125572ebc6", + "sha256:fdbdd1d630195689f325c9ef1a12900524dceb503b00a987663ff4f58669b93d" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1'", - "version": "==1.9.2" + "markers": "python_version >= '3.7'", + "version": "==1.10.12" }, "pyrsistent": { "hashes": [ @@ -250,17 +252,19 @@ }, "python-dotenv": { "hashes": [ - "sha256:aae25dc1ebe97c420f50b81fb0e5c949659af713f31fdb63c749ca68748f34b1", - "sha256:f521bc2ac9a8e03c736f62911605c5d83970021e3fa95b37d769e2bbbe9b6172" + "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", + "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a" ], - "markers": "python_version >= '3.5'", - "version": "==0.19.0" + "markers": "python_version >= '3.8'", + "version": "==1.0.1" }, "python-multipart": { "hashes": [ - "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43" + "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132", + "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18" ], - "version": "==0.0.5" + "markers": "python_version >= '3.7'", + "version": "==0.0.6" }, "robot-server": { "editable": true, @@ -270,22 +274,6 @@ "editable": true, "path": "./../server-utils" }, - "setuptools": { - "hashes": [ - "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05", - "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78" - ], - "markers": "python_version >= '3.8'", - "version": "==69.0.3" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, "sniffio": { "hashes": [ "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", @@ -296,52 +284,63 @@ }, "sqlalchemy": { "hashes": [ - "sha256:04164e0063feb7aedd9d073db0fd496edb244be40d46ea1f0d8990815e4b8c34", - "sha256:159c2f69dd6efd28e894f261ffca1100690f28210f34cfcd70b895e0ea7a64f3", - "sha256:199dc6d0068753b6a8c0bd3aceb86a3e782df118260ebc1fa981ea31ee054674", - "sha256:1bbac3e8293b34c4403d297e21e8f10d2a57756b75cff101dc62186adec725f5", - "sha256:20e9eba7fd86ef52e0df25bea83b8b518dfdf0bce09b336cfe51671f52aaaa3f", - "sha256:290cbdf19129ae520d4bdce392648c6fcdbee763bc8f750b53a5ab51880cb9c9", - "sha256:316270e5867566376e69a0ac738b863d41396e2b63274616817e1d34156dff0e", - "sha256:3f88a4ee192142eeed3fe173f673ea6ab1f5a863810a9d85dbf6c67a9bd08f97", - "sha256:4aa96e957141006181ca58e792e900ee511085b8dae06c2d08c00f108280fb8a", - "sha256:4b2bcab3a914715d332ca783e9bda13bc570d8b9ef087563210ba63082c18c16", - "sha256:576684771456d02e24078047c2567025f2011977aa342063468577d94e194b00", - "sha256:5a2e73508f939175363d8a4be9dcdc84cf16a92578d7fa86e6e4ca0e6b3667b2", - "sha256:5ba59761c19b800bc2e1c9324da04d35ef51e4ee9621ff37534bc2290d258f71", - "sha256:5dc9801ae9884e822ba942ca493642fb50f049c06b6dbe3178691fce48ceb089", - "sha256:6fdd2dc5931daab778c2b65b03df6ae68376e028a3098eb624d0909d999885bc", - "sha256:708973b5d9e1e441188124aaf13c121e5b03b6054c2df59b32219175a25aa13e", - "sha256:7ff72b3cc9242d1a1c9b84bd945907bf174d74fc2519efe6184d6390a8df478b", - "sha256:8679f9aba5ac22e7bce54ccd8a77641d3aea3e2d96e73e4356c887ebf8ff1082", - "sha256:8b9a395122770a6f08ebfd0321546d7379f43505882c7419d7886856a07caa13", - "sha256:8e1e5d96b744a4f91163290b01045430f3f32579e46d87282449e5b14d27d4ac", - "sha256:9a0195af6b9050c9322a97cf07514f66fe511968e623ca87b2df5e3cf6349615", - "sha256:9cb5698c896fa72f88e7ef04ef62572faf56809093180771d9be8d9f2e264a13", - "sha256:b3f1d9b3aa09ab9adc7f8c4b40fc3e081eb903054c9a6f9ae1633fe15ae503b4", - "sha256:bb42f9b259c33662c6a9b866012f6908a91731a419e69304e1261ba3ab87b8d1", - "sha256:bca714d831e5b8860c3ab134c93aec63d1a4f493bed20084f54e3ce9f0a3bf99", - "sha256:bedd89c34ab62565d44745212814e4b57ef1c24ad4af9b29c504ce40f0dc6558", - "sha256:bfec934aac7f9fa95fc82147a4ba5db0a8bdc4ebf1e33b585ab8860beb10232f", - "sha256:c7046f7aa2db445daccc8424f50b47a66c4039c9f058246b43796aa818f8b751", - "sha256:d7e483f4791fbda60e23926b098702340504f7684ce7e1fd2c1bf02029288423", - "sha256:dd93162615870c976dba43963a24bb418b28448fef584f30755990c134a06a55", - "sha256:e4607d2d16330757818c9d6fba322c2e80b4b112ff24295d1343a80b876eb0ed", - "sha256:e9a680d9665f88346ed339888781f5236347933906c5a56348abb8261282ec48", - "sha256:edfcf93fd92e2f9eef640b3a7a40db20fe3c1d7c2c74faa41424c63dead61b76", - "sha256:f7e4a3c0c3c596296b37f8427c467c8e4336dc8d50f8ed38042e8ba79507b2c9", - "sha256:fff677fa4522dafb5a5e2c0cf909790d5d367326321aeabc0dffc9047cb235bd" + "sha256:0525c4905b4b52d8ccc3c203c9d7ab2a80329ffa077d4bacf31aefda7604dc65", + "sha256:0535d5b57d014d06ceeaeffd816bb3a6e2dddeb670222570b8c4953e2d2ea678", + "sha256:0892e7ac8bc76da499ad3ee8de8da4d7905a3110b952e2a35a940dab1ffa550e", + "sha256:0d661cff58c91726c601cc0ee626bf167b20cc4d7941c93c5f3ac28dc34ddbea", + "sha256:1980e6eb6c9be49ea8f89889989127daafc43f0b1b6843d71efab1514973cca0", + "sha256:1a09d5bd1a40d76ad90e5570530e082ddc000e1d92de495746f6257dc08f166b", + "sha256:245c67c88e63f1523e9216cad6ba3107dea2d3ee19adc359597a628afcabfbcb", + "sha256:2ad16880ccd971ac8e570550fbdef1385e094b022d6fc85ef3ce7df400dddad3", + "sha256:2be4e6294c53f2ec8ea36486b56390e3bcaa052bf3a9a47005687ccf376745d1", + "sha256:2c55040d8ea65414de7c47f1a23823cd9f3fad0dc93e6b6b728fee81230f817b", + "sha256:352df882088a55293f621328ec33b6ffca936ad7f23013b22520542e1ab6ad1b", + "sha256:3823dda635988e6744d4417e13f2e2b5fe76c4bf29dd67e95f98717e1b094cad", + "sha256:38ef80328e3fee2be0a1abe3fe9445d3a2e52a1282ba342d0dab6edf1fef4707", + "sha256:39b02b645632c5fe46b8dd30755682f629ffbb62ff317ecc14c998c21b2896ff", + "sha256:3b0cd89a7bd03f57ae58263d0f828a072d1b440c8c2949f38f3b446148321171", + "sha256:3ec7a0ed9b32afdf337172678a4a0e6419775ba4e649b66f49415615fa47efbd", + "sha256:3f0ef620ecbab46e81035cf3dedfb412a7da35340500ba470f9ce43a1e6c423b", + "sha256:50e074aea505f4427151c286955ea025f51752fa42f9939749336672e0674c81", + "sha256:55e699466106d09f028ab78d3c2e1f621b5ef2c8694598242259e4515715da7c", + "sha256:5e180fff133d21a800c4f050733d59340f40d42364fcb9d14f6a67764bdc48d2", + "sha256:6cacc0b2dd7d22a918a9642fc89840a5d3cee18a0e1fe41080b1141b23b10916", + "sha256:7af40425ac535cbda129d9915edcaa002afe35d84609fd3b9d6a8c46732e02ee", + "sha256:7d8139ca0b9f93890ab899da678816518af74312bb8cd71fb721436a93a93298", + "sha256:7deeae5071930abb3669b5185abb6c33ddfd2398f87660fafdb9e6a5fb0f3f2f", + "sha256:86a22143a4001f53bf58027b044da1fb10d67b62a785fc1390b5c7f089d9838c", + "sha256:8ca484ca11c65e05639ffe80f20d45e6be81fbec7683d6c9a15cd421e6e8b340", + "sha256:8d1d7d63e5d2f4e92a39ae1e897a5d551720179bb8d1254883e7113d3826d43c", + "sha256:8e702e7489f39375601c7ea5a0bef207256828a2bc5986c65cb15cd0cf097a87", + "sha256:a055ba17f4675aadcda3005df2e28a86feb731fdcc865e1f6b4f209ed1225cba", + "sha256:a33cb3f095e7d776ec76e79d92d83117438b6153510770fcd57b9c96f9ef623d", + "sha256:a61184c7289146c8cff06b6b41807c6994c6d437278e72cf00ff7fe1c7a263d1", + "sha256:af55cc207865d641a57f7044e98b08b09220da3d1b13a46f26487cc2f898a072", + "sha256:b00cf0471888823b7a9f722c6c41eb6985cf34f077edcf62695ac4bed6ec01ee", + "sha256:b03850c290c765b87102959ea53299dc9addf76ca08a06ea98383348ae205c99", + "sha256:b97fd5bb6b7c1a64b7ac0632f7ce389b8ab362e7bd5f60654c2a418496be5d7f", + "sha256:c37bc677690fd33932182b85d37433845de612962ed080c3e4d92f758d1bd894", + "sha256:cecb66492440ae8592797dd705a0cbaa6abe0555f4fa6c5f40b078bd2740fc6b", + "sha256:d0a83afab5e062abffcdcbcc74f9d3ba37b2385294dd0927ad65fc6ebe04e054", + "sha256:d3cf56cc36d42908495760b223ca9c2c0f9f0002b4eddc994b24db5fcb86a9e4", + "sha256:e646b19f47d655261b22df9976e572f588185279970efba3d45c377127d35349", + "sha256:e7908c2025eb18394e32d65dd02d2e37e17d733cdbe7d78231c2b6d7eb20cdb9", + "sha256:e8f2df79a46e130235bc5e1bbef4de0583fb19d481eaa0bffa76e8347ea45ec6", + "sha256:eaeeb2464019765bc4340214fca1143081d49972864773f3f1e95dba5c7edc7d", + "sha256:eb18549b770351b54e1ab5da37d22bc530b8bfe2ee31e22b9ebe650640d2ef12", + "sha256:f2e5b6f5cf7c18df66d082604a1d9c7a2d18f7d1dbe9514a2afaccbb51cc4fc3", + "sha256:f8cafa6f885a0ff5e39efa9325195217bb47d5929ab0051636610d24aef45ade" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.4.32" + "version": "==1.4.51" }, "starlette": { "hashes": [ - "sha256:3c8e48e52736b3161e34c9f0e8153b4f32ec5d8995a3ee1d59410d92f75162ed", - "sha256:7d49f4a27f8742262ef1470608c59ddbc66baf37c148e938c7038e6bc7a998aa" + "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75", + "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91" ], - "markers": "python_version >= '3.6'", - "version": "==0.14.2" + "markers": "python_version >= '3.7'", + "version": "==0.27.0" }, "systemd-python": { "hashes": [ @@ -360,18 +359,19 @@ }, "uvicorn": { "hashes": [ - "sha256:2a76bb359171a504b3d1c853409af3adbfa5cef374a4a59e5881945a97a93eae", - "sha256:45ad7dfaaa7d55cab4cd1e85e03f27e9d60bc067ddc59db52a2b0aeca8870292" + "sha256:4b85ba02b8a20429b9b205d015cbeb788a12da527f731811b643fd739ef90d5f", + "sha256:54898fcd80c13ff1cd28bf77b04ec9dbd8ff60c5259b499b4b12bb0917f22907" ], - "version": "==0.14.0" + "markers": "python_version >= '3.8'", + "version": "==0.27.0.post1" }, "wsproto": { "hashes": [ - "sha256:868776f8456997ad0d9720f7322b746bbe9193751b5b290b7f924659377c8c38", - "sha256:d8345d1808dd599b5ffb352c25a367adb6157e664e140dbecba3f9bc007edb9f" + "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", + "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736" ], - "markers": "python_full_version >= '3.6.1'", - "version": "==1.0.0" + "markers": "python_full_version >= '3.7.0'", + "version": "==1.2.0" } }, "develop": { @@ -520,6 +520,9 @@ "version": "==8.1.7" }, "coverage": { + "extras": [ + "toml" + ], "hashes": [ "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61", "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1", @@ -579,21 +582,21 @@ }, "decoy": { "hashes": [ - "sha256:599d6f4b6e67b74a3d8edf7a432b0b7d5d3c0296f7733fe96f2f4be4360bbfec", - "sha256:d84bd95816339ab2fda65aa6ced3291a0739bbc83ca82344c8543a801a082d56" + "sha256:575bdbe81afb4c152cd99a34568a9aa4369461f79d6172c678279c5d5585befe", + "sha256:7ddcc08b8ce991f7705cee76fae9061dcb17352e0a1ca2d9a0d4a0306ebd51cd" ], "index": "pypi", - "markers": "python_version >= '3.6' and python_version < '4.0'", - "version": "==1.10.3" + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==2.1.1" }, "diff-match-patch": { "hashes": [ - "sha256:8bf9d9c4e059d917b5c6312bac0c137971a32815ddbda9c682b949f2986b4d34", - "sha256:da6f5a01aa586df23dfc89f3827e1cafbb5420be9d87769eeb079ddfd9477a18" + "sha256:953019cdb9c9d2c9e47b5b12bcff3cf4746fc4598eb406076fa1fc27e6a1f15c", + "sha256:dce43505fb7b1b317de7195579388df0746d90db07015ed47a85e5e44930ef93" ], "index": "pypi", - "markers": "python_version >= '2.7'", - "version": "==20200713" + "markers": "python_version >= '3.7'", + "version": "==20230430" }, "exceptiongroup": { "hashes": [ @@ -613,38 +616,39 @@ }, "flake8": { "hashes": [ - "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", - "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" + "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132", + "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.9.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==7.0.0" }, "flake8-annotations": { "hashes": [ - "sha256:0d6cd2e770b5095f09689c9d84cc054c51b929c41a68969ea1beb4b825cac515", - "sha256:d10c4638231f8a50c0a597c4efce42bd7b7d85df4f620a0ddaca526138936a4f" + "sha256:af78e3216ad800d7e144745ece6df706c81b3255290cbf870e54879d495e8ade", + "sha256:ff37375e71e3b83f2a5a04d443c41e2c407de557a884f3300a7fa32f3c41cb0a" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1' and python_full_version < '4.0.0'", - "version": "==2.6.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==3.0.1" }, "flake8-docstrings": { "hashes": [ - "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde", - "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b" + "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af", + "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75" ], "index": "pypi", - "version": "==1.6.0" + "markers": "python_version >= '3.7'", + "version": "==1.7.0" }, "flake8-noqa": { "hashes": [ - "sha256:26d92ca6b72dec732d294e587a2bdeb66dab01acc609ed6a064693d6baa4e789", - "sha256:445618162e0bbae1b9d983326d4e39066c5c6de71ba0c444ca2d4d1fa5b2cdb7" + "sha256:4465e16a19be433980f6f563d05540e2e54797eb11facb9feb50fed60624dc45", + "sha256:771765ab27d1efd157528379acd15131147f9ae578a72d17fb432ca197881243" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.2.9" + "version": "==1.4.0" }, "frozenlist": { "hashes": [ @@ -747,130 +751,150 @@ }, "mccabe": { "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "version": "==0.6.1" + "markers": "python_version >= '3.6'", + "version": "==0.7.0" }, "mock": { "hashes": [ - "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62", - "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc" + "sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744", + "sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d" ], "index": "pypi", "markers": "python_version >= '3.6'", - "version": "==4.0.3" + "version": "==5.1.0" }, "multidict": { "hashes": [ - "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9", - "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8", - "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03", - "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710", - "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161", - "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664", - "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569", - "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067", - "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313", - "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706", - "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2", - "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636", - "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49", - "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93", - "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603", - "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0", - "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60", - "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4", - "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e", - "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1", - "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60", - "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951", - "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc", - "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe", - "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95", - "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d", - "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8", - "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed", - "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2", - "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775", - "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87", - "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c", - "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2", - "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98", - "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3", - "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe", - "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78", - "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660", - "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176", - "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e", - "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988", - "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c", - "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c", - "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0", - "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449", - "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f", - "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde", - "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5", - "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d", - "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac", - "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a", - "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9", - "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca", - "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11", - "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35", - "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063", - "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b", - "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982", - "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258", - "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1", - "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52", - "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480", - "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7", - "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461", - "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d", - "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc", - "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779", - "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a", - "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547", - "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0", - "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171", - "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf", - "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d", - "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba" + "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556", + "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c", + "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29", + "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b", + "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8", + "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7", + "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd", + "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40", + "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6", + "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3", + "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c", + "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9", + "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5", + "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae", + "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442", + "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9", + "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc", + "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c", + "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea", + "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5", + "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50", + "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182", + "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453", + "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e", + "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600", + "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733", + "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda", + "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241", + "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461", + "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e", + "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e", + "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b", + "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e", + "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7", + "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386", + "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd", + "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9", + "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf", + "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee", + "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5", + "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a", + "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271", + "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54", + "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4", + "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496", + "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb", + "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319", + "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3", + "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f", + "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527", + "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed", + "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604", + "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef", + "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8", + "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5", + "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5", + "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626", + "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c", + "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d", + "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c", + "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc", + "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc", + "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b", + "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38", + "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450", + "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1", + "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f", + "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3", + "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755", + "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226", + "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a", + "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046", + "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf", + "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479", + "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e", + "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1", + "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a", + "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83", + "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929", + "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93", + "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a", + "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c", + "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44", + "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89", + "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba", + "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e", + "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da", + "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24", + "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423", + "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef" ], "markers": "python_version >= '3.7'", - "version": "==6.0.4" + "version": "==6.0.5" }, "mypy": { "hashes": [ - "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", - "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", - "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", - "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", - "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", - "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", - "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", - "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", - "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", - "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", - "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", - "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", - "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", - "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", - "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", - "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", - "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", - "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", - "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", - "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", - "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", - "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", - "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", - "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" + "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6", + "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d", + "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02", + "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d", + "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3", + "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3", + "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3", + "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66", + "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259", + "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835", + "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd", + "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d", + "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8", + "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07", + "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b", + "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e", + "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6", + "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae", + "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9", + "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d", + "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a", + "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592", + "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218", + "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817", + "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4", + "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410", + "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.981" + "markers": "python_version >= '3.8'", + "version": "==1.8.0" }, "mypy-extensions": { "hashes": [ @@ -898,11 +922,11 @@ }, "platformdirs": { "hashes": [ - "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", - "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", + "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "pluggy": { "hashes": [ @@ -922,11 +946,11 @@ }, "pycodestyle": { "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" + "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.7.0" + "markers": "python_version >= '3.8'", + "version": "==2.11.1" }, "pydocstyle": { "hashes": [ @@ -938,11 +962,11 @@ }, "pyflakes": { "hashes": [ - "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", - "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" + "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", + "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.3.1" + "markers": "python_version >= '3.8'", + "version": "==3.2.0" }, "pytest": { "hashes": [ @@ -955,20 +979,29 @@ }, "pytest-aiohttp": { "hashes": [ - "sha256:0b9b660b146a65e1313e2083d0d2e1f63047797354af9a28d6b7c9f0726fa33d", - "sha256:c929854339637977375838703b62fef63528598bc0a9d451639eba95f4aaa44f" + "sha256:63a5360fd2f34dda4ab8e6baee4c5f5be4cd186a403cabd498fced82ac9c561e", + "sha256:880262bc5951e934463b15e3af8bb298f11f7d4d3ebac970aab425aff10a780a" ], "index": "pypi", - "version": "==0.3.0" + "markers": "python_version >= '3.7'", + "version": "==1.0.5" + }, + "pytest-asyncio": { + "hashes": [ + "sha256:2143d9d9375bf372a73260e4114541485e84fca350b0b6b92674ca56ff5f7ea2", + "sha256:b0079dfac14b60cd1ce4691fbfb1748fe939db7d0234b5aba97197d10fbe0fef" + ], + "markers": "python_version >= '3.8'", + "version": "==0.23.4" }, "pytest-cov": { "hashes": [ - "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191", - "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e" + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.10.1" + "markers": "python_version >= '3.7'", + "version": "==4.1.0" }, "pytest-forked": { "hashes": [ @@ -1002,6 +1035,15 @@ "markers": "python_version < '3.11'", "version": "==2.0.1" }, + "types-mock": { + "hashes": [ + "sha256:13ca379d5710ccb3f18f69ade5b08881874cb83383d8fb49b1d4dac9d5c5d090", + "sha256:3d116955495935b0bcba14954b38d97e507cd43eca3e3700fc1b8e4f5c6bf2c7" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==5.1.0.20240106" + }, "typing-extensions": { "hashes": [ "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", diff --git a/g-code-testing/g_code_parsing/g_code_functionality_defs/g_code_functionality_def_base.py b/g-code-testing/g_code_parsing/g_code_functionality_defs/g_code_functionality_def_base.py index 3667d139506..004f3e606bc 100644 --- a/g-code-testing/g_code_parsing/g_code_functionality_defs/g_code_functionality_def_base.py +++ b/g-code-testing/g_code_parsing/g_code_functionality_defs/g_code_functionality_def_base.py @@ -53,6 +53,7 @@ def generate_explanation( @classmethod def _generate_command_explanation(cls, g_code_args: Dict[str, str]) -> str: ... + return "" @classmethod def _generate_response_explanation(cls, response: str) -> str: diff --git a/hardware/Pipfile b/hardware/Pipfile index 0b302c13e6b..b02e50c7c51 100644 --- a/hardware/Pipfile +++ b/hardware/Pipfile @@ -11,19 +11,19 @@ numpy = "==1.22.3" pydantic = "==1.9.2" [dev-packages] -pytest = "==7.1.1" +pytest = "==7.4.4" pytest-lazy-fixture = "==0.6.3" -pytest-cov = "==2.10.1" -mypy = "==0.981" +pytest-cov = "==4.1.0" +mypy = "==1.8.0" black = "==22.3.0" -flake8 = "~=3.9.0" -flake8-annotations = "~=2.6.2" -flake8-docstrings = "~=1.6.0" -flake8-noqa = "~=1.2.1" -mock = "~=4.0.3" -types-mock = "==4.0.1" -hypothesis = "~=6.39.5" -pytest-asyncio = "~=0.16" +flake8 = "==7.0.0" +flake8-annotations = "~=3.0.1" +flake8-docstrings = "~=1.7.0" +flake8-noqa = "~=1.4.0" +mock = "~=5.1.0" +types-mock = "~=5.1.0" +hypothesis = "~=6.96.1" +pytest-asyncio = "~=0.23.0" matplotlib = "*" opentrons-shared-data = { editable = true, path = "../shared-data/python" } diff --git a/hardware/Pipfile.lock b/hardware/Pipfile.lock index a56c60f726d..ccab8884999 100644 --- a/hardware/Pipfile.lock +++ b/hardware/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "16eff2fac0ee431c4cd558ef6e2cc98fc2f2ec703e3e33bb639b948b8f5ccbfb" + "sha256": "04ae6d52e739cf67e21d13822316f7dc2030d272976c0a9cfd0f7d35db743301" }, "pipfile-spec": 6, "requires": { @@ -174,20 +174,20 @@ }, "setuptools": { "hashes": [ - "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2", - "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6" + "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05", + "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78" ], "markers": "python_version >= '3.8'", - "version": "==69.0.2" + "version": "==69.0.3" }, "typing-extensions": { "hashes": [ - "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", - "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.8.0" + "version": "==4.9.0" }, "wrapt": { "hashes": [ @@ -269,11 +269,11 @@ "develop": { "attrs": { "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", + "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" ], "markers": "python_version >= '3.7'", - "version": "==23.1.0" + "version": "==23.2.0" }, "black": { "hashes": [ @@ -364,62 +364,65 @@ "version": "==1.2.0" }, "coverage": { + "extras": [ + "toml" + ], "hashes": [ - "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", - "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", - "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", - "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", - "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", - "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", - "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", - "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", - "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", - "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", - "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", - "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", - "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", - "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", - "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", - "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", - "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", - "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", - "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", - "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", - "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", - "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", - "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", - "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", - "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", - "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", - "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", - "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", - "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", - "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", - "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", - "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", - "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", - "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", - "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", - "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", - "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", - "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", - "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", - "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", - "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", - "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", - "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", - "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", - "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", - "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", - "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", - "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", - "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", - "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", - "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", - "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" + "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca", + "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471", + "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a", + "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058", + "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85", + "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143", + "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446", + "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590", + "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a", + "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105", + "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9", + "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a", + "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac", + "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25", + "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2", + "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450", + "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932", + "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba", + "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137", + "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae", + "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614", + "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70", + "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e", + "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505", + "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870", + "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc", + "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451", + "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7", + "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e", + "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566", + "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5", + "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26", + "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2", + "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42", + "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555", + "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43", + "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed", + "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa", + "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516", + "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952", + "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd", + "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09", + "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c", + "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f", + "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6", + "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1", + "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0", + "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e", + "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9", + "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9", + "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e", + "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06" ], "markers": "python_version >= '3.8'", - "version": "==7.3.2" + "version": "==7.4.0" }, "cycler": { "hashes": [ @@ -429,97 +432,106 @@ "markers": "python_version >= '3.8'", "version": "==0.12.1" }, + "exceptiongroup": { + "hashes": [ + "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", + "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + ], + "markers": "python_version < '3.11'", + "version": "==1.2.0" + }, "flake8": { "hashes": [ - "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", - "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" + "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132", + "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.9.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==7.0.0" }, "flake8-annotations": { "hashes": [ - "sha256:0d6cd2e770b5095f09689c9d84cc054c51b929c41a68969ea1beb4b825cac515", - "sha256:d10c4638231f8a50c0a597c4efce42bd7b7d85df4f620a0ddaca526138936a4f" + "sha256:af78e3216ad800d7e144745ece6df706c81b3255290cbf870e54879d495e8ade", + "sha256:ff37375e71e3b83f2a5a04d443c41e2c407de557a884f3300a7fa32f3c41cb0a" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1' and python_full_version < '4.0.0'", - "version": "==2.6.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==3.0.1" }, "flake8-docstrings": { "hashes": [ - "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde", - "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b" + "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af", + "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75" ], "index": "pypi", - "version": "==1.6.0" + "markers": "python_version >= '3.7'", + "version": "==1.7.0" }, "flake8-noqa": { "hashes": [ - "sha256:26d92ca6b72dec732d294e587a2bdeb66dab01acc609ed6a064693d6baa4e789", - "sha256:445618162e0bbae1b9d983326d4e39066c5c6de71ba0c444ca2d4d1fa5b2cdb7" + "sha256:4465e16a19be433980f6f563d05540e2e54797eb11facb9feb50fed60624dc45", + "sha256:771765ab27d1efd157528379acd15131147f9ae578a72d17fb432ca197881243" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.2.9" + "version": "==1.4.0" }, "fonttools": { "hashes": [ - "sha256:13ac0cba2fc63fa4b232f2a7971f35f35c6eaf10bd1271fa96d4ce6253a8acfd", - "sha256:156ae342a1ed1fe38e180de471e98fbf5b2b6ae280fa3323138569c4ca215844", - "sha256:1a9f9cdd7ef63d1b8ac90db335762451452426b3207abd79f60da510cea62da5", - "sha256:1c9937c4dd1061afd22643389445fabda858af5e805860ec3082a4bc07c7a720", - "sha256:25852f0c63df0af022f698464a4a80f7d1d5bd974bcd22f995f6b4ad198e32dd", - "sha256:2ae45716c27a41807d58a9f3f59983bdc8c0a46cb259e4450ab7e196253a9853", - "sha256:2c23c59d321d62588620f2255cf951270bf637d88070f38ed8b5e5558775b86c", - "sha256:2cf923a4a556ab4cc4c52f69a4a2db624cf5a2cf360394368b40c5152fe3321e", - "sha256:2d0eba685938c603f2f648dfc0aadbf8c6a4fe1c7ca608c2970a6ef39e00f254", - "sha256:3033b55f401a622de2630b3982234d97219d89b058607b87927eccb0f922313c", - "sha256:49ea0983e55fd7586a809787cd4644a7ae471e53ab8ddc016f9093b400e32646", - "sha256:5200b01f463d97cc2b7ff8a1e3584151f4413e98cb8419da5f17d1dbb84cc214", - "sha256:5b627ed142398ea9202bd752c04311592558964d1a765fb2f78dc441a05633f4", - "sha256:6d4a4ebcc76e30898ff3296ea786491c70e183f738319ae2629e0d44f17ece42", - "sha256:795150d5edc595e1a2cfb3d65e8f4f3d027704fc2579f8990d381bef6b188eb6", - "sha256:7b460720ce81773da1a3e7cc964c48e1e11942b280619582a897fa0117b56a62", - "sha256:7b5636f5706d49f13b6d610fe54ee662336cdf56b5a6f6683c0b803e23d826d2", - "sha256:8485cc468288e213f31afdaf1fdda3c79010f542559fbba936a54f4644df2570", - "sha256:87c214197712cc14fd2a4621efce2a9c501a77041232b789568149a8a3161517", - "sha256:87c3299da7da55394fb324349db0ede38114a46aafd0e7dfcabfecd28cdd94c3", - "sha256:89c2c520f9492844ecd6316d20c6c7a157b5c0cb73a1411b3db28ee304f30122", - "sha256:8be6adfa4e15977075278dd0a0bae74dec59be7b969b5ceed93fb86af52aa5be", - "sha256:8bee9f4fc8c99824a424ae45c789ee8c67cb84f8e747afa7f83b7d3cef439c3b", - "sha256:982f69855ac258260f51048d9e0c53c5f19881138cc7ca06deb38dc4b97404b6", - "sha256:9e6aeb5c340416d11a3209d75c48d13e72deea9e1517837dd1522c1fd1f17c11", - "sha256:a0e94244ec24a940ecfbe5b31c975c8a575d5ed2d80f9a280ce3b21fa5dc9c34", - "sha256:a4a50a1dfad7f7ba5ca3f99cc73bf5cdac67ceade8e4b355a877521f20ad1b63", - "sha256:a9fa52ef8fd14d7eb3d813e1451e7ace3e1eebfa9b7237d3f81fee8f3de6a114", - "sha256:adab73618d0a328b203a0e242b3eba60a2b5662d9cb2bd16ed9c52af8a7d86af", - "sha256:c506e3d3a9e898caee4dc094f34b49c5566870d5a2d1ca2125f0a9f35ecc2205", - "sha256:c779f8701deedf41908f287aeb775b8a6f59875ad1002b98ac6034ae4ddc1b7b", - "sha256:c94564b1f3b5dd87e73577610d85115b1936edcc596deaf84a31bbe70e17456b", - "sha256:c9a0e422ab79e5cb2b47913be6a4b5fd20c4c7ac34a24f3691a4e099e965e0b8", - "sha256:ca9eceebe70035b057ce549e2054cad73e95cac3fe91a9d827253d1c14618204", - "sha256:ce199227ce7921eaafdd4f96536f16b232d6b580ce74ce337de544bf06cb2752", - "sha256:d00fc63131dcac6b25f50a5a129758438317e54e3ce5587163f7058de4b0e933", - "sha256:d3d7b96aba96e05e8c911ce2dfc5acc6a178b8f44f6aa69371ab91aa587563da", - "sha256:d4e69e2c7f93b695d2e6f18f709d501d945f65c1d237dafaabdd23cd935a5276", - "sha256:e26e7fb908ae4f622813e7cb32cd2db6c24e3122bb3b98f25e832a2fe0e7e228", - "sha256:e5b7905fd68eacb7cc56a13139da5c312c45baae6950dd00b02563c54508a041", - "sha256:f5f1423a504ccc329efb5aa79738de83d38c072be5308788dde6bd419969d7f5", - "sha256:f8bc3973ed58893c4107993e0a7ae34901cb572b5e798249cbef35d30801ffd4" + "sha256:0255dbc128fee75fb9be364806b940ed450dd6838672a150d501ee86523ac61e", + "sha256:0a00bd0e68e88987dcc047ea31c26d40a3c61185153b03457956a87e39d43c37", + "sha256:0a1d313a415eaaba2b35d6cd33536560deeebd2ed758b9bfb89ab5d97dc5deac", + "sha256:0f750037e02beb8b3569fbff701a572e62a685d2a0e840d75816592280e5feae", + "sha256:13819db8445a0cec8c3ff5f243af6418ab19175072a9a92f6cc8ca7d1452754b", + "sha256:254d9a6f7be00212bf0c3159e0a420eb19c63793b2c05e049eb337f3023c5ecc", + "sha256:29495d6d109cdbabe73cfb6f419ce67080c3ef9ea1e08d5750240fd4b0c4763b", + "sha256:32ab2e9702dff0dd4510c7bb958f265a8d3dd5c0e2547e7b5f7a3df4979abb07", + "sha256:3480eeb52770ff75140fe7d9a2ec33fb67b07efea0ab5129c7e0c6a639c40c70", + "sha256:3a808f3c1d1df1f5bf39be869b6e0c263570cdafb5bdb2df66087733f566ea71", + "sha256:3b629108351d25512d4ea1a8393a2dba325b7b7d7308116b605ea3f8e1be88df", + "sha256:3d71606c9321f6701642bd4746f99b6089e53d7e9817fc6b964e90d9c5f0ecc6", + "sha256:3e2b95dce2ead58fb12524d0ca7d63a63459dd489e7e5838c3cd53557f8933e1", + "sha256:4a5a5318ba5365d992666ac4fe35365f93004109d18858a3e18ae46f67907670", + "sha256:4c811d3c73b6abac275babb8aa439206288f56fdb2c6f8835e3d7b70de8937a7", + "sha256:4e743935139aa485fe3253fc33fe467eab6ea42583fa681223ea3f1a93dd01e6", + "sha256:4ec558c543609e71b2275c4894e93493f65d2f41c15fe1d089080c1d0bb4d635", + "sha256:5465df494f20a7d01712b072ae3ee9ad2887004701b95cb2cc6dcb9c2c97a899", + "sha256:5b60e3afa9635e3dfd3ace2757039593e3bd3cf128be0ddb7a1ff4ac45fa5a50", + "sha256:63fbed184979f09a65aa9c88b395ca539c94287ba3a364517698462e13e457c9", + "sha256:69731e8bea0578b3c28fdb43dbf95b9386e2d49a399e9a4ad736b8e479b08085", + "sha256:6dd58cc03016b281bd2c74c84cdaa6bd3ce54c5a7f47478b7657b930ac3ed8eb", + "sha256:740947906590a878a4bde7dd748e85fefa4d470a268b964748403b3ab2aeed6c", + "sha256:7df26dd3650e98ca45f1e29883c96a0b9f5bb6af8d632a6a108bc744fa0bd9b3", + "sha256:7eb7ad665258fba68fd22228a09f347469d95a97fb88198e133595947a20a184", + "sha256:7ee48bd9d6b7e8f66866c9090807e3a4a56cf43ffad48962725a190e0dd774c8", + "sha256:86e0427864c6c91cf77f16d1fb9bf1bbf7453e824589e8fb8461b6ee1144f506", + "sha256:8f57ecd742545362a0f7186774b2d1c53423ed9ece67689c93a1055b236f638c", + "sha256:90f898cdd67f52f18049250a6474185ef6544c91f27a7bee70d87d77a8daf89c", + "sha256:94208ea750e3f96e267f394d5588579bb64cc628e321dbb1d4243ffbc291b18b", + "sha256:a1c154bb85dc9a4cf145250c88d112d88eb414bad81d4cb524d06258dea1bdc0", + "sha256:a5d77479fb885ef38a16a253a2f4096bc3d14e63a56d6246bfdb56365a12b20c", + "sha256:a86a5ab2873ed2575d0fcdf1828143cfc6b977ac448e3dc616bb1e3d20efbafa", + "sha256:ac71e2e201df041a2891067dc36256755b1229ae167edbdc419b16da78732c2f", + "sha256:b3e1304e5f19ca861d86a72218ecce68f391646d85c851742d265787f55457a4", + "sha256:b8be28c036b9f186e8c7eaf8a11b42373e7e4949f9e9f370202b9da4c4c3f56c", + "sha256:c19044256c44fe299d9a73456aabee4b4d06c6b930287be93b533b4737d70aa1", + "sha256:d49ce3ea7b7173faebc5664872243b40cf88814ca3eb135c4a3cdff66af71946", + "sha256:e040f905d542362e07e72e03612a6270c33d38281fd573160e1003e43718d68d", + "sha256:eabae77a07c41ae0b35184894202305c3ad211a93b2eb53837c2a1143c8bc952", + "sha256:f791446ff297fd5f1e2247c188de53c1bfb9dd7f0549eba55b73a3c2087a2703", + "sha256:f83a4daef6d2a202acb9bf572958f91cfde5b10c8ee7fb1d09a4c81e5d851fd8" ], "markers": "python_version >= '3.8'", - "version": "==4.46.0" + "version": "==4.47.2" }, "hypothesis": { "hashes": [ - "sha256:1577ac8baa9c77ee3c946124c7b69551e127c4440f9e56fa6ed49bc73dabbf49", - "sha256:7cc9056edeab51ce195b3b6994f2446f0aac405d191cab7e2de5e159cb4c2bc2" + "sha256:848ea0952f0bdfd02eac59e41b03f1cbba8fa2cffeffa8db328bbd6cfe159974", + "sha256:955a57e56be4607c81c17ca53e594af54aadeed91e07b88bb7f84e8208ea7739" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==6.39.6" + "markers": "python_version >= '3.8'", + "version": "==6.96.1" }, "iniconfig": { "hashes": [ @@ -683,50 +695,54 @@ }, "mccabe": { "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "version": "==0.6.1" + "markers": "python_version >= '3.6'", + "version": "==0.7.0" }, "mock": { "hashes": [ - "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62", - "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc" + "sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744", + "sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d" ], "index": "pypi", "markers": "python_version >= '3.6'", - "version": "==4.0.3" + "version": "==5.1.0" }, "mypy": { "hashes": [ - "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", - "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", - "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", - "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", - "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", - "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", - "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", - "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", - "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", - "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", - "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", - "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", - "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", - "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", - "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", - "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", - "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", - "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", - "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", - "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", - "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", - "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", - "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", - "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" + "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6", + "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d", + "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02", + "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d", + "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3", + "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3", + "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3", + "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66", + "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259", + "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835", + "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd", + "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d", + "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8", + "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07", + "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b", + "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e", + "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6", + "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae", + "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9", + "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d", + "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a", + "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592", + "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218", + "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817", + "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4", + "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410", + "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.981" + "markers": "python_version >= '3.8'", + "version": "==1.8.0" }, "mypy-extensions": { "hashes": [ @@ -778,71 +794,85 @@ }, "pathspec": { "hashes": [ - "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", - "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" + "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", + "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" ], - "markers": "python_version >= '3.7'", - "version": "==0.11.2" + "markers": "python_version >= '3.8'", + "version": "==0.12.1" }, "pillow": { "hashes": [ - "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d", - "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de", - "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616", - "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839", - "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099", - "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a", - "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219", - "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106", - "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b", - "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412", - "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b", - "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7", - "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2", - "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7", - "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14", - "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f", - "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27", - "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57", - "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262", - "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28", - "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610", - "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172", - "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273", - "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e", - "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d", - "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818", - "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f", - "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9", - "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01", - "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7", - "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651", - "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312", - "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80", - "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666", - "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061", - "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b", - "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992", - "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593", - "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4", - "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db", - "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba", - "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd", - "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e", - "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212", - "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb", - "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2", - "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34", - "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256", - "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f", - "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2", - "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38", - "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996", - "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a", - "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793" + "sha256:0304004f8067386b477d20a518b50f3fa658a28d44e4116970abfcd94fac34a8", + "sha256:0689b5a8c5288bc0504d9fcee48f61a6a586b9b98514d7d29b840143d6734f39", + "sha256:0eae2073305f451d8ecacb5474997c08569fb4eb4ac231ffa4ad7d342fdc25ac", + "sha256:0fb3e7fc88a14eacd303e90481ad983fd5b69c761e9e6ef94c983f91025da869", + "sha256:11fa2e5984b949b0dd6d7a94d967743d87c577ff0b83392f17cb3990d0d2fd6e", + "sha256:127cee571038f252a552760076407f9cff79761c3d436a12af6000cd182a9d04", + "sha256:154e939c5f0053a383de4fd3d3da48d9427a7e985f58af8e94d0b3c9fcfcf4f9", + "sha256:15587643b9e5eb26c48e49a7b33659790d28f190fc514a322d55da2fb5c2950e", + "sha256:170aeb00224ab3dc54230c797f8404507240dd868cf52066f66a41b33169bdbe", + "sha256:1b5e1b74d1bd1b78bc3477528919414874748dd363e6272efd5abf7654e68bef", + "sha256:1da3b2703afd040cf65ec97efea81cfba59cdbed9c11d8efc5ab09df9509fc56", + "sha256:1e23412b5c41e58cec602f1135c57dfcf15482013ce6e5f093a86db69646a5aa", + "sha256:2247178effb34a77c11c0e8ac355c7a741ceca0a732b27bf11e747bbc950722f", + "sha256:257d8788df5ca62c980314053197f4d46eefedf4e6175bc9412f14412ec4ea2f", + "sha256:3031709084b6e7852d00479fd1d310b07d0ba82765f973b543c8af5061cf990e", + "sha256:322209c642aabdd6207517e9739c704dc9f9db943015535783239022002f054a", + "sha256:322bdf3c9b556e9ffb18f93462e5f749d3444ce081290352c6070d014c93feb2", + "sha256:33870dc4653c5017bf4c8873e5488d8f8d5f8935e2f1fb9a2208c47cdd66efd2", + "sha256:35bb52c37f256f662abdfa49d2dfa6ce5d93281d323a9af377a120e89a9eafb5", + "sha256:3c31822339516fb3c82d03f30e22b1d038da87ef27b6a78c9549888f8ceda39a", + "sha256:3eedd52442c0a5ff4f887fab0c1c0bb164d8635b32c894bc1faf4c618dd89df2", + "sha256:3ff074fc97dd4e80543a3e91f69d58889baf2002b6be64347ea8cf5533188213", + "sha256:47c0995fc4e7f79b5cfcab1fc437ff2890b770440f7696a3ba065ee0fd496563", + "sha256:49d9ba1ed0ef3e061088cd1e7538a0759aab559e2e0a80a36f9fd9d8c0c21591", + "sha256:51f1a1bffc50e2e9492e87d8e09a17c5eea8409cda8d3f277eb6edc82813c17c", + "sha256:52a50aa3fb3acb9cf7213573ef55d31d6eca37f5709c69e6858fe3bc04a5c2a2", + "sha256:54f1852cd531aa981bc0965b7d609f5f6cc8ce8c41b1139f6ed6b3c54ab82bfb", + "sha256:609448742444d9290fd687940ac0b57fb35e6fd92bdb65386e08e99af60bf757", + "sha256:69ffdd6120a4737710a9eee73e1d2e37db89b620f702754b8f6e62594471dee0", + "sha256:6fad5ff2f13d69b7e74ce5b4ecd12cc0ec530fcee76356cac6742785ff71c452", + "sha256:7049e301399273a0136ff39b84c3678e314f2158f50f517bc50285fb5ec847ad", + "sha256:70c61d4c475835a19b3a5aa42492409878bbca7438554a1f89d20d58a7c75c01", + "sha256:716d30ed977be8b37d3ef185fecb9e5a1d62d110dfbdcd1e2a122ab46fddb03f", + "sha256:753cd8f2086b2b80180d9b3010dd4ed147efc167c90d3bf593fe2af21265e5a5", + "sha256:773efe0603db30c281521a7c0214cad7836c03b8ccff897beae9b47c0b657d61", + "sha256:7823bdd049099efa16e4246bdf15e5a13dbb18a51b68fa06d6c1d4d8b99a796e", + "sha256:7c8f97e8e7a9009bcacbe3766a36175056c12f9a44e6e6f2d5caad06dcfbf03b", + "sha256:823ef7a27cf86df6597fa0671066c1b596f69eba53efa3d1e1cb8b30f3533068", + "sha256:8373c6c251f7ef8bda6675dd6d2b3a0fcc31edf1201266b5cf608b62a37407f9", + "sha256:83b2021f2ade7d1ed556bc50a399127d7fb245e725aa0113ebd05cfe88aaf588", + "sha256:870ea1ada0899fd0b79643990809323b389d4d1d46c192f97342eeb6ee0b8483", + "sha256:8d12251f02d69d8310b046e82572ed486685c38f02176bd08baf216746eb947f", + "sha256:9c23f307202661071d94b5e384e1e1dc7dfb972a28a2310e4ee16103e66ddb67", + "sha256:9d189550615b4948f45252d7f005e53c2040cea1af5b60d6f79491a6e147eef7", + "sha256:a086c2af425c5f62a65e12fbf385f7c9fcb8f107d0849dba5839461a129cf311", + "sha256:a2b56ba36e05f973d450582fb015594aaa78834fefe8dfb8fcd79b93e64ba4c6", + "sha256:aebb6044806f2e16ecc07b2a2637ee1ef67a11840a66752751714a0d924adf72", + "sha256:b1b3020d90c2d8e1dae29cf3ce54f8094f7938460fb5ce8bc5c01450b01fbaf6", + "sha256:b4b6b1e20608493548b1f32bce8cca185bf0480983890403d3b8753e44077129", + "sha256:b6f491cdf80ae540738859d9766783e3b3c8e5bd37f5dfa0b76abdecc5081f13", + "sha256:b792a349405fbc0163190fde0dc7b3fef3c9268292586cf5645598b48e63dc67", + "sha256:b7c2286c23cd350b80d2fc9d424fc797575fb16f854b831d16fd47ceec078f2c", + "sha256:babf5acfede515f176833ed6028754cbcd0d206f7f614ea3447d67c33be12516", + "sha256:c365fd1703040de1ec284b176d6af5abe21b427cb3a5ff68e0759e1e313a5e7e", + "sha256:c4225f5220f46b2fde568c74fca27ae9771536c2e29d7c04f4fb62c83275ac4e", + "sha256:c570f24be1e468e3f0ce7ef56a89a60f0e05b30a3669a459e419c6eac2c35364", + "sha256:c6dafac9e0f2b3c78df97e79af707cdc5ef8e88208d686a4847bab8266870023", + "sha256:c8de2789052ed501dd829e9cae8d3dcce7acb4777ea4a479c14521c942d395b1", + "sha256:cb28c753fd5eb3dd859b4ee95de66cc62af91bcff5db5f2571d32a520baf1f04", + "sha256:cb4c38abeef13c61d6916f264d4845fab99d7b711be96c326b84df9e3e0ff62d", + "sha256:d1b35bcd6c5543b9cb547dee3150c93008f8dd0f1fef78fc0cd2b141c5baf58a", + "sha256:d8e6aeb9201e655354b3ad049cb77d19813ad4ece0df1249d3c793de3774f8c7", + "sha256:d8ecd059fdaf60c1963c58ceb8997b32e9dc1b911f5da5307aab614f1ce5c2fb", + "sha256:da2b52b37dad6d9ec64e653637a096905b258d2fc2b984c41ae7d08b938a67e4", + "sha256:e87f0b2c78157e12d7686b27d63c070fd65d994e8ddae6f328e0dcf4a0cd007e", + "sha256:edca80cbfb2b68d7b56930b84a0e45ae1694aeba0541f798e908a49d66b837f1", + "sha256:f379abd2f1e3dddb2b61bc67977a6b5a0a3f7485538bcc6f39ec76163891ee48", + "sha256:fe4c15f6c9285dc54ce6553a3ce908ed37c8f3825b5a51a15c91442bb955b868" ], "markers": "python_version >= '3.8'", - "version": "==10.1.0" + "version": "==10.2.0" }, "platformdirs": { "hashes": [ @@ -860,21 +890,13 @@ "markers": "python_version >= '3.8'", "version": "==1.3.0" }, - "py": { - "hashes": [ - "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", - "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.11.0" - }, "pycodestyle": { "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" + "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.7.0" + "markers": "python_version >= '3.8'", + "version": "==2.11.1" }, "pydantic": { "hashes": [ @@ -928,11 +950,11 @@ }, "pyflakes": { "hashes": [ - "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", - "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" + "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", + "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.3.1" + "markers": "python_version >= '3.8'", + "version": "==3.2.0" }, "pyparsing": { "hashes": [ @@ -982,30 +1004,30 @@ }, "pytest": { "hashes": [ - "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63", - "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea" + "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", + "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==7.1.1" + "version": "==7.4.4" }, "pytest-asyncio": { "hashes": [ - "sha256:c16052382554c7b22d48782ab3438d5b10f8cf7a4bdcae7f0f67f097d95beecc", - "sha256:ea9021364e32d58f0be43b91c6233fb8d2224ccef2398d6837559e587682808f" + "sha256:37a9d912e8338ee7b4a3e917381d1c95bfc8682048cb0fbc35baba316ec1faba", + "sha256:af313ce900a62fbe2b1aed18e37ad757f1ef9940c6b6a88e2954de38d6b1fb9f" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==0.23.2" + "version": "==0.23.3" }, "pytest-cov": { "hashes": [ - "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191", - "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e" + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.10.1" + "markers": "python_version >= '3.7'", + "version": "==4.1.0" }, "pytest-lazy-fixture": { "hashes": [ @@ -1025,11 +1047,11 @@ }, "setuptools": { "hashes": [ - "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2", - "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6" + "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05", + "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78" ], "markers": "python_version >= '3.8'", - "version": "==69.0.2" + "version": "==69.0.3" }, "six": { "hashes": [ @@ -1063,20 +1085,21 @@ }, "types-mock": { "hashes": [ - "sha256:1a470543be8de673e2ea14739622de3bfb8c9b10429f50338ba9ca1e868c15e9", - "sha256:1ad09970f4f5ec45a138ab1e88d032f010e851bccef7765b34737ed390bbc5c8" + "sha256:13ca379d5710ccb3f18f69ade5b08881874cb83383d8fb49b1d4dac9d5c5d090", + "sha256:3d116955495935b0bcba14954b38d97e507cd43eca3e3700fc1b8e4f5c6bf2c7" ], "index": "pypi", - "version": "==4.0.1" + "markers": "python_version >= '3.8'", + "version": "==5.1.0.20240106" }, "typing-extensions": { "hashes": [ - "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", - "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.8.0" + "version": "==4.9.0" } } } diff --git a/hardware/opentrons_hardware/drivers/binary_usb/bin_serial.py b/hardware/opentrons_hardware/drivers/binary_usb/bin_serial.py index 0ce04bb2d8a..d6d68c50f73 100644 --- a/hardware/opentrons_hardware/drivers/binary_usb/bin_serial.py +++ b/hardware/opentrons_hardware/drivers/binary_usb/bin_serial.py @@ -5,8 +5,8 @@ from functools import partial from typing import Optional, Type, Tuple -import serial # type: ignore[import] -from serial.tools.list_ports import comports # type: ignore[import] +import serial # type: ignore[import-untyped] +from serial.tools.list_ports import comports # type: ignore[import-untyped] from opentrons_shared_data.errors.exceptions import InternalUSBCommunicationError diff --git a/hardware/opentrons_hardware/drivers/gpio/__init__.py b/hardware/opentrons_hardware/drivers/gpio/__init__.py index bb54878b4b6..0b23c93d470 100644 --- a/hardware/opentrons_hardware/drivers/gpio/__init__.py +++ b/hardware/opentrons_hardware/drivers/gpio/__init__.py @@ -30,7 +30,7 @@ def _get_gpiod() -> Any: If gpiod is not available, a mock will be used and the problem will be logged. """ try: - import gpiod # type: ignore[import] + import gpiod # type: ignore[import-not-found] return gpiod except ImportError: diff --git a/hardware/opentrons_hardware/firmware_bindings/utils/binary_serializable.py b/hardware/opentrons_hardware/firmware_bindings/utils/binary_serializable.py index 832c469f42f..b35b5d26896 100644 --- a/hardware/opentrons_hardware/firmware_bindings/utils/binary_serializable.py +++ b/hardware/opentrons_hardware/firmware_bindings/utils/binary_serializable.py @@ -88,7 +88,7 @@ def from_string(cls: Type[This], t: str) -> This: Returns: New instance. """ - ... + raise NotImplementedError() @property def value(self) -> T: diff --git a/hardware/opentrons_hardware/hardware_control/motion_planning/move_utils.py b/hardware/opentrons_hardware/hardware_control/motion_planning/move_utils.py index 8792d9fb596..fee27ee82cb 100644 --- a/hardware/opentrons_hardware/hardware_control/motion_planning/move_utils.py +++ b/hardware/opentrons_hardware/hardware_control/motion_planning/move_utils.py @@ -517,6 +517,10 @@ def build_move( """Build a move.""" log = logging.getLogger("build_move") + # TODO: We need to limit the initial speed and the final speed based on the directions + # of this and the bounding moves - if the directions are not the same, and I mean exact + # unit vector equivalence, we need to limit the junction speed to the max speed discontinuity + # because we can only instantly change speed below that value. initial_speed = find_initial_speed(constraints, move, prev_move) final_speed = find_final_speed(constraints, move, next_move) final_speed = achievable_final(constraints, move, initial_speed, final_speed) diff --git a/hardware/opentrons_hardware/scripts/can_comm.py b/hardware/opentrons_hardware/scripts/can_comm.py index b74e27f5830..a864efcc95b 100644 --- a/hardware/opentrons_hardware/scripts/can_comm.py +++ b/hardware/opentrons_hardware/scripts/can_comm.py @@ -73,7 +73,7 @@ def create_choices(enum_type: Type[Enum]) -> Sequence[str]: """ # mypy wants type annotation for v. - return [f"{i}: {v.name}" for (i, v) in enumerate(enum_type)] # type: ignore[var-annotated] + return [f"{i}: {v.name}" for (i, v) in enumerate(enum_type)] PromptedEnum = TypeVar("PromptedEnum", bound=Enum, covariant=True) diff --git a/hardware/opentrons_hardware/scripts/sensors.py b/hardware/opentrons_hardware/scripts/sensors.py index a004b90e17b..ea9bb1badbc 100644 --- a/hardware/opentrons_hardware/scripts/sensors.py +++ b/hardware/opentrons_hardware/scripts/sensors.py @@ -39,7 +39,7 @@ def create_choices(enum_type: Type[Enum]) -> Sequence[str]: """ # mypy wants type annotation for v. - return [f"{i}: {v.name}" for (i, v) in enumerate(enum_type)] # type: ignore[var-annotated] + return [f"{i}: {v.name}" for (i, v) in enumerate(enum_type)] def prompt_sensor_type( diff --git a/hardware/opentrons_hardware/scripts/usb_comm.py b/hardware/opentrons_hardware/scripts/usb_comm.py index 353a06ef47f..3d971e02357 100644 --- a/hardware/opentrons_hardware/scripts/usb_comm.py +++ b/hardware/opentrons_hardware/scripts/usb_comm.py @@ -53,7 +53,7 @@ def create_choices(enum_type: Type[Enum]) -> Sequence[str]: """ # mypy wants type annotation for v. - return [f"{i}: {v.name}" for (i, v) in enumerate(enum_type)] # type: ignore[var-annotated] + return [f"{i}: {v.name}" for (i, v) in enumerate(enum_type)] PromptedEnum = TypeVar("PromptedEnum", bound=Enum, covariant=True) diff --git a/hardware/tests/firmware_integration/conftest.py b/hardware/tests/firmware_integration/conftest.py index fe4bf09cb46..ad465b1170f 100644 --- a/hardware/tests/firmware_integration/conftest.py +++ b/hardware/tests/firmware_integration/conftest.py @@ -3,7 +3,7 @@ import pytest from typing import AsyncGenerator, Iterator, AsyncIterator, List, Dict -from _pytest.fixtures import FixtureRequest +from _pytest.fixtures import SubRequest from opentrons_hardware.drivers.can_bus.settings import DriverSettings from opentrons_hardware.drivers.can_bus.build import build_driver @@ -32,7 +32,7 @@ async def can_messenger( @pytest.fixture def can_messenger_queue( - request: FixtureRequest, + request: SubRequest, can_messenger: CanMessenger, ) -> Iterator[WaitableCallback]: """Create WaitableCallback for the CAN Messenger.""" @@ -55,9 +55,9 @@ def can_messenger_queue( constants.NodeId.gantry_y, ], ) -def subsystem_node_id(request: FixtureRequest) -> Iterator[constants.NodeId]: +def subsystem_node_id(request: SubRequest) -> Iterator[constants.NodeId]: """Each subsystem's node id as a fixture.""" - yield request.param # type: ignore[attr-defined] + yield request.param _motor_nodes = [ @@ -88,9 +88,9 @@ def subsystem_node_id(request: FixtureRequest) -> Iterator[constants.NodeId]: scope="session", params=_motor_nodes, ) -def motor_node_id(request: FixtureRequest) -> Iterator[constants.NodeId]: +def motor_node_id(request: SubRequest) -> Iterator[constants.NodeId]: """Each motor's node id as a fixture.""" - yield request.param # type: ignore[attr-defined] + yield request.param @pytest.fixture(scope="session") diff --git a/hardware/tests/firmware_integration/test_eeprom.py b/hardware/tests/firmware_integration/test_eeprom.py index 44377cdd6e7..1552582ff60 100644 --- a/hardware/tests/firmware_integration/test_eeprom.py +++ b/hardware/tests/firmware_integration/test_eeprom.py @@ -3,7 +3,7 @@ from typing import Iterator import pytest -from _pytest.fixtures import FixtureRequest +from _pytest.fixtures import SubRequest from opentrons_hardware.firmware_bindings import NodeId, ArbitrationId from opentrons_hardware.firmware_bindings.messages.fields import EepromDataField @@ -28,9 +28,9 @@ NodeId.pipette_left, ], ) -def eeprom_node_id(request: FixtureRequest) -> Iterator[NodeId]: +def eeprom_node_id(request: SubRequest) -> Iterator[NodeId]: """Node with eeprom.""" - yield request.param # type: ignore[attr-defined] + yield request.param def filter_func(arb: ArbitrationId) -> bool: diff --git a/hardware/tests/firmware_integration/test_move_groups.py b/hardware/tests/firmware_integration/test_move_groups.py index 8f33c5f0701..4122f4bf80f 100644 --- a/hardware/tests/firmware_integration/test_move_groups.py +++ b/hardware/tests/firmware_integration/test_move_groups.py @@ -4,7 +4,7 @@ from typing import Iterator, List, Dict import pytest -from _pytest.fixtures import FixtureRequest +from _pytest.fixtures import SubRequest from opentrons_hardware.firmware_bindings import NodeId, ArbitrationId from opentrons_hardware.firmware_bindings.messages.message_definitions import ( AddLinearMoveRequest, @@ -35,9 +35,9 @@ scope="session", params=list(range(3)), ) -def group_id(request: FixtureRequest) -> Iterator[int]: +def group_id(request: SubRequest) -> Iterator[int]: """A group id test fixture.""" - yield request.param # type: ignore[attr-defined] + yield request.param def filter_func(arb: ArbitrationId) -> bool: @@ -193,7 +193,7 @@ async def test_move_integration( # Also mypy doesn't like pytest.approx so we have to type ignore it # We now store the position as a tuple of assumed position + encoder value. - assert {k: v.motor_position for k, v in position.items()} == { # type: ignore[comparison-overlap] + assert {k: v.motor_position for k, v in position.items()} == { motor_node: pytest.approx( motor_node.value, abs=all_motor_node_step_sizes[motor_node] * 3 ) diff --git a/hardware/tests/opentrons_hardware/drivers/binary_usb/test_driver.py b/hardware/tests/opentrons_hardware/drivers/binary_usb/test_driver.py index 2148818ecfd..c72648f2f48 100644 --- a/hardware/tests/opentrons_hardware/drivers/binary_usb/test_driver.py +++ b/hardware/tests/opentrons_hardware/drivers/binary_usb/test_driver.py @@ -1,5 +1,5 @@ """USB Driver tests.""" -import serial # type: ignore[import] +import serial # type: ignore[import-untyped] import time from contextlib import ExitStack import multiprocessing @@ -157,7 +157,7 @@ async def test_recv(subject: SerialUsbDriver, test_port_host: SerialEmulator) -> length = test_port_host.write(b"\x00\x01\x00\x00") assert length == 4 message = await subject.read() - assert type(message) == Ack + assert type(message) is Ack assert message == Ack() @@ -179,11 +179,11 @@ async def test_recv_iterator( break assert len(messages) == 3 - assert type(messages[0]) == Ack + assert type(messages[0]) is Ack assert messages[0] == Ack() - assert type(messages[1]) == AckFailed + assert type(messages[1]) is AckFailed assert messages[1] == AckFailed() - assert type(messages[2]) == EnterBootloaderRequest + assert type(messages[2]) is EnterBootloaderRequest assert messages[2] == EnterBootloaderRequest() diff --git a/hardware/tests/opentrons_hardware/firmware_bindings/test_constants.py b/hardware/tests/opentrons_hardware/firmware_bindings/test_constants.py index f8c9a182c55..c9d74a8f8d5 100644 --- a/hardware/tests/opentrons_hardware/firmware_bindings/test_constants.py +++ b/hardware/tests/opentrons_hardware/firmware_bindings/test_constants.py @@ -61,9 +61,7 @@ def test_application_for(node_id: NodeId) -> None: # get a flattened list of all the sub-nodes, which are nodes with more # than one element in the NodeId.bootloader_map list. - sub_nodes = sum( # type: ignore[var-annotated] - [n for n in NodeId.bootloader_map().values() if len(n) > 1], [] - ) + sub_nodes = sum([n for n in NodeId.bootloader_map().values() if len(n) > 1], []) # Make sure that if this is a sub-node that the application node is the first # element in the bootloader map list if node_id in sub_nodes: diff --git a/hardware/tests/opentrons_hardware/hardware_control/test_motion_plan.py b/hardware/tests/opentrons_hardware/hardware_control/test_motion_plan.py index 38df3df2c1b..857c0d08f92 100644 --- a/hardware/tests/opentrons_hardware/hardware_control/test_motion_plan.py +++ b/hardware/tests/opentrons_hardware/hardware_control/test_motion_plan.py @@ -2,7 +2,7 @@ import numpy as np from hypothesis import given, assume, strategies as st from hypothesis.extra import numpy as hynp -from typing import Iterator, List +from typing import Iterator, List, Tuple from opentrons_hardware.hardware_control.motion_planning import move_manager from opentrons_hardware.hardware_control.motion_planning.types import ( @@ -20,7 +20,7 @@ def generate_axis_constraint(draw: st.DrawFn) -> AxisConstraints: """Create axis constraint using Hypothesis.""" acc = draw(st.integers(min_value=500, max_value=5000)) - speed_dist = draw(st.integers(min_value=10, max_value=50)) + speed_dist = draw(st.integers(min_value=11, max_value=50)) dir_change_dist = draw(st.integers(min_value=5, max_value=10)) assume(speed_dist > dir_change_dist) return AxisConstraints.build( @@ -47,51 +47,62 @@ def generate_coordinates(draw: st.DrawFn) -> Coordinates[str, np.float64]: @st.composite -def generate_close_coordinates( - draw: st.DrawFn, prev_coord: Coordinates[str, np.float64] +def generate_coordinates_with_defined_separation( + draw: st.DrawFn, + prev_coord: Coordinates[str, np.float64], + min_separation: float = 0.1, + max_separation: float = 1.0, ) -> Coordinates[str, np.float64]: """Create coordinates using Hypothesis.""" diff: List[np.typing.NDArray[np.float64]] = [ - draw(hynp.from_dtype(np.dtype(np.float64), min_value=0.1, max_value=1.0)), - draw(hynp.from_dtype(np.dtype(np.float64), min_value=0.1, max_value=1.0)), - draw(hynp.from_dtype(np.dtype(np.float64), min_value=0.1, max_value=1.0)), - draw(hynp.from_dtype(np.dtype(np.float64), min_value=0.1, max_value=1.0)), - draw(hynp.from_dtype(np.dtype(np.float64), min_value=0.1, max_value=1.0)), - draw(hynp.from_dtype(np.dtype(np.float64), min_value=0.1, max_value=1.0)), + draw( + hynp.from_dtype( + np.dtype(np.float64), min_value=min_separation, max_value=max_separation + ) + ) + for elem in range(len(prev_coord)) ] coord: np.typing.NDArray[np.float64] = vectorize(prev_coord) + diff return dict(zip(SIXAXES, (np.float64(i) for i in coord))) -def reject_close_coordinates( - a: Coordinates[str, np.float64], b: Coordinates[str, np.float64] -) -> bool: - """Reject example if the coordinates are too close. - - Consecutive coordinates must be at least 1mm apart in one of the axes. - """ - return not np.any(np.isclose(vectorize(b), vectorize(a), atol=1.0)) - - @st.composite -def generate_target_list( - draw: st.DrawFn, - elements: st.SearchStrategy[Coordinates[str, np.float64]] = generate_coordinates(), +def generate_far_target_list( + draw: st.DrawFn, origin: Coordinates[str, np.float64] ) -> List[MoveTarget[str]]: """Generate a list of MoveTarget using Hypothesis.""" - target_num = draw(st.integers(min_value=1, max_value=10)) + # Note: this needs to change! It should be the following: + # target_num = draw(st.integers(min_value=1, max_value=10)) + # but, we don't properly handle sequences of moves that steadily change direction in one blend + # - in practice, we really just blend single moves, which this tests satisfactorily. + target_num = 1 target_list: List[MoveTarget[str]] = [] + prev_coord = origin while len(target_list) < target_num: - position = draw(elements) - if len(target_list): - assume(reject_close_coordinates(position, target_list[-1].position)) + position = draw( + generate_coordinates_with_defined_separation(prev_coord, 1.0, 500.0) + ) target = MoveTarget.build( position, np.float64(draw(st.floats(min_value=10, max_value=500))) ) target_list.append(target) + prev_coord = position return target_list +@st.composite +def generate_far_path( + draw: st.DrawFn, + origin_strategy: st.SearchStrategy[ + Coordinates[str, np.float64] + ] = generate_coordinates(), +) -> Tuple[Coordinates[str, np.float64], List[MoveTarget[str]]]: + """Generate a path (origin plus target) with a large difference in position.""" + origin = draw(origin_strategy) + target_list = draw(generate_far_target_list(origin)) + return (origin, target_list) + + @st.composite def generate_close_target_list( draw: st.DrawFn, origin: Coordinates[str, np.float64] @@ -101,7 +112,9 @@ def generate_close_target_list( target_list: List[MoveTarget[str]] = [] prev_coord = origin while len(target_list) < target_num: - position = draw(generate_close_coordinates(prev_coord)) + position = draw( + generate_coordinates_with_defined_separation(prev_coord, 0.1, 1.0) + ) target = MoveTarget.build( position, np.float64(draw(st.floats(min_value=0.1, max_value=10.0))) ) @@ -110,6 +123,19 @@ def generate_close_target_list( return target_list +@st.composite +def generate_close_path( + draw: st.DrawFn, + origin_strategy: st.SearchStrategy[ + Coordinates[str, np.float64] + ] = generate_coordinates(), +) -> Tuple[Coordinates[str, np.float64], List[MoveTarget[str]]]: + """Generate a path (origin, target) with little difference between positions.""" + origin = draw(origin_strategy) + target_list = draw(generate_close_target_list(origin)) + return (origin, target_list) + + @given( x_constraint=generate_axis_constraint(), y_constraint=generate_axis_constraint(), @@ -117,8 +143,7 @@ def generate_close_target_list( a_constraint=generate_axis_constraint(), b_constraint=generate_axis_constraint(), c_constraint=generate_axis_constraint(), - origin=generate_coordinates(), - targets=generate_target_list(), + path=generate_far_path(), ) def test_move_plan( x_constraint: AxisConstraints, @@ -127,11 +152,10 @@ def test_move_plan( a_constraint: AxisConstraints, b_constraint: AxisConstraints, c_constraint: AxisConstraints, - origin: Coordinates[str, np.float64], - targets: List[MoveTarget[str]], + path: Tuple[Coordinates[str, np.float64], List[MoveTarget[str]]], ) -> None: """Test motion plan using Hypothesis.""" - assume(reject_close_coordinates(origin, targets[0].position)) + origin, targets = path constraints: SystemConstraints[str] = { "X": x_constraint, "Y": y_constraint, @@ -147,7 +171,7 @@ def test_move_plan( iteration_limit=20, ) - assert converged + assert converged, f"Failed to converge: {blend_log}" @given( @@ -157,8 +181,7 @@ def test_move_plan( a_constraint=generate_axis_constraint(), b_constraint=generate_axis_constraint(), c_constraint=generate_axis_constraint(), - origin=generate_coordinates(), - data=st.data(), + path=generate_close_path(), ) def test_close_move_plan( x_constraint: AxisConstraints, @@ -167,11 +190,10 @@ def test_close_move_plan( a_constraint: AxisConstraints, b_constraint: AxisConstraints, c_constraint: AxisConstraints, - origin: Coordinates[str, np.float64], - data: st.DataObject, + path: Tuple[Coordinates[str, np.float64], List[MoveTarget[str]]], ) -> None: """Test motion plan using Hypothesis.""" - targets = data.draw(generate_close_target_list(origin)) + origin, targets = path constraints: SystemConstraints[str] = { "X": x_constraint, "Y": y_constraint, @@ -187,4 +209,4 @@ def test_close_move_plan( iteration_limit=20, ) - assert converged + assert converged, f"Failed to converge: {blend_log}" diff --git a/hardware/tests/opentrons_hardware/hardware_control/tools/test_oneshot.py b/hardware/tests/opentrons_hardware/hardware_control/tools/test_oneshot.py index 737abc361cf..15df612f787 100644 --- a/hardware/tests/opentrons_hardware/hardware_control/tools/test_oneshot.py +++ b/hardware/tests/opentrons_hardware/hardware_control/tools/test_oneshot.py @@ -64,7 +64,7 @@ def responder( assert tools.gripper is None # Only the tools request should be sent - no followups for mounts with nothing on # them - assert await mock_messenger.send.called_once_with( + mock_messenger.send.assert_called_once_with( node_id=NodeId.head, message=message_definitions.AttachedToolsRequest(), ) @@ -107,7 +107,7 @@ def responder( # Only the tools request should be sent - no followups for mounts with nothing on # them - assert await mock_messenger.send.called_once_with( + mock_messenger.send.assert_called_once_with( node_id=NodeId.head, message=message_definitions.AttachedToolsRequest( payload=payloads.EmptyPayload() diff --git a/hardware/tests/opentrons_hardware/sensors/test_sensor_drivers.py b/hardware/tests/opentrons_hardware/sensors/test_sensor_drivers.py index 9a241ca0196..15512087862 100644 --- a/hardware/tests/opentrons_hardware/sensors/test_sensor_drivers.py +++ b/hardware/tests/opentrons_hardware/sensors/test_sensor_drivers.py @@ -2,7 +2,7 @@ import pytest import mock from typing import Union, List -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from unittest.mock import patch from mock.mock import AsyncMock diff --git a/robot-server/Config.in b/robot-server/Config.in index b829d640d9b..359b031d79c 100644 --- a/robot-server/Config.in +++ b/robot-server/Config.in @@ -10,7 +10,6 @@ config BR2_PACKAGE_PYTHON_OPENTRONS_ROBOT_SERVER select BR2_PACKAGE_PYTHON_MULTIPART # runtime select BR2_PACKAGE_PYTHON_PYDANTIC # runtime select BR2_PACKAGE_PYTHON_SQLALCHEMY # runtime - select BR2_PACKAGE_PYTHON_AIOSQLITE # runtime select BR2_PACKAGE_PYTHON_TYPING_EXTENSIONS # runtime select BR2_PACKAGE_PYTHON_UVICORN # runtime select BR2_PACKAGE_PYTHON_WSPROTO # runtime diff --git a/robot-server/Pipfile b/robot-server/Pipfile index 0007a8f0da3..e6c1b7ba794 100755 --- a/robot-server/Pipfile +++ b/robot-server/Pipfile @@ -11,47 +11,51 @@ python_version = "3.10" # https://github.com/pypa/pipenv/issues/4408#issuecomment-668324177 atomicwrites = { version = "==1.4.0", markers="sys_platform=='win32'" } colorama = { version = "==0.4.4", markers="sys_platform=='win32'" } -# pytest 7.3.0 dropped attrs, and tavern 1.x at least has some pytest hooks +# pytest 7.3.0 dropped attrs, and tavern up to at least 2.x has some pytest hooks # that implicitly require the use of attrs in pytest internals -pytest = "<7.3.0,>=7.1.0" -tavern = "~=1.6" -pytest-asyncio = "~=0.16" -pytest-cov = "==2.10.1" +pytest = "==7.2.2" +tavern = "==2.9.1" +pytest-asyncio = "~=0.23.0" +pytest-cov = "==4.1.0" pytest-lazy-fixture = "==0.6.3" pytest-xdist = "~=2.5.0" requests = "==2.27.1" graphviz = "==0.19" -mock = "~=4.0.3" -mypy = "==0.981" -flake8 = "~=3.9.0" -flake8-annotations = "~=2.6.2" -flake8-docstrings = "~=1.6.0" -flake8-noqa = "~=1.2.1" -decoy = "~=2.1" -httpx = "==0.18.*" +mock = "~=5.0.1" +mypy = "==1.8.0" +flake8 = "==7.0.0" +flake8-annotations = "~=3.0.1" +flake8-docstrings = "~=1.7.0" +flake8-noqa = "~=1.4.0" +decoy = "==2.1.1" +httpx = "==0.26.0" black = "==22.3.0" -types-requests = "==2.25.6" -types-mock = "==4.0.1" +types-requests = "~=2.27.1" +types-mock = "~=5.1.0" sqlalchemy2-stubs = "==0.0.2a21" -python-box = "==5.4.1" +# limited by tavern +python-box = "==6.1.0" types-paho-mqtt = "==1.6.0.20240106" [packages] -anyio = "==3.6.1" -fastapi = "==0.68.1" -python-dotenv = "==0.19.0" -python-multipart = "==0.0.5" -pydantic = "==1.9.2" +anyio = "==3.7.1" +# fastapi >=0.100.0 is intended for use with pydantic 2.x, and while it theoretically is +# backwards compatible, best to be sure +fastapi = "==0.99.1" +python-dotenv = "==1.0.1" +python-multipart = "==0.0.6" +# pydantic 2.x has many breaking api changes +pydantic = "==1.10.12" typing-extensions = ">=4.0.0,<5" -uvicorn = "==0.14.0" -wsproto = "==1.0.0" +uvicorn = "==0.27.0.post1" +wsproto = "==1.2.0" systemd-python = { version = "==234", markers="sys_platform == 'linux'" } idna = "==3.3" click = "==8.1.2" -numpy = "==1.23.3" +numpy = "==1.22.3" zipp = "==3.5.0" -sqlalchemy = "==1.4.32" -aiosqlite = "==0.17.0" +# breaking changes above this version of sqlalchemy +sqlalchemy = "==1.4.51" opentrons-hardware = {editable = true, path='../hardware', extras=['FLEX']} opentrons = { editable = true, path = "../api"} opentrons-shared-data = { editable = true, path = "../shared-data/python" } diff --git a/robot-server/Pipfile.lock b/robot-server/Pipfile.lock index f932e667400..e97832aab95 100644 --- a/robot-server/Pipfile.lock +++ b/robot-server/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b54ccd56fbeba707cb1a93b887360d66ea97ab72b01beb64ce3ac1139f871c05" + "sha256": "d56512f7ae8f68fd80ec6eff41af08576468087a45578f5b2c8241e42d95b887" }, "pipfile-spec": 6, "requires": { @@ -23,31 +23,14 @@ ], "version": "==0.2.0" }, - "aiosqlite": { - "hashes": [ - "sha256:6c49dc6d3405929b1d08eeccc72306d3677503cc5e5e43771efc1e00232e8231", - "sha256:f0e6acc24bc4864149267ac82fb46dfb3be4455f99fe21df82609cc6e6baee51" - ], - "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==0.17.0" - }, "anyio": { "hashes": [ - "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b", - "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be" + "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780", + "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5" ], "index": "pypi", - "markers": "python_full_version >= '3.6.2'", - "version": "==3.6.1" - }, - "asgiref": { - "hashes": [ - "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e", - "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed" - ], "markers": "python_version >= '3.7'", - "version": "==3.7.2" + "version": "==3.7.1" }, "attrs": { "hashes": [ @@ -66,14 +49,22 @@ "markers": "python_version >= '3.7'", "version": "==8.1.2" }, + "exceptiongroup": { + "hashes": [ + "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", + "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + ], + "markers": "python_version < '3.11'", + "version": "==1.2.0" + }, "fastapi": { "hashes": [ - "sha256:644bb815bae326575c4b2842469fb83053a4b974b82fa792ff9283d17fbbd99d", - "sha256:94d2820906c36b9b8303796fb7271337ec89c74223229e3cfcf056b5a7d59e23" + "sha256:976df7bab51ac7beda9f68c4513b8c4490b5c1135c72aafd0a5ee4023ec5282e", + "sha256:ac78f717cd80d657bd183f94d33b9bda84aa376a46a9dab513586b8eef1dc6fc" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==0.68.1" + "markers": "python_version >= '3.7'", + "version": "==0.99.1" }, "h11": { "hashes": [ @@ -94,10 +85,11 @@ }, "jsonschema": { "hashes": [ - "sha256:5f9c0a719ca2ce14c5de2fd350a64fd2d13e8539db29836a86adc990bb1a068f", - "sha256:8d4a2b7b6c2237e0199c8ea1a6d3e05bf118e289ae2b9d7ba444182a2959560d" + "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d", + "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6" ], - "version": "==3.0.2" + "markers": "python_version >= '3.7'", + "version": "==4.17.3" }, "msgpack": { "hashes": [ @@ -163,38 +155,30 @@ }, "numpy": { "hashes": [ - "sha256:004f0efcb2fe1c0bd6ae1fcfc69cc8b6bf2407e0f18be308612007a0762b4089", - "sha256:09f6b7bdffe57fc61d869a22f506049825d707b288039d30f26a0d0d8ea05164", - "sha256:0ea3f98a0ffce3f8f57675eb9119f3f4edb81888b6874bc1953f91e0b1d4f440", - "sha256:17c0e467ade9bda685d5ac7f5fa729d8d3e76b23195471adae2d6a6941bd2c18", - "sha256:1f27b5322ac4067e67c8f9378b41c746d8feac8bdd0e0ffede5324667b8a075c", - "sha256:22d43376ee0acd547f3149b9ec12eec2f0ca4a6ab2f61753c5b29bb3e795ac4d", - "sha256:2ad3ec9a748a8943e6eb4358201f7e1c12ede35f510b1a2221b70af4bb64295c", - "sha256:301c00cf5e60e08e04d842fc47df641d4a181e651c7135c50dc2762ffe293dbd", - "sha256:39a664e3d26ea854211867d20ebcc8023257c1800ae89773cbba9f9e97bae036", - "sha256:51bf49c0cd1d52be0a240aa66f3458afc4b95d8993d2d04f0d91fa60c10af6cd", - "sha256:78a63d2df1d947bd9d1b11d35564c2f9e4b57898aae4626638056ec1a231c40c", - "sha256:7cd1328e5bdf0dee621912f5833648e2daca72e3839ec1d6695e91089625f0b4", - "sha256:8355fc10fd33a5a70981a5b8a0de51d10af3688d7a9e4a34fcc8fa0d7467bb7f", - "sha256:8c79d7cf86d049d0c5089231a5bcd31edb03555bd93d81a16870aa98c6cfb79d", - "sha256:91b8d6768a75247026e951dce3b2aac79dc7e78622fc148329135ba189813584", - "sha256:94c15ca4e52671a59219146ff584488907b1f9b3fc232622b47e2cf832e94fb8", - "sha256:98dcbc02e39b1658dc4b4508442a560fe3ca5ca0d989f0df062534e5ca3a5c1a", - "sha256:a64403f634e5ffdcd85e0b12c08f04b3080d3e840aef118721021f9b48fc1460", - "sha256:bc6e8da415f359b578b00bcfb1d08411c96e9a97f9e6c7adada554a0812a6cc6", - "sha256:bdc9febce3e68b697d931941b263c59e0c74e8f18861f4064c1f712562903411", - "sha256:c1ba66c48b19cc9c2975c0d354f24058888cdc674bebadceb3cdc9ec403fb5d1", - "sha256:c9f707b5bb73bf277d812ded9896f9512a43edff72712f31667d0a8c2f8e71ee", - "sha256:d5422d6a1ea9b15577a9432e26608c73a78faf0b9039437b075cf322c92e98e7", - "sha256:e5d5420053bbb3dd64c30e58f9363d7a9c27444c3648e61460c1237f9ec3fa14", - "sha256:e868b0389c5ccfc092031a861d4e158ea164d8b7fdbb10e3b5689b4fc6498df6", - "sha256:efd9d3abe5774404becdb0748178b48a218f1d8c44e0375475732211ea47c67e", - "sha256:f8c02ec3c4c4fcb718fdf89a6c6f709b14949408e8cf2a2be5bfa9c49548fd85", - "sha256:ffcf105ecdd9396e05a8e58e81faaaf34d3f9875f137c7372450baa5d77c9a54" + "sha256:07a8c89a04997625236c5ecb7afe35a02af3896c8aa01890a849913a2309c676", + "sha256:08d9b008d0156c70dc392bb3ab3abb6e7a711383c3247b410b39962263576cd4", + "sha256:201b4d0552831f7250a08d3b38de0d989d6f6e4658b709a02a73c524ccc6ffce", + "sha256:2c10a93606e0b4b95c9b04b77dc349b398fdfbda382d2a39ba5a822f669a0123", + "sha256:3ca688e1b9b95d80250bca34b11a05e389b1420d00e87a0d12dc45f131f704a1", + "sha256:48a3aecd3b997bf452a2dedb11f4e79bc5bfd21a1d4cc760e703c31d57c84b3e", + "sha256:568dfd16224abddafb1cbcce2ff14f522abe037268514dd7e42c6776a1c3f8e5", + "sha256:5bfb1bb598e8229c2d5d48db1860bcf4311337864ea3efdbe1171fb0c5da515d", + "sha256:639b54cdf6aa4f82fe37ebf70401bbb74b8508fddcf4797f9fe59615b8c5813a", + "sha256:8251ed96f38b47b4295b1ae51631de7ffa8260b5b087808ef09a39a9d66c97ab", + "sha256:92bfa69cfbdf7dfc3040978ad09a48091143cffb778ec3b03fa170c494118d75", + "sha256:97098b95aa4e418529099c26558eeb8486e66bd1e53a6b606d684d0c3616b168", + "sha256:a3bae1a2ed00e90b3ba5f7bd0a7c7999b55d609e0c54ceb2b076a25e345fa9f4", + "sha256:c34ea7e9d13a70bf2ab64a2532fe149a9aced424cd05a2c4ba662fd989e3e45f", + "sha256:dbc7601a3b7472d559dc7b933b18b4b66f9aa7452c120e87dfb33d02008c8a18", + "sha256:e7927a589df200c5e23c57970bafbd0cd322459aa7b1ff73b7c2e84d6e3eae62", + "sha256:f8c1f39caad2c896bc0018f699882b345b2a63708008be29b1f355ebf6f933fe", + "sha256:f950f8845b480cffe522913d35567e29dd381b0dc7e4ce6a4a9f9156417d2430", + "sha256:fade0d4f4d292b6f39951b6836d7a3c7ef5b2347f3c420cd9820a1d90d794802", + "sha256:fdf3c08bce27132395d3c3ba1503cac12e17282358cb4bddc25cc46b0aca07aa" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.23.3" + "version": "==1.22.3" }, "opentrons": { "editable": true, @@ -227,45 +211,46 @@ }, "pydantic": { "hashes": [ - "sha256:1061c6ee6204f4f5a27133126854948e3b3d51fcc16ead2e5d04378c199b2f44", - "sha256:19b5686387ea0d1ea52ecc4cffb71abb21702c5e5b2ac626fd4dbaa0834aa49d", - "sha256:2bd446bdb7755c3a94e56d7bdfd3ee92396070efa8ef3a34fab9579fe6aa1d84", - "sha256:328558c9f2eed77bd8fffad3cef39dbbe3edc7044517f4625a769d45d4cf7555", - "sha256:32e0b4fb13ad4db4058a7c3c80e2569adbd810c25e6ca3bbd8b2a9cc2cc871d7", - "sha256:3ee0d69b2a5b341fc7927e92cae7ddcfd95e624dfc4870b32a85568bd65e6131", - "sha256:4aafd4e55e8ad5bd1b19572ea2df546ccace7945853832bb99422a79c70ce9b8", - "sha256:4b3946f87e5cef3ba2e7bd3a4eb5a20385fe36521d6cc1ebf3c08a6697c6cfb3", - "sha256:4de71c718c9756d679420c69f216776c2e977459f77e8f679a4a961dc7304a56", - "sha256:5565a49effe38d51882cb7bac18bda013cdb34d80ac336428e8908f0b72499b0", - "sha256:5803ad846cdd1ed0d97eb00292b870c29c1f03732a010e66908ff48a762f20e4", - "sha256:5da164119602212a3fe7e3bc08911a89db4710ae51444b4224c2382fd09ad453", - "sha256:615661bfc37e82ac677543704437ff737418e4ea04bef9cf11c6d27346606044", - "sha256:78a4d6bdfd116a559aeec9a4cfe77dda62acc6233f8b56a716edad2651023e5e", - "sha256:7d0f183b305629765910eaad707800d2f47c6ac5bcfb8c6397abdc30b69eeb15", - "sha256:7ead3cd020d526f75b4188e0a8d71c0dbbe1b4b6b5dc0ea775a93aca16256aeb", - "sha256:84d76ecc908d917f4684b354a39fd885d69dd0491be175f3465fe4b59811c001", - "sha256:8cb0bc509bfb71305d7a59d00163d5f9fc4530f0881ea32c74ff4f74c85f3d3d", - "sha256:91089b2e281713f3893cd01d8e576771cd5bfdfbff5d0ed95969f47ef6d676c3", - "sha256:9c9e04a6cdb7a363d7cb3ccf0efea51e0abb48e180c0d31dca8d247967d85c6e", - "sha256:a8c5360a0297a713b4123608a7909e6869e1b56d0e96eb0d792c27585d40757f", - "sha256:afacf6d2a41ed91fc631bade88b1d319c51ab5418870802cedb590b709c5ae3c", - "sha256:b34ba24f3e2d0b39b43f0ca62008f7ba962cff51efa56e64ee25c4af6eed987b", - "sha256:bd67cb2c2d9602ad159389c29e4ca964b86fa2f35c2faef54c3eb28b4efd36c8", - "sha256:c0f5e142ef8217019e3eef6ae1b6b55f09a7a15972958d44fbd228214cede567", - "sha256:cdb4272678db803ddf94caa4f94f8672e9a46bae4a44f167095e4d06fec12979", - "sha256:d70916235d478404a3fa8c997b003b5f33aeac4686ac1baa767234a0f8ac2326", - "sha256:d8ce3fb0841763a89322ea0432f1f59a2d3feae07a63ea2c958b2315e1ae8adb", - "sha256:e0b214e57623a535936005797567231a12d0da0c29711eb3514bc2b3cd008d0f", - "sha256:e631c70c9280e3129f071635b81207cad85e6c08e253539467e4ead0e5b219aa", - "sha256:e78578f0c7481c850d1c969aca9a65405887003484d24f6110458fb02cca7747", - "sha256:f0ca86b525264daa5f6b192f216a0d1e860b7383e3da1c65a1908f9c02f42801", - "sha256:f1a68f4f65a9ee64b6ccccb5bf7e17db07caebd2730109cb8a95863cfa9c4e55", - "sha256:fafe841be1103f340a24977f61dee76172e4ae5f647ab9e7fd1e1fca51524f08", - "sha256:ff68fc85355532ea77559ede81f35fff79a6a5543477e168ab3a381887caea76" + "sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303", + "sha256:1289c180abd4bd4555bb927c42ee42abc3aee02b0fb2d1223fb7c6e5bef87dbe", + "sha256:1eb2085c13bce1612da8537b2d90f549c8cbb05c67e8f22854e201bde5d98a47", + "sha256:2031de0967c279df0d8a1c72b4ffc411ecd06bac607a212892757db7462fc494", + "sha256:2a7bac939fa326db1ab741c9d7f44c565a1d1e80908b3797f7f81a4f86bc8d33", + "sha256:2d5a58feb9a39f481eda4d5ca220aa8b9d4f21a41274760b9bc66bfd72595b86", + "sha256:2f9a6fab5f82ada41d56b0602606a5506aab165ca54e52bc4545028382ef1c5d", + "sha256:2fcfb5296d7877af406ba1547dfde9943b1256d8928732267e2653c26938cd9c", + "sha256:549a8e3d81df0a85226963611950b12d2d334f214436a19537b2efed61b7639a", + "sha256:598da88dfa127b666852bef6d0d796573a8cf5009ffd62104094a4fe39599565", + "sha256:5d1197e462e0364906cbc19681605cb7c036f2475c899b6f296104ad42b9f5fb", + "sha256:69328e15cfda2c392da4e713443c7dbffa1505bc9d566e71e55abe14c97ddc62", + "sha256:6a9dfa722316f4acf4460afdf5d41d5246a80e249c7ff475c43a3a1e9d75cf62", + "sha256:6b30bcb8cbfccfcf02acb8f1a261143fab622831d9c0989707e0e659f77a18e0", + "sha256:6c076be61cd0177a8433c0adcb03475baf4ee91edf5a4e550161ad57fc90f523", + "sha256:771735dc43cf8383959dc9b90aa281f0b6092321ca98677c5fb6125a6f56d58d", + "sha256:795e34e6cc065f8f498c89b894a3c6da294a936ee71e644e4bd44de048af1405", + "sha256:87afda5539d5140cb8ba9e8b8c8865cb5b1463924d38490d73d3ccfd80896b3f", + "sha256:8fb2aa3ab3728d950bcc885a2e9eff6c8fc40bc0b7bb434e555c215491bcf48b", + "sha256:a1fcb59f2f355ec350073af41d927bf83a63b50e640f4dbaa01053a28b7a7718", + "sha256:a5e7add47a5b5a40c49b3036d464e3c7802f8ae0d1e66035ea16aa5b7a3923ed", + "sha256:a73f489aebd0c2121ed974054cb2759af8a9f747de120acd2c3394cf84176ccb", + "sha256:ab26038b8375581dc832a63c948f261ae0aa21f1d34c1293469f135fa92972a5", + "sha256:b0d191db0f92dfcb1dec210ca244fdae5cbe918c6050b342d619c09d31eea0cc", + "sha256:b749a43aa51e32839c9d71dc67eb1e4221bb04af1033a32e3923d46f9effa942", + "sha256:b7ccf02d7eb340b216ec33e53a3a629856afe1c6e0ef91d84a4e6f2fb2ca70fe", + "sha256:ba5b2e6fe6ca2b7e013398bc7d7b170e21cce322d266ffcd57cca313e54fb246", + "sha256:ba5c4a8552bff16c61882db58544116d021d0b31ee7c66958d14cf386a5b5350", + "sha256:c79e6a11a07da7374f46970410b41d5e266f7f38f6a17a9c4823db80dadf4303", + "sha256:ca48477862372ac3770969b9d75f1bf66131d386dba79506c46d75e6b48c1e09", + "sha256:dea7adcc33d5d105896401a1f37d56b47d443a2b2605ff8a969a0ed5543f7e33", + "sha256:e0a16d274b588767602b7646fa05af2782576a6cf1022f4ba74cbb4db66f6ca8", + "sha256:e4129b528c6baa99a429f97ce733fff478ec955513630e61b49804b6cf9b224a", + "sha256:e5f805d2d5d0a41633651a73fa4ecdd0b3d7a49de4ec3fadf062fe16501ddbf1", + "sha256:ef6c96b2baa2100ec91a4b428f80d8f28a3c9e53568219b6c298c1125572ebc6", + "sha256:fdbdd1d630195689f325c9ef1a12900524dceb503b00a987663ff4f58669b93d" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1'", - "version": "==1.9.2" + "markers": "python_version >= '3.7'", + "version": "==1.10.12" }, "pyrsistent": { "hashes": [ @@ -317,23 +302,26 @@ "sha256:6ad50f4613289f3c4d276b6d2ac8901d776dcb929994cce93f55a69e858c595f", "sha256:7eea9b81b0ff908000a825db024313f622895bd578e8a17433e0474cd7d2da83" ], + "markers": "python_version >= '3.7'", "version": "==4.2.2" }, "python-dotenv": { "hashes": [ - "sha256:aae25dc1ebe97c420f50b81fb0e5c949659af713f31fdb63c749ca68748f34b1", - "sha256:f521bc2ac9a8e03c736f62911605c5d83970021e3fa95b37d769e2bbbe9b6172" + "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", + "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a" ], "index": "pypi", - "markers": "python_version >= '3.5'", - "version": "==0.19.0" + "markers": "python_version >= '3.8'", + "version": "==1.0.1" }, "python-multipart": { "hashes": [ - "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43" + "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132", + "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18" ], "index": "pypi", - "version": "==0.0.5" + "markers": "python_version >= '3.7'", + "version": "==0.0.6" }, "robot-server": { "editable": true, @@ -351,14 +339,6 @@ "markers": "python_version >= '3.8'", "version": "==69.0.3" }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, "sniffio": { "hashes": [ "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", @@ -369,53 +349,64 @@ }, "sqlalchemy": { "hashes": [ - "sha256:04164e0063feb7aedd9d073db0fd496edb244be40d46ea1f0d8990815e4b8c34", - "sha256:159c2f69dd6efd28e894f261ffca1100690f28210f34cfcd70b895e0ea7a64f3", - "sha256:199dc6d0068753b6a8c0bd3aceb86a3e782df118260ebc1fa981ea31ee054674", - "sha256:1bbac3e8293b34c4403d297e21e8f10d2a57756b75cff101dc62186adec725f5", - "sha256:20e9eba7fd86ef52e0df25bea83b8b518dfdf0bce09b336cfe51671f52aaaa3f", - "sha256:290cbdf19129ae520d4bdce392648c6fcdbee763bc8f750b53a5ab51880cb9c9", - "sha256:316270e5867566376e69a0ac738b863d41396e2b63274616817e1d34156dff0e", - "sha256:3f88a4ee192142eeed3fe173f673ea6ab1f5a863810a9d85dbf6c67a9bd08f97", - "sha256:4aa96e957141006181ca58e792e900ee511085b8dae06c2d08c00f108280fb8a", - "sha256:4b2bcab3a914715d332ca783e9bda13bc570d8b9ef087563210ba63082c18c16", - "sha256:576684771456d02e24078047c2567025f2011977aa342063468577d94e194b00", - "sha256:5a2e73508f939175363d8a4be9dcdc84cf16a92578d7fa86e6e4ca0e6b3667b2", - "sha256:5ba59761c19b800bc2e1c9324da04d35ef51e4ee9621ff37534bc2290d258f71", - "sha256:5dc9801ae9884e822ba942ca493642fb50f049c06b6dbe3178691fce48ceb089", - "sha256:6fdd2dc5931daab778c2b65b03df6ae68376e028a3098eb624d0909d999885bc", - "sha256:708973b5d9e1e441188124aaf13c121e5b03b6054c2df59b32219175a25aa13e", - "sha256:7ff72b3cc9242d1a1c9b84bd945907bf174d74fc2519efe6184d6390a8df478b", - "sha256:8679f9aba5ac22e7bce54ccd8a77641d3aea3e2d96e73e4356c887ebf8ff1082", - "sha256:8b9a395122770a6f08ebfd0321546d7379f43505882c7419d7886856a07caa13", - "sha256:8e1e5d96b744a4f91163290b01045430f3f32579e46d87282449e5b14d27d4ac", - "sha256:9a0195af6b9050c9322a97cf07514f66fe511968e623ca87b2df5e3cf6349615", - "sha256:9cb5698c896fa72f88e7ef04ef62572faf56809093180771d9be8d9f2e264a13", - "sha256:b3f1d9b3aa09ab9adc7f8c4b40fc3e081eb903054c9a6f9ae1633fe15ae503b4", - "sha256:bb42f9b259c33662c6a9b866012f6908a91731a419e69304e1261ba3ab87b8d1", - "sha256:bca714d831e5b8860c3ab134c93aec63d1a4f493bed20084f54e3ce9f0a3bf99", - "sha256:bedd89c34ab62565d44745212814e4b57ef1c24ad4af9b29c504ce40f0dc6558", - "sha256:bfec934aac7f9fa95fc82147a4ba5db0a8bdc4ebf1e33b585ab8860beb10232f", - "sha256:c7046f7aa2db445daccc8424f50b47a66c4039c9f058246b43796aa818f8b751", - "sha256:d7e483f4791fbda60e23926b098702340504f7684ce7e1fd2c1bf02029288423", - "sha256:dd93162615870c976dba43963a24bb418b28448fef584f30755990c134a06a55", - "sha256:e4607d2d16330757818c9d6fba322c2e80b4b112ff24295d1343a80b876eb0ed", - "sha256:e9a680d9665f88346ed339888781f5236347933906c5a56348abb8261282ec48", - "sha256:edfcf93fd92e2f9eef640b3a7a40db20fe3c1d7c2c74faa41424c63dead61b76", - "sha256:f7e4a3c0c3c596296b37f8427c467c8e4336dc8d50f8ed38042e8ba79507b2c9", - "sha256:fff677fa4522dafb5a5e2c0cf909790d5d367326321aeabc0dffc9047cb235bd" + "sha256:0525c4905b4b52d8ccc3c203c9d7ab2a80329ffa077d4bacf31aefda7604dc65", + "sha256:0535d5b57d014d06ceeaeffd816bb3a6e2dddeb670222570b8c4953e2d2ea678", + "sha256:0892e7ac8bc76da499ad3ee8de8da4d7905a3110b952e2a35a940dab1ffa550e", + "sha256:0d661cff58c91726c601cc0ee626bf167b20cc4d7941c93c5f3ac28dc34ddbea", + "sha256:1980e6eb6c9be49ea8f89889989127daafc43f0b1b6843d71efab1514973cca0", + "sha256:1a09d5bd1a40d76ad90e5570530e082ddc000e1d92de495746f6257dc08f166b", + "sha256:245c67c88e63f1523e9216cad6ba3107dea2d3ee19adc359597a628afcabfbcb", + "sha256:2ad16880ccd971ac8e570550fbdef1385e094b022d6fc85ef3ce7df400dddad3", + "sha256:2be4e6294c53f2ec8ea36486b56390e3bcaa052bf3a9a47005687ccf376745d1", + "sha256:2c55040d8ea65414de7c47f1a23823cd9f3fad0dc93e6b6b728fee81230f817b", + "sha256:352df882088a55293f621328ec33b6ffca936ad7f23013b22520542e1ab6ad1b", + "sha256:3823dda635988e6744d4417e13f2e2b5fe76c4bf29dd67e95f98717e1b094cad", + "sha256:38ef80328e3fee2be0a1abe3fe9445d3a2e52a1282ba342d0dab6edf1fef4707", + "sha256:39b02b645632c5fe46b8dd30755682f629ffbb62ff317ecc14c998c21b2896ff", + "sha256:3b0cd89a7bd03f57ae58263d0f828a072d1b440c8c2949f38f3b446148321171", + "sha256:3ec7a0ed9b32afdf337172678a4a0e6419775ba4e649b66f49415615fa47efbd", + "sha256:3f0ef620ecbab46e81035cf3dedfb412a7da35340500ba470f9ce43a1e6c423b", + "sha256:50e074aea505f4427151c286955ea025f51752fa42f9939749336672e0674c81", + "sha256:55e699466106d09f028ab78d3c2e1f621b5ef2c8694598242259e4515715da7c", + "sha256:5e180fff133d21a800c4f050733d59340f40d42364fcb9d14f6a67764bdc48d2", + "sha256:6cacc0b2dd7d22a918a9642fc89840a5d3cee18a0e1fe41080b1141b23b10916", + "sha256:7af40425ac535cbda129d9915edcaa002afe35d84609fd3b9d6a8c46732e02ee", + "sha256:7d8139ca0b9f93890ab899da678816518af74312bb8cd71fb721436a93a93298", + "sha256:7deeae5071930abb3669b5185abb6c33ddfd2398f87660fafdb9e6a5fb0f3f2f", + "sha256:86a22143a4001f53bf58027b044da1fb10d67b62a785fc1390b5c7f089d9838c", + "sha256:8ca484ca11c65e05639ffe80f20d45e6be81fbec7683d6c9a15cd421e6e8b340", + "sha256:8d1d7d63e5d2f4e92a39ae1e897a5d551720179bb8d1254883e7113d3826d43c", + "sha256:8e702e7489f39375601c7ea5a0bef207256828a2bc5986c65cb15cd0cf097a87", + "sha256:a055ba17f4675aadcda3005df2e28a86feb731fdcc865e1f6b4f209ed1225cba", + "sha256:a33cb3f095e7d776ec76e79d92d83117438b6153510770fcd57b9c96f9ef623d", + "sha256:a61184c7289146c8cff06b6b41807c6994c6d437278e72cf00ff7fe1c7a263d1", + "sha256:af55cc207865d641a57f7044e98b08b09220da3d1b13a46f26487cc2f898a072", + "sha256:b00cf0471888823b7a9f722c6c41eb6985cf34f077edcf62695ac4bed6ec01ee", + "sha256:b03850c290c765b87102959ea53299dc9addf76ca08a06ea98383348ae205c99", + "sha256:b97fd5bb6b7c1a64b7ac0632f7ce389b8ab362e7bd5f60654c2a418496be5d7f", + "sha256:c37bc677690fd33932182b85d37433845de612962ed080c3e4d92f758d1bd894", + "sha256:cecb66492440ae8592797dd705a0cbaa6abe0555f4fa6c5f40b078bd2740fc6b", + "sha256:d0a83afab5e062abffcdcbcc74f9d3ba37b2385294dd0927ad65fc6ebe04e054", + "sha256:d3cf56cc36d42908495760b223ca9c2c0f9f0002b4eddc994b24db5fcb86a9e4", + "sha256:e646b19f47d655261b22df9976e572f588185279970efba3d45c377127d35349", + "sha256:e7908c2025eb18394e32d65dd02d2e37e17d733cdbe7d78231c2b6d7eb20cdb9", + "sha256:e8f2df79a46e130235bc5e1bbef4de0583fb19d481eaa0bffa76e8347ea45ec6", + "sha256:eaeeb2464019765bc4340214fca1143081d49972864773f3f1e95dba5c7edc7d", + "sha256:eb18549b770351b54e1ab5da37d22bc530b8bfe2ee31e22b9ebe650640d2ef12", + "sha256:f2e5b6f5cf7c18df66d082604a1d9c7a2d18f7d1dbe9514a2afaccbb51cc4fc3", + "sha256:f8cafa6f885a0ff5e39efa9325195217bb47d5929ab0051636610d24aef45ade" ], "index": "pypi", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.4.32" + "version": "==1.4.51" }, "starlette": { "hashes": [ - "sha256:3c8e48e52736b3161e34c9f0e8153b4f32ec5d8995a3ee1d59410d92f75162ed", - "sha256:7d49f4a27f8742262ef1470608c59ddbc66baf37c148e938c7038e6bc7a998aa" + "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75", + "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91" ], - "markers": "python_version >= '3.6'", - "version": "==0.14.2" + "markers": "python_version >= '3.7'", + "version": "==0.27.0" }, "systemd-python": { "hashes": [ @@ -435,11 +426,12 @@ }, "uvicorn": { "hashes": [ - "sha256:2a76bb359171a504b3d1c853409af3adbfa5cef374a4a59e5881945a97a93eae", - "sha256:45ad7dfaaa7d55cab4cd1e85e03f27e9d60bc067ddc59db52a2b0aeca8870292" + "sha256:4b85ba02b8a20429b9b205d015cbeb788a12da527f731811b643fd739ef90d5f", + "sha256:54898fcd80c13ff1cd28bf77b04ec9dbd8ff60c5259b499b4b12bb0917f22907" ], "index": "pypi", - "version": "==0.14.0" + "markers": "python_version >= '3.8'", + "version": "==0.27.0.post1" }, "wrapt": { "hashes": [ @@ -519,12 +511,12 @@ }, "wsproto": { "hashes": [ - "sha256:868776f8456997ad0d9720f7322b746bbe9193751b5b290b7f924659377c8c38", - "sha256:d8345d1808dd599b5ffb352c25a367adb6157e664e140dbecba3f9bc007edb9f" + "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", + "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1'", - "version": "==1.0.0" + "markers": "python_full_version >= '3.7.0'", + "version": "==1.2.0" }, "zipp": { "hashes": [ @@ -539,12 +531,12 @@ "develop": { "anyio": { "hashes": [ - "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b", - "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be" + "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780", + "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5" ], "index": "pypi", - "markers": "python_full_version >= '3.6.2'", - "version": "==3.6.1" + "markers": "python_version >= '3.7'", + "version": "==3.7.1" }, "atomicwrites": { "hashes": [ @@ -594,11 +586,11 @@ }, "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "version": "==2024.2.2" }, "charset-normalizer": { "hashes": [ @@ -626,6 +618,9 @@ "version": "==0.4.4" }, "coverage": { + "extras": [ + "toml" + ], "hashes": [ "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61", "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1", @@ -716,38 +711,39 @@ }, "flake8": { "hashes": [ - "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", - "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" + "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132", + "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.9.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==7.0.0" }, "flake8-annotations": { "hashes": [ - "sha256:0d6cd2e770b5095f09689c9d84cc054c51b929c41a68969ea1beb4b825cac515", - "sha256:d10c4638231f8a50c0a597c4efce42bd7b7d85df4f620a0ddaca526138936a4f" + "sha256:af78e3216ad800d7e144745ece6df706c81b3255290cbf870e54879d495e8ade", + "sha256:ff37375e71e3b83f2a5a04d443c41e2c407de557a884f3300a7fa32f3c41cb0a" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1' and python_full_version < '4.0.0'", - "version": "==2.6.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==3.0.1" }, "flake8-docstrings": { "hashes": [ - "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde", - "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b" + "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af", + "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75" ], "index": "pypi", - "version": "==1.6.0" + "markers": "python_version >= '3.7'", + "version": "==1.7.0" }, "flake8-noqa": { "hashes": [ - "sha256:26d92ca6b72dec732d294e587a2bdeb66dab01acc609ed6a064693d6baa4e789", - "sha256:445618162e0bbae1b9d983326d4e39066c5c6de71ba0c444ca2d4d1fa5b2cdb7" + "sha256:4465e16a19be433980f6f563d05540e2e54797eb11facb9feb50fed60624dc45", + "sha256:771765ab27d1efd157528379acd15131147f9ae578a72d17fb432ca197881243" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.2.9" + "version": "==1.4.0" }, "graphviz": { "hashes": [ @@ -768,20 +764,20 @@ }, "httpcore": { "hashes": [ - "sha256:036f960468759e633574d7c121afba48af6419615d36ab8ede979f1ad6276fa3", - "sha256:369aa481b014cf046f7067fddd67d00560f2f00426e79569d99cb11245134af0" + "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7", + "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535" ], - "markers": "python_version >= '3.6'", - "version": "==0.13.7" + "markers": "python_version >= '3.8'", + "version": "==1.0.2" }, "httpx": { "hashes": [ - "sha256:979afafecb7d22a1d10340bafb403cf2cb75aff214426ff206521fc79d26408c", - "sha256:9f99c15d33642d38bce8405df088c1c4cfd940284b4290cacbfb02e64f4877c6" + "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf", + "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==0.18.2" + "markers": "python_version >= '3.8'", + "version": "==0.26.0" }, "idna": { "hashes": [ @@ -802,65 +798,78 @@ }, "jmespath": { "hashes": [ - "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9", - "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f" + "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", + "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.0" + "markers": "python_version >= '3.7'", + "version": "==1.0.1" }, "jsonschema": { "hashes": [ - "sha256:5f9c0a719ca2ce14c5de2fd350a64fd2d13e8539db29836a86adc990bb1a068f", - "sha256:8d4a2b7b6c2237e0199c8ea1a6d3e05bf118e289ae2b9d7ba444182a2959560d" + "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d", + "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6" + ], + "markers": "python_version >= '3.7'", + "version": "==4.17.3" + }, + "jsonschema-specifications": { + "hashes": [ + "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc", + "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c" ], - "version": "==3.0.2" + "markers": "python_version >= '3.8'", + "version": "==2023.12.1" }, "mccabe": { "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "version": "==0.6.1" + "markers": "python_version >= '3.6'", + "version": "==0.7.0" }, "mock": { "hashes": [ - "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62", - "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc" + "sha256:06f18d7d65b44428202b145a9a36e99c2ee00d1eb992df0caf881d4664377891", + "sha256:0e0bc5ba78b8db3667ad636d964eb963dc97a59f04c6f6214c5f0e4a8f726c56" ], "index": "pypi", "markers": "python_version >= '3.6'", - "version": "==4.0.3" + "version": "==5.0.2" }, "mypy": { "hashes": [ - "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", - "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", - "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", - "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", - "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", - "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", - "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", - "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", - "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", - "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", - "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", - "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", - "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", - "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", - "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", - "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", - "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", - "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", - "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", - "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", - "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", - "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", - "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", - "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" + "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6", + "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d", + "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02", + "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d", + "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3", + "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3", + "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3", + "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66", + "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259", + "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835", + "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd", + "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d", + "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8", + "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07", + "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b", + "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e", + "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6", + "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae", + "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9", + "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d", + "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a", + "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592", + "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218", + "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817", + "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4", + "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410", + "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.981" + "markers": "python_version >= '3.8'", + "version": "==1.8.0" }, "mypy-extensions": { "hashes": [ @@ -902,11 +911,11 @@ }, "platformdirs": { "hashes": [ - "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", - "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", + "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "pluggy": { "hashes": [ @@ -926,11 +935,11 @@ }, "pycodestyle": { "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" + "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.7.0" + "markers": "python_version >= '3.8'", + "version": "==2.11.1" }, "pydocstyle": { "hashes": [ @@ -942,11 +951,11 @@ }, "pyflakes": { "hashes": [ - "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", - "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" + "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", + "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.3.1" + "markers": "python_version >= '3.8'", + "version": "==3.2.0" }, "pyjwt": { "hashes": [ @@ -963,44 +972,6 @@ ], "version": "==1.8.0" }, - "pyrsistent": { - "hashes": [ - "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f", - "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e", - "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958", - "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34", - "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca", - "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d", - "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d", - "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4", - "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714", - "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf", - "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee", - "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8", - "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224", - "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d", - "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054", - "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656", - "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7", - "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423", - "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce", - "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e", - "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3", - "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0", - "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f", - "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b", - "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce", - "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a", - "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174", - "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86", - "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f", - "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b", - "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98", - "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022" - ], - "markers": "python_version >= '3.8'", - "version": "==0.20.0" - }, "pytest": { "hashes": [ "sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e", @@ -1021,12 +992,12 @@ }, "pytest-cov": { "hashes": [ - "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191", - "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e" + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.10.1" + "markers": "python_version >= '3.7'", + "version": "==4.1.0" }, "pytest-forked": { "hashes": [ @@ -1055,12 +1026,27 @@ }, "python-box": { "hashes": [ - "sha256:60ae9156de34cf92b899bd099580950df70a5b0813e67a3310a1cdd1976457fa", - "sha256:b68e0f8abc86f3deda751b3390f64df64a0989459de51ba4db949662a7b4d8ac" + "sha256:11cbe62f0dace8a6e2a10d210a5e87b99ad1a1286865568862516794c923a988", + "sha256:1d29eafaa287857751e27fbe9a08dd856480f0037fe988b221eba4dac33e5852", + "sha256:3638d3559f19ece7fa29f6a6550bc64696cd3b65e3d4154df07a3d06982252ff", + "sha256:3f0036f91e13958d2b37d2bc74c1197aa36ffd66755342eb64910f63d8a2990f", + "sha256:53998c3b95e31d1f31e46279ef1d27ac30b137746927260901ee61457f8468a0", + "sha256:594b0363b187df855ff8649488b1301dddbbeea769629b7caeb584efe779b841", + "sha256:6e7c243b356cb36e2c0f0e5ed7850969fede6aa812a7f501de7768996c7744d7", + "sha256:7b73f26e40a7adc57b9e39f5687d026dfa8a336f48aefaf852a223b4e37392ad", + "sha256:9dbd92b67c443a97326273c9239fce04d3b6958be815d293f96ab65bc4a9dae7", + "sha256:ab13208b053525ef154a36a4a52873b98a12b18b946edd4c939a4d5080e9a218", + "sha256:ac44b3b85714a4575cc273b5dbd39ef739f938ef6c522d6757704a29e7797d16", + "sha256:af6bcee7e1abe9251e9a41ca9ab677e1f679f6059321cfbae7e78a3831e0b736", + "sha256:bdec0a5f5a17b01fc538d292602a077aa8c641fb121e1900dff0591791af80e8", + "sha256:c14aa4e72bf30f4d573e62ff8030a86548603a100c3fb534561dbedf4a83f454", + "sha256:d199cd289b4f4d053770eadd70217c76214aac30b92a23adfb9627fd8558d300", + "sha256:ed6d7fe47d756dc2d9dea448702cea103716580a2efee7c859954929295fe28e", + "sha256:fa4696b5e09ccf695bf05c16bb5ca1fcc95a141a71a31eb262eee8e2ac07189a" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==5.4.1" + "markers": "python_version >= '3.7'", + "version": "==6.1.0" }, "python-dateutil": { "hashes": [ @@ -1127,6 +1113,14 @@ "markers": "python_version >= '3.6'", "version": "==6.0.1" }, + "referencing": { + "hashes": [ + "sha256:39240f2ecc770258f28b642dd47fd74bc8b02484de54e1882b74b35ebd779bd5", + "sha256:c775fedf74bc0f9189c2a3be1c12fd03e8c23f4d371dce795df44e06c5b412f7" + ], + "markers": "python_version >= '3.8'", + "version": "==0.33.0" + }, "requests": { "hashes": [ "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", @@ -1136,15 +1130,110 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "version": "==2.27.1" }, - "rfc3986": { - "extras": [ - "idna2008" - ], - "hashes": [ - "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835", - "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97" + "rpds-py": { + "hashes": [ + "sha256:01f58a7306b64e0a4fe042047dd2b7d411ee82e54240284bab63e325762c1147", + "sha256:0210b2668f24c078307260bf88bdac9d6f1093635df5123789bfee4d8d7fc8e7", + "sha256:02866e060219514940342a1f84303a1ef7a1dad0ac311792fbbe19b521b489d2", + "sha256:0387ce69ba06e43df54e43968090f3626e231e4bc9150e4c3246947567695f68", + "sha256:060f412230d5f19fc8c8b75f315931b408d8ebf56aec33ef4168d1b9e54200b1", + "sha256:071bc28c589b86bc6351a339114fb7a029f5cddbaca34103aa573eba7b482382", + "sha256:0bfb09bf41fe7c51413f563373e5f537eaa653d7adc4830399d4e9bdc199959d", + "sha256:10162fe3f5f47c37ebf6d8ff5a2368508fe22007e3077bf25b9c7d803454d921", + "sha256:149c5cd24f729e3567b56e1795f74577aa3126c14c11e457bec1b1c90d212e38", + "sha256:1701fc54460ae2e5efc1dd6350eafd7a760f516df8dbe51d4a1c79d69472fbd4", + "sha256:1957a2ab607f9added64478a6982742eb29f109d89d065fa44e01691a20fc20a", + "sha256:1a746a6d49665058a5896000e8d9d2f1a6acba8a03b389c1e4c06e11e0b7f40d", + "sha256:1bfcad3109c1e5ba3cbe2f421614e70439f72897515a96c462ea657261b96518", + "sha256:1d36b2b59e8cc6e576f8f7b671e32f2ff43153f0ad6d0201250a7c07f25d570e", + "sha256:1db228102ab9d1ff4c64148c96320d0be7044fa28bd865a9ce628ce98da5973d", + "sha256:1dc29db3900cb1bb40353772417800f29c3d078dbc8024fd64655a04ee3c4bdf", + "sha256:1e626b365293a2142a62b9a614e1f8e331b28f3ca57b9f05ebbf4cf2a0f0bdc5", + "sha256:1f3c3461ebb4c4f1bbc70b15d20b565759f97a5aaf13af811fcefc892e9197ba", + "sha256:20de7b7179e2031a04042e85dc463a93a82bc177eeba5ddd13ff746325558aa6", + "sha256:24e4900a6643f87058a27320f81336d527ccfe503984528edde4bb660c8c8d59", + "sha256:2528ff96d09f12e638695f3a2e0c609c7b84c6df7c5ae9bfeb9252b6fa686253", + "sha256:25f071737dae674ca8937a73d0f43f5a52e92c2d178330b4c0bb6ab05586ffa6", + "sha256:270987bc22e7e5a962b1094953ae901395e8c1e1e83ad016c5cfcfff75a15a3f", + "sha256:292f7344a3301802e7c25c53792fae7d1593cb0e50964e7bcdcc5cf533d634e3", + "sha256:2953937f83820376b5979318840f3ee47477d94c17b940fe31d9458d79ae7eea", + "sha256:2a792b2e1d3038daa83fa474d559acfd6dc1e3650ee93b2662ddc17dbff20ad1", + "sha256:2a7b2f2f56a16a6d62e55354dd329d929560442bd92e87397b7a9586a32e3e76", + "sha256:2f4eb548daf4836e3b2c662033bfbfc551db58d30fd8fe660314f86bf8510b93", + "sha256:3664d126d3388a887db44c2e293f87d500c4184ec43d5d14d2d2babdb4c64cad", + "sha256:3677fcca7fb728c86a78660c7fb1b07b69b281964673f486ae72860e13f512ad", + "sha256:380e0df2e9d5d5d339803cfc6d183a5442ad7ab3c63c2a0982e8c824566c5ccc", + "sha256:3ac732390d529d8469b831949c78085b034bff67f584559340008d0f6041a049", + "sha256:4128980a14ed805e1b91a7ed551250282a8ddf8201a4e9f8f5b7e6225f54170d", + "sha256:4341bd7579611cf50e7b20bb8c2e23512a3dc79de987a1f411cb458ab670eb90", + "sha256:436474f17733c7dca0fbf096d36ae65277e8645039df12a0fa52445ca494729d", + "sha256:4dc889a9d8a34758d0fcc9ac86adb97bab3fb7f0c4d29794357eb147536483fd", + "sha256:4e21b76075c01d65d0f0f34302b5a7457d95721d5e0667aea65e5bb3ab415c25", + "sha256:516fb8c77805159e97a689e2f1c80655c7658f5af601c34ffdb916605598cda2", + "sha256:5576ee2f3a309d2bb403ec292d5958ce03953b0e57a11d224c1f134feaf8c40f", + "sha256:5a024fa96d541fd7edaa0e9d904601c6445e95a729a2900c5aec6555fe921ed6", + "sha256:5d0e8a6434a3fbf77d11448c9c25b2f25244226cfbec1a5159947cac5b8c5fa4", + "sha256:5e7d63ec01fe7c76c2dbb7e972fece45acbb8836e72682bde138e7e039906e2c", + "sha256:60e820ee1004327609b28db8307acc27f5f2e9a0b185b2064c5f23e815f248f8", + "sha256:637b802f3f069a64436d432117a7e58fab414b4e27a7e81049817ae94de45d8d", + "sha256:65dcf105c1943cba45d19207ef51b8bc46d232a381e94dd38719d52d3980015b", + "sha256:698ea95a60c8b16b58be9d854c9f993c639f5c214cf9ba782eca53a8789d6b19", + "sha256:70fcc6c2906cfa5c6a552ba7ae2ce64b6c32f437d8f3f8eea49925b278a61453", + "sha256:720215373a280f78a1814becb1312d4e4d1077b1202a56d2b0815e95ccb99ce9", + "sha256:7450dbd659fed6dd41d1a7d47ed767e893ba402af8ae664c157c255ec6067fde", + "sha256:7b7d9ca34542099b4e185b3c2a2b2eda2e318a7dbde0b0d83357a6d4421b5296", + "sha256:7fbd70cb8b54fe745301921b0816c08b6d917593429dfc437fd024b5ba713c58", + "sha256:81038ff87a4e04c22e1d81f947c6ac46f122e0c80460b9006e6517c4d842a6ec", + "sha256:810685321f4a304b2b55577c915bece4c4a06dfe38f6e62d9cc1d6ca8ee86b99", + "sha256:82ada4a8ed9e82e443fcef87e22a3eed3654dd3adf6e3b3a0deb70f03e86142a", + "sha256:841320e1841bb53fada91c9725e766bb25009cfd4144e92298db296fb6c894fb", + "sha256:8587fd64c2a91c33cdc39d0cebdaf30e79491cc029a37fcd458ba863f8815383", + "sha256:8ffe53e1d8ef2520ebcf0c9fec15bb721da59e8ef283b6ff3079613b1e30513d", + "sha256:9051e3d2af8f55b42061603e29e744724cb5f65b128a491446cc029b3e2ea896", + "sha256:91e5a8200e65aaac342a791272c564dffcf1281abd635d304d6c4e6b495f29dc", + "sha256:93432e747fb07fa567ad9cc7aaadd6e29710e515aabf939dfbed8046041346c6", + "sha256:938eab7323a736533f015e6069a7d53ef2dcc841e4e533b782c2bfb9fb12d84b", + "sha256:9584f8f52010295a4a417221861df9bea4c72d9632562b6e59b3c7b87a1522b7", + "sha256:9737bdaa0ad33d34c0efc718741abaafce62fadae72c8b251df9b0c823c63b22", + "sha256:99da0a4686ada4ed0f778120a0ea8d066de1a0a92ab0d13ae68492a437db78bf", + "sha256:99f567dae93e10be2daaa896e07513dd4bf9c2ecf0576e0533ac36ba3b1d5394", + "sha256:9bdf1303df671179eaf2cb41e8515a07fc78d9d00f111eadbe3e14262f59c3d0", + "sha256:9f0e4dc0f17dcea4ab9d13ac5c666b6b5337042b4d8f27e01b70fae41dd65c57", + "sha256:a000133a90eea274a6f28adc3084643263b1e7c1a5a66eb0a0a7a36aa757ed74", + "sha256:a3264e3e858de4fc601741498215835ff324ff2482fd4e4af61b46512dd7fc83", + "sha256:a71169d505af63bb4d20d23a8fbd4c6ce272e7bce6cc31f617152aa784436f29", + "sha256:a967dd6afda7715d911c25a6ba1517975acd8d1092b2f326718725461a3d33f9", + "sha256:aa5bfb13f1e89151ade0eb812f7b0d7a4d643406caaad65ce1cbabe0a66d695f", + "sha256:ae35e8e6801c5ab071b992cb2da958eee76340e6926ec693b5ff7d6381441745", + "sha256:b686f25377f9c006acbac63f61614416a6317133ab7fafe5de5f7dc8a06d42eb", + "sha256:b760a56e080a826c2e5af09002c1a037382ed21d03134eb6294812dda268c811", + "sha256:b86b21b348f7e5485fae740d845c65a880f5d1eda1e063bc59bef92d1f7d0c55", + "sha256:b9412abdf0ba70faa6e2ee6c0cc62a8defb772e78860cef419865917d86c7342", + "sha256:bd345a13ce06e94c753dab52f8e71e5252aec1e4f8022d24d56decd31e1b9b23", + "sha256:be22ae34d68544df293152b7e50895ba70d2a833ad9566932d750d3625918b82", + "sha256:bf046179d011e6114daf12a534d874958b039342b347348a78b7cdf0dd9d6041", + "sha256:c3d2010656999b63e628a3c694f23020322b4178c450dc478558a2b6ef3cb9bb", + "sha256:c64602e8be701c6cfe42064b71c84ce62ce66ddc6422c15463fd8127db3d8066", + "sha256:d65e6b4f1443048eb7e833c2accb4fa7ee67cc7d54f31b4f0555b474758bee55", + "sha256:d8bbd8e56f3ba25a7d0cf980fc42b34028848a53a0e36c9918550e0280b9d0b6", + "sha256:da1ead63368c04a9bded7904757dfcae01eba0e0f9bc41d3d7f57ebf1c04015a", + "sha256:dbbb95e6fc91ea3102505d111b327004d1c4ce98d56a4a02e82cd451f9f57140", + "sha256:dbc56680ecf585a384fbd93cd42bc82668b77cb525343170a2d86dafaed2a84b", + "sha256:df3b6f45ba4515632c5064e35ca7f31d51d13d1479673185ba8f9fefbbed58b9", + "sha256:dfe07308b311a8293a0d5ef4e61411c5c20f682db6b5e73de6c7c8824272c256", + "sha256:e796051f2070f47230c745d0a77a91088fbee2cc0502e9b796b9c6471983718c", + "sha256:efa767c220d94aa4ac3a6dd3aeb986e9f229eaf5bce92d8b1b3018d06bed3772", + "sha256:f0b8bf5b8db49d8fd40f54772a1dcf262e8be0ad2ab0206b5a2ec109c176c0a4", + "sha256:f175e95a197f6a4059b50757a3dca33b32b61691bdbd22c29e8a8d21d3914cae", + "sha256:f2f3b28b40fddcb6c1f1f6c88c6f3769cd933fa493ceb79da45968a21dccc920", + "sha256:f6c43b6f97209e370124baf2bf40bb1e8edc25311a158867eb1c3a5d449ebc7a", + "sha256:f7f4cb1f173385e8a39c29510dd11a78bf44e360fb75610594973f5ea141028b", + "sha256:fad059a4bd14c45776600d223ec194e77db6c20255578bb5bcdd7c18fd169361", + "sha256:ff1dcb8e8bc2261a088821b2595ef031c91d499a0c1b031c152d43fe0a6ecec8", + "sha256:ffee088ea9b593cc6160518ba9bd319b5475e5f3e578e4552d63818773c6f56a" ], - "version": "==1.5.0" + "markers": "python_version >= '3.8'", + "version": "==0.17.1" }, "ruamel.yaml": { "hashes": [ @@ -1210,14 +1299,6 @@ "markers": "python_version < '3.13' and platform_python_implementation == 'CPython'", "version": "==0.2.8" }, - "setuptools": { - "hashes": [ - "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05", - "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78" - ], - "markers": "python_version >= '3.8'", - "version": "==69.0.3" - }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -1252,19 +1333,20 @@ }, "stevedore": { "hashes": [ - "sha256:4e485ad9b087d1ce475b747d8abd21c328cd7410b5a7a70ca73431be29dc5bac", - "sha256:937f644e83276ca231e21376b400ffe56637d24258bbcc47db6e80be1f60894f" + "sha256:7f8aeb6e3f90f96832c301bff21a7eb5eefbe894c88c506483d355565d88cc1a", + "sha256:aa6436565c069b2946fe4ebff07f5041e0c8bf18c7376dd29edf80cf7d524e4e" ], - "markers": "python_version >= '3.6'", - "version": "==3.3.3" + "markers": "python_version >= '3.8'", + "version": "==4.1.1" }, "tavern": { "hashes": [ - "sha256:18ea77cfe0d0be1b99900b447487279e7769c21e23b53e9865be40035da71fc6" + "sha256:056c4c45e27c97552ae9a3eb6a249701820a09465b4131cc4e71489166d8442d", + "sha256:21ce0c29f9e15e4b613f5f43df6da96ed0e115e5d52b4b8c1501e898708e9d35" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==1.25.2" + "markers": "python_version >= '3.8'", + "version": "==2.9.1" }, "tomli": { "hashes": [ @@ -1276,11 +1358,12 @@ }, "types-mock": { "hashes": [ - "sha256:1a470543be8de673e2ea14739622de3bfb8c9b10429f50338ba9ca1e868c15e9", - "sha256:1ad09970f4f5ec45a138ab1e88d032f010e851bccef7765b34737ed390bbc5c8" + "sha256:13ca379d5710ccb3f18f69ade5b08881874cb83383d8fb49b1d4dac9d5c5d090", + "sha256:3d116955495935b0bcba14954b38d97e507cd43eca3e3700fc1b8e4f5c6bf2c7" ], "index": "pypi", - "version": "==4.0.1" + "markers": "python_version >= '3.8'", + "version": "==5.1.0.20240106" }, "types-paho-mqtt": { "hashes": [ @@ -1293,11 +1376,18 @@ }, "types-requests": { "hashes": [ - "sha256:a5a305b43ea57bf64d6731f89816946a405b591eff6de28d4c0fd58422cee779", - "sha256:e21541c0f55c066c491a639309159556dd8c5833e49fcde929c4c47bdb0002ee" + "sha256:1b6cf6a2bf57fd8018c1b636b69762900466fafddfb62e1330e092f3d4b0966a", + "sha256:6fab97b99fea52b9c7b466a4dd93e06bb325bc7e7420475e87831026a8dd35cc" ], "index": "pypi", - "version": "==2.25.6" + "version": "==2.27.31" + }, + "types-urllib3": { + "hashes": [ + "sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f", + "sha256:9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e" + ], + "version": "==1.26.25.14" }, "typing-extensions": { "hashes": [ diff --git a/robot-server/robot_server/app_setup.py b/robot-server/robot_server/app_setup.py index b628c7eb2d8..191ba339a41 100644 --- a/robot-server/robot_server/app_setup.py +++ b/robot-server/robot_server/app_setup.py @@ -74,8 +74,7 @@ async def on_startup() -> None: if settings.persistence_directory == "automatically_make_temporary": persistence_directory: Optional[Path] = None else: - # mypy won't narrow out the sentinel literal from the above if, sadly - persistence_directory = settings.persistence_directory # type: ignore[assignment] + persistence_directory = settings.persistence_directory initialize_logging() initialize_task_runner(app_state=app.state) diff --git a/robot-server/robot_server/commands/router.py b/robot-server/robot_server/commands/router.py index d831d889424..c96a492b815 100644 --- a/robot-server/robot_server/commands/router.py +++ b/robot-server/robot_server/commands/router.py @@ -54,6 +54,7 @@ class CommandNotFound(ErrorDetails): " simple, stateless control of the robot. For complex control," " create a run with ``POST /runs`` and issue commands on that run." ), + response_model=SimpleBody[StatelessCommand], status_code=status.HTTP_201_CREATED, responses={ status.HTTP_201_CREATED: {"model": SimpleBody[StatelessCommand]}, @@ -126,6 +127,7 @@ async def create_command( "Get a list of commands that have been run on the device since boot." " Only returns command run via the `/commands` endpoint." ), + response_model=SimpleMultiBody[StatelessCommand], responses={ status.HTTP_200_OK: {"model": SimpleMultiBody[StatelessCommand]}, status.HTTP_409_CONFLICT: {"model": ErrorBody[RunActive]}, @@ -170,6 +172,7 @@ async def get_commands_list( "Get a single stateless command that has been queued or executed." " Only returns command run via the `/commands` endpoint." ), + response_model=SimpleBody[StatelessCommand], responses={ status.HTTP_200_OK: {"model": SimpleBody[StatelessCommand]}, status.HTTP_404_NOT_FOUND: {"model": ErrorBody[CommandNotFound]}, diff --git a/robot-server/robot_server/deck_configuration/router.py b/robot-server/robot_server/deck_configuration/router.py index 6b1a3fc33c8..054390486fe 100644 --- a/robot-server/robot_server/deck_configuration/router.py +++ b/robot-server/robot_server/deck_configuration/router.py @@ -24,7 +24,8 @@ router = fastapi.APIRouter() -@router.put( +@PydanticResponse.wrap_route( + router.put, path="/deck_configuration", summary="Set the deck configuration", description=( @@ -82,8 +83,9 @@ async def put_deck_configuration( # noqa: D103 ) -@router.get( - "/deck_configuration", +@PydanticResponse.wrap_route( + router.get, + path="/deck_configuration", summary="Get the deck configuration", description=( "Get the robot's current deck configuration." diff --git a/robot-server/robot_server/instruments/instrument_models.py b/robot-server/robot_server/instruments/instrument_models.py index f02b8bcf303..78bdd918938 100644 --- a/robot-server/robot_server/instruments/instrument_models.py +++ b/robot-server/robot_server/instruments/instrument_models.py @@ -100,7 +100,7 @@ class PipetteData(BaseModel): class PipetteState(BaseModel): """State from an attached pipette.""" - tipDetected: bool = Field( + tipDetected: Optional[bool] = Field( None, description="Physical state of the tip photointerrupter on the Flex. Null for OT-2", alias="tip_detected", diff --git a/robot-server/robot_server/instruments/router.py b/robot-server/robot_server/instruments/router.py index 326e1bb3caa..f8e7448d5f1 100644 --- a/robot-server/robot_server/instruments/router.py +++ b/robot-server/robot_server/instruments/router.py @@ -251,7 +251,8 @@ async def _get_attached_instruments_ot2( ) -@instruments_router.get( +@PydanticResponse.wrap_route( + instruments_router.get, path="/instruments", summary="Get attached instruments.", description="Get a list of all instruments (pipettes & gripper) currently attached" diff --git a/robot-server/robot_server/maintenance_runs/router/base_router.py b/robot-server/robot_server/maintenance_runs/router/base_router.py index 93c448e8390..905c118688b 100644 --- a/robot-server/robot_server/maintenance_runs/router/base_router.py +++ b/robot-server/robot_server/maintenance_runs/router/base_router.py @@ -121,7 +121,8 @@ async def get_run_data_from_url( return run_data -@base_router.post( +@PydanticResponse.wrap_route( + base_router.post, path="/maintenance_runs", summary="Create a maintenance run", description=dedent( @@ -188,7 +189,8 @@ async def create_run( ) -@base_router.get( +@PydanticResponse.wrap_route( + base_router.get, path="/maintenance_runs/current_run", summary="Get the current maintenance run", description="Get the currently active maintenance run, if any", @@ -224,7 +226,8 @@ async def get_current_run( ) -@base_router.get( +@PydanticResponse.wrap_route( + base_router.get, path="/maintenance_runs/{runId}", summary="Get a maintenance run", description="Get a specific run by its unique identifier.", @@ -247,7 +250,8 @@ async def get_run( ) -@base_router.delete( +@PydanticResponse.wrap_route( + base_router.delete, path="/maintenance_runs/{runId}", summary="Delete a run", description="Delete a specific run by its unique identifier.", diff --git a/robot-server/robot_server/maintenance_runs/router/commands_router.py b/robot-server/robot_server/maintenance_runs/router/commands_router.py index 09eb4cce0bf..5742fbc302c 100644 --- a/robot-server/robot_server/maintenance_runs/router/commands_router.py +++ b/robot-server/robot_server/maintenance_runs/router/commands_router.py @@ -115,7 +115,8 @@ async def get_current_run_engine_from_url( return engine_store.engine -@commands_router.post( +@PydanticResponse.wrap_route( + commands_router.post, path="/maintenance_runs/{runId}/commands", summary="Enqueue a command", description=textwrap.dedent( @@ -203,7 +204,8 @@ async def create_run_command( ) -@commands_router.get( +@PydanticResponse.wrap_route( + commands_router.get, path="/maintenance_runs/{runId}/commands", summary="Get a list of all commands in the run", description=( @@ -297,7 +299,8 @@ async def get_run_commands( ) -@commands_router.get( +@PydanticResponse.wrap_route( + commands_router.get, path="/maintenance_runs/{runId}/commands/{commandId}", summary="Get full details about a specific command in the run", description=( diff --git a/robot-server/robot_server/maintenance_runs/router/labware_router.py b/robot-server/robot_server/maintenance_runs/router/labware_router.py index 234cb2d71ff..513636e9942 100644 --- a/robot-server/robot_server/maintenance_runs/router/labware_router.py +++ b/robot-server/robot_server/maintenance_runs/router/labware_router.py @@ -17,7 +17,8 @@ labware_router = APIRouter() -@labware_router.post( +@PydanticResponse.wrap_route( + labware_router.post, path="/maintenance_runs/{runId}/labware_offsets", summary="Add a labware offset to a maintenance run", description=( @@ -57,7 +58,8 @@ async def add_labware_offset( # TODO(mc, 2022-02-28): add complementary GET endpoint # https://github.com/Opentrons/opentrons/issues/9427 -@labware_router.post( +@PydanticResponse.wrap_route( + labware_router.post, path="/maintenance_runs/{runId}/labware_definitions", summary="Add a labware definition to a maintenance run", description=( diff --git a/robot-server/robot_server/modules/router.py b/robot-server/robot_server/modules/router.py index 7ece61a72d1..8155a88c4a6 100644 --- a/robot-server/robot_server/modules/router.py +++ b/robot-server/robot_server/modules/router.py @@ -24,7 +24,8 @@ modules_router = APIRouter() -@modules_router.get( +@PydanticResponse.wrap_route( + modules_router.get, path="/modules", summary="Get attached modules.", description="Get a list of all modules currently attached to the robot.", @@ -40,9 +41,13 @@ async def get_attached_modules( ) -> PydanticResponse[SimpleMultiBody[AttachedModule]]: """Get a list of all attached modules.""" if requested_version <= 2: - return await legacy_get_attached_modules( # type: ignore[return-value] + # TODO: can we use a redirect here or something + legacy_data = await legacy_get_attached_modules( hardware=hardware, ) + return await PydanticResponse.create( + content=legacy_data # type: ignore[arg-type] + ) # Load any the module calibrations module_calibrations: Dict[str, module_calibration.ModuleCalibrationOffset] = { diff --git a/robot-server/robot_server/protocols/router.py b/robot-server/robot_server/protocols/router.py index f420f85e623..09eaedea1f9 100644 --- a/robot-server/robot_server/protocols/router.py +++ b/robot-server/robot_server/protocols/router.py @@ -115,7 +115,8 @@ class ProtocolLinks(BaseModel): protocols_router = APIRouter() -@protocols_router.post( +@PydanticResponse.wrap_route( + protocols_router.post, path="/protocols", summary="Upload a protocol", description=dedent( @@ -179,7 +180,11 @@ async def create_protocol( analysis_id: Unique identifier to attach to the analysis resource. created_at: Timestamp to attach to the new resource. """ - buffered_files = await file_reader_writer.read(files=files) + for file in files: + # TODO(mm, 2024-02-07): Investigate whether the filename can actually be None. + assert file.filename is not None + buffered_files = await file_reader_writer.read(files=files) # type: ignore[arg-type] + content_hash = await file_hasher.hash(buffered_files) cached_protocol_id = protocol_store.get_id_by_hash(content_hash) @@ -271,7 +276,8 @@ async def create_protocol( ) -@protocols_router.get( +@PydanticResponse.wrap_route( + protocols_router.get, path="/protocols", summary="Get uploaded protocols", responses={status.HTTP_200_OK: {"model": SimpleMultiBody[Protocol]}}, @@ -308,7 +314,8 @@ async def get_protocols( ) -@protocols_router.get( +@PydanticResponse.wrap_route( + protocols_router.get, path="/protocols/ids", summary="[Internal] Get uploaded protocol IDs", description=( @@ -337,7 +344,8 @@ async def get_protocol_ids( ) -@protocols_router.get( +@PydanticResponse.wrap_route( + protocols_router.get, path="/protocols/{protocolId}", summary="Get an uploaded protocol", responses={ @@ -394,7 +402,8 @@ async def get_protocol_by_id( ) -@protocols_router.delete( +@PydanticResponse.wrap_route( + protocols_router.delete, path="/protocols/{protocolId}", summary="Delete an uploaded protocol", responses={ @@ -428,7 +437,8 @@ async def delete_protocol_by_id( ) -@protocols_router.get( +@PydanticResponse.wrap_route( + protocols_router.get, path="/protocols/{protocolId}/analyses", summary="Get a protocol's analyses", responses={ @@ -465,7 +475,8 @@ async def get_protocol_analyses( ) -@protocols_router.get( +@PydanticResponse.wrap_route( + protocols_router.get, path="/protocols/{protocolId}/analyses/{analysisId}", summary="Get one of a protocol's analyses", responses={ diff --git a/robot-server/robot_server/robot/calibration/check/user_flow.py b/robot-server/robot_server/robot/calibration/check/user_flow.py index 361b17dbe8a..1366c0054ed 100644 --- a/robot-server/robot_server/robot/calibration/check/user_flow.py +++ b/robot-server/robot_server/robot/calibration/check/user_flow.py @@ -90,7 +90,7 @@ """ # TODO: BC 2020-07-08: type all command logic here with actual Model type -COMMAND_HANDLER = Callable[..., Awaitable] +COMMAND_HANDLER = Callable[..., Awaitable[None]] COMMAND_MAP = Dict[str, COMMAND_HANDLER] @@ -552,7 +552,7 @@ def get_instruments(self) -> List[CheckAttachedPipette]: tipRackUri=info_pip.tip_rack.uri, rank=info_pip.rank.value, mount=str(info_pip.mount), - serial=hw_pip.pipette_id, # type: ignore[arg-type] + serial=hw_pip.pipette_id, defaultTipracks=info_pip.default_tipracks, # type: ignore[arg-type] ) for hw_pip, info_pip in zip(hw_pips, info_pips) @@ -575,7 +575,7 @@ def get_active_pipette(self) -> CheckAttachedPipette: tipRackUri=self.active_pipette.tip_rack.uri, rank=self.active_pipette.rank.value, mount=str(self.mount), - serial=self.hw_pipette.pipette_id, # type: ignore[arg-type] + serial=self.hw_pipette.pipette_id, defaultTipracks=( self.active_pipette.default_tipracks # type: ignore[arg-type] ), diff --git a/robot-server/robot_server/robot/calibration/deck/user_flow.py b/robot-server/robot_server/robot/calibration/deck/user_flow.py index c64af632018..55ed1351f84 100644 --- a/robot-server/robot_server/robot/calibration/deck/user_flow.py +++ b/robot-server/robot_server/robot/calibration/deck/user_flow.py @@ -82,7 +82,7 @@ """ # TODO: BC 2020-07-08: type all command logic here with actual Model type -COMMAND_HANDLER = Callable[..., Awaitable] +COMMAND_HANDLER = Callable[..., Awaitable[None]] COMMAND_MAP = Dict[str, COMMAND_HANDLER] @@ -187,7 +187,7 @@ def get_pipette(self) -> Optional[AttachedPipette]: name=self._hw_pipette.name, tipLength=self._hw_pipette.active_tip_settings.default_tip_length, mount=str(self._mount), - serial=self._hw_pipette.pipette_id, # type: ignore[arg-type] + serial=self._hw_pipette.pipette_id, defaultTipracks=self._default_tipracks, ) diff --git a/robot-server/robot_server/robot/calibration/helper_classes.py b/robot-server/robot_server/robot/calibration/helper_classes.py index a421dc6819a..68da8509222 100644 --- a/robot-server/robot_server/robot/calibration/helper_classes.py +++ b/robot-server/robot_server/robot/calibration/helper_classes.py @@ -94,21 +94,25 @@ def supported(self): class AttachedPipette(BaseModel): """Pipette (if any) attached to the mount""" - model: str = Field( + model: typing.Optional[str] = Field( None, description="The model of the attached pipette. These are snake " "case as in the Protocol API. This includes the full" " version string", ) - name: str = Field( + name: typing.Optional[str] = Field( None, description="Short name of pipette model without" "generation version" ) - tipLength: float = Field( + tipLength: typing.Optional[float] = Field( None, description="The default tip length for this pipette" ) - mount: str = Field(None, description="The mount this pipette attached to") - serial: str = Field(None, description="The serial number of the attached pipette") - defaultTipracks: typing.List[typing.Dict[str, typing.Any]] = Field( + mount: typing.Optional[str] = Field( + None, description="The mount this pipette attached to" + ) + serial: typing.Optional[str] = Field( + None, description="The serial number of the attached pipette" + ) + defaultTipracks: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = Field( None, description="A list of default tipracks for this pipette" ) diff --git a/robot-server/robot_server/robot/calibration/pipette_offset/models.py b/robot-server/robot_server/robot/calibration/pipette_offset/models.py index cde5c6bcf3b..d6aa245943f 100644 --- a/robot-server/robot_server/robot/calibration/pipette_offset/models.py +++ b/robot-server/robot_server/robot/calibration/pipette_offset/models.py @@ -13,7 +13,7 @@ class PipetteOffsetCalibrationSessionStatus(BaseModel): ) labware: List[RequiredLabware] shouldPerformTipLength: bool = Field( - None, + ..., description="Does tip length calibration data exist for " "this pipette and tip rack combination", ) diff --git a/robot-server/robot_server/robot/calibration/pipette_offset/user_flow.py b/robot-server/robot_server/robot/calibration/pipette_offset/user_flow.py index e9fb7beb6f4..695e8428634 100644 --- a/robot-server/robot_server/robot/calibration/pipette_offset/user_flow.py +++ b/robot-server/robot_server/robot/calibration/pipette_offset/user_flow.py @@ -68,7 +68,7 @@ """ # TODO: BC 2020-07-08: type all command logic here with actual Model type -COMMAND_HANDLER = Callable[..., Awaitable] +COMMAND_HANDLER = Callable[..., Awaitable[None]] COMMAND_MAP = Dict[str, COMMAND_HANDLER] PipetteOffsetStateMachine = Union[ @@ -199,7 +199,7 @@ def get_pipette(self) -> AttachedPipette: name=self._hw_pipette.name, tipLength=self._hw_pipette.active_tip_settings.default_tip_length, mount=str(self._mount), - serial=self._hw_pipette.pipette_id, # type: ignore[arg-type] + serial=self._hw_pipette.pipette_id, defaultTipracks=self._default_tipracks, # type: ignore[arg-type] ) diff --git a/robot-server/robot_server/robot/calibration/tip_length/user_flow.py b/robot-server/robot_server/robot/calibration/tip_length/user_flow.py index e771c0def5d..fec0fa42639 100644 --- a/robot-server/robot_server/robot/calibration/tip_length/user_flow.py +++ b/robot-server/robot_server/robot/calibration/tip_length/user_flow.py @@ -35,7 +35,7 @@ """ # TODO: BC 2020-07-08: type all command logic here with actual Model type -COMMAND_HANDLER = Callable[..., Awaitable] +COMMAND_HANDLER = Callable[..., Awaitable[None]] COMMAND_MAP = Dict[str, COMMAND_HANDLER] @@ -134,7 +134,7 @@ def get_pipette(self) -> AttachedPipette: name=self._hw_pipette.name, tipLength=self._hw_pipette.active_tip_settings.default_tip_length, mount=str(self._mount), - serial=self._hw_pipette.pipette_id, # type: ignore[arg-type] + serial=self._hw_pipette.pipette_id, defaultTipracks=self._default_tipracks, # type: ignore[arg-type] ) diff --git a/robot-server/robot_server/robot/control/router.py b/robot-server/robot_server/robot/control/router.py index 0193dce94f1..3116fc6957e 100644 --- a/robot-server/robot_server/robot/control/router.py +++ b/robot-server/robot_server/robot/control/router.py @@ -37,8 +37,9 @@ async def _get_estop_status_response( return await PydanticResponse.create(content=SimpleBody.construct(data=data)) -@control_router.get( - "/robot/control/estopStatus", +@PydanticResponse.wrap_route( + control_router.get, + path="/robot/control/estopStatus", summary="Get connected estop status.", description="Get the current estop status of the robot, as well as a list of connected estops.", responses={ @@ -53,8 +54,9 @@ async def get_estop_status( return await _get_estop_status_response(estop_handler) -@control_router.put( - "/robot/control/acknowledgeEstopDisengage", +@PydanticResponse.wrap_route( + control_router.put, + path="/robot/control/acknowledgeEstopDisengage", summary="Acknowledge and clear an Estop event.", description="If the estop is currently logically engaged (the estop was previously pressed but is " + "now released), this endpoint will reset the state to reflect the current physical status.", @@ -75,8 +77,9 @@ def get_door_switch_required(robot_type: RobotType = Depends(get_robot_type)) -> return ff.enable_door_safety_switch(RobotTypeEnum.robot_literal_to_enum(robot_type)) -@control_router.get( - "/robot/door/status", +@PydanticResponse.wrap_route( + control_router.get, + path="/robot/door/status", summary="Get the status of the robot door.", description="Get whether the robot door is open or closed.", responses={status.HTTP_200_OK: {"model": SimpleBody[DoorStatusModel]}}, diff --git a/robot-server/robot_server/runs/router/actions_router.py b/robot-server/robot_server/runs/router/actions_router.py index dc3f8ab4aba..3969fd1ec7a 100644 --- a/robot-server/robot_server/runs/router/actions_router.py +++ b/robot-server/robot_server/runs/router/actions_router.py @@ -71,7 +71,8 @@ async def get_run_controller( ) -@actions_router.post( +@PydanticResponse.wrap_route( + actions_router.post, path="/runs/{runId}/actions", summary="Issue a control action to the run", description="Provide an action in order to control execution of the run.", diff --git a/robot-server/robot_server/runs/router/base_router.py b/robot-server/robot_server/runs/router/base_router.py index 43b1202d29b..d7c1ea1bc59 100644 --- a/robot-server/robot_server/runs/router/base_router.py +++ b/robot-server/robot_server/runs/router/base_router.py @@ -114,7 +114,8 @@ async def get_run_data_from_url( return run_data -@base_router.post( +@PydanticResponse.wrap_route( + base_router.post, path="/runs", summary="Create a run", description=dedent( @@ -197,7 +198,8 @@ async def create_run( ) -@base_router.get( +@PydanticResponse.wrap_route( + base_router.get, path="/runs", summary="Get all runs", description="Get a list of all active and inactive runs.", @@ -238,7 +240,8 @@ async def get_runs( ) -@base_router.get( +@PydanticResponse.wrap_route( + base_router.get, path="/runs/{runId}", summary="Get a run", description="Get a specific run by its unique identifier.", @@ -261,7 +264,8 @@ async def get_run( ) -@base_router.delete( +@PydanticResponse.wrap_route( + base_router.delete, path="/runs/{runId}", summary="Delete a run", description="Delete a specific run by its unique identifier.", @@ -295,7 +299,8 @@ async def remove_run( ) -@base_router.patch( +@PydanticResponse.wrap_route( + base_router.patch, path="/runs/{runId}", summary="Update a run", description="Update a specific run, returning the updated resource.", diff --git a/robot-server/robot_server/runs/router/commands_router.py b/robot-server/robot_server/runs/router/commands_router.py index 10e1833bd1a..a8767ca5482 100644 --- a/robot-server/robot_server/runs/router/commands_router.py +++ b/robot-server/robot_server/runs/router/commands_router.py @@ -117,7 +117,8 @@ async def get_current_run_engine_from_url( return engine_store.engine -@commands_router.post( +@PydanticResponse.wrap_route( + commands_router.post, path="/runs/{runId}/commands", summary="Enqueue a command", description=textwrap.dedent( @@ -228,7 +229,8 @@ async def create_run_command( ) -@commands_router.get( +@PydanticResponse.wrap_route( + commands_router.get, path="/runs/{runId}/commands", summary="Get a list of all protocol commands in the run", description=( @@ -320,7 +322,8 @@ async def get_run_commands( ) -@commands_router.get( +@PydanticResponse.wrap_route( + commands_router.get, path="/runs/{runId}/commands/{commandId}", summary="Get full details about a specific command in the run", description=( diff --git a/robot-server/robot_server/runs/router/labware_router.py b/robot-server/robot_server/runs/router/labware_router.py index d58f8c3a9fb..7659d5ccf98 100644 --- a/robot-server/robot_server/runs/router/labware_router.py +++ b/robot-server/robot_server/runs/router/labware_router.py @@ -29,7 +29,8 @@ labware_router = APIRouter() -@labware_router.post( +@PydanticResponse.wrap_route( + labware_router.post, path="/runs/{runId}/labware_offsets", summary="Add a labware offset to a run", description=( @@ -74,7 +75,8 @@ async def add_labware_offset( # TODO(mc, 2022-02-28): add complementary GET endpoint # https://github.com/Opentrons/opentrons/issues/9427 -@labware_router.post( +@PydanticResponse.wrap_route( + labware_router.post, path="/runs/{runId}/labware_definitions", summary="Add a labware definition to a run", description=( @@ -115,7 +117,8 @@ async def add_labware_definition( ) -@labware_router.get( +@PydanticResponse.wrap_route( + labware_router.get, path="/runs/{runId}/loaded_labware_definitions", summary="Get the definitions of a run's loaded labware", description=( diff --git a/robot-server/robot_server/service/json_api/response.py b/robot-server/robot_server/service/json_api/response.py index 47f96a58d5f..a43e6c11568 100644 --- a/robot-server/robot_server/service/json_api/response.py +++ b/robot-server/robot_server/service/json_api/response.py @@ -1,9 +1,21 @@ from __future__ import annotations from anyio import to_thread -from typing import Any, Dict, Generic, List, Optional, TypeVar, Sequence +from typing import ( + Any, + Dict, + Generic, + List, + Optional, + TypeVar, + Sequence, + ParamSpec, + Callable, +) from pydantic import Field, BaseModel from pydantic.generics import GenericModel +from pydantic.typing import get_args from fastapi.responses import JSONResponse +from fastapi.dependencies.utils import get_typed_return_annotation from .resource_links import ResourceLinks as DeprecatedResourceLinks @@ -119,6 +131,12 @@ class MultiBody( ResponseBodyT = TypeVar("ResponseBodyT", bound=BaseResponseBody) +RouteMethodSig = ParamSpec("RouteMethodSig") +DecoratedEndpoint = TypeVar("DecoratedEndpoint", bound=Callable[..., Any]) +RouteMethodReturn = TypeVar( + "RouteMethodReturn", bound=Callable[[DecoratedEndpoint], DecoratedEndpoint] +) + class PydanticResponse(JSONResponse, Generic[ResponseBodyT]): """A custom JSON response that uses Pydantic for JSON serialization. @@ -127,6 +145,61 @@ class PydanticResponse(JSONResponse, Generic[ResponseBodyT]): than returning a plain Pydantic model and letting FastAPI serialize it. """ + @classmethod + def wrap_route( + cls, + route_method: Callable[RouteMethodSig, RouteMethodReturn], + *route_args: RouteMethodSig.args, + **route_kwargs: RouteMethodSig.kwargs, + ) -> Callable[[DecoratedEndpoint], DecoratedEndpoint]: + """Use this classmethod as a decorator to wrap routes that return PydanticResponses. + + The route method (i.e. the .post() method of the router) is the first argument and the rest of the + arguments are keyword args that are forwarded to the route handler. + + For instance: + @PydanticResponse.wrap_route( + some_router.post, + path='/some/path', + ... + ) + def my_some_path_handler(...) -> PydanticResponse[SimpleBody[whatever]]: + ... + + The reason this exists is that if you do not specify a response_model, pydantic will parse the return + value annotation and try to stuff it in a pydantic field. Pydantic fields can't handle arbitrary classes, + like fastapi.JSONResponse; therefore, you get an exception while parsing the file (since this all happens + in a decorator). The fix for this is to always specify a response_model, even if you're also doing a return + value annotation and/or responses={} arguments. + + This decorator does that for you! Just take any route handler that returns a PydanticResponse (you still have to + annotate it as such, and return PydanticResponse.create(...) yourself, this only handles the decorating part) and + replace its route decoration with this one, passing the erstwhile route decorator in. + """ + # our outermost function exists to capture the arguments that you want to forward to the route decorator + assert ( + "response_model" not in route_kwargs + ), "Do not use PydanticResponse.wrap_route if you are already specifying a response model" + + def decorator( + endpoint_method: DecoratedEndpoint, + ) -> DecoratedEndpoint: + # the return annotation is e.g. PydanticResponse[SimpleBody[Whatever]] + return_annotation = get_typed_return_annotation(endpoint_method) + # the first arg of the outermost type is the argument to the generic, + # in this case SimpleBody[Whatever] + response_model = get_args(return_annotation)[0] + # and that's what we want to pass to the route method as response_model, so we do it and get the actual + # function transformer + route_decorator = route_method( + **route_kwargs, response_model=response_model + ) + # which we then call on the endpoint method to get it registered with the router, and return the results + return route_decorator(endpoint_method) + + # and finally we return our own function transformer with the route method args closed over + return decorator + def __init__( self, content: ResponseBodyT, @@ -163,7 +236,7 @@ class DeprecatedResponseDataModel(BaseModel): Prefer ResourceModel, which requires ID to be specified """ - id: str = Field(None, description="Unique identifier for the resource object.") + id: str = Field(..., description="Unique identifier for the resource object.") # TODO(mc, 2021-12-09): remove this model diff --git a/robot-server/robot_server/service/labware/router.py b/robot-server/robot_server/service/labware/router.py index e008af014d1..9d446c6db0e 100644 --- a/robot-server/robot_server/service/labware/router.py +++ b/robot-server/robot_server/service/labware/router.py @@ -36,6 +36,7 @@ class LabwareCalibrationEndpointsRemoved(ErrorDetails): "This endpoint has been removed." " Use the `/runs` endpoints to manage labware offsets." ), + response_model=None, responses={ status.HTTP_200_OK: {"model": lw_models.MultipleCalibrationsResponse}, status.HTTP_410_GONE: {"model": ErrorBody[LabwareCalibrationEndpointsRemoved]}, @@ -61,6 +62,7 @@ async def get_all_labware_calibrations( "This endpoint has been removed." " Use the `/runs` endpoints to manage labware offsets." ), + response_model=None, responses={ status.HTTP_404_NOT_FOUND: {"model": ErrorBody}, status.HTTP_410_GONE: {"model": ErrorBody[LabwareCalibrationEndpointsRemoved]}, @@ -87,6 +89,7 @@ async def get_specific_labware_calibration( "This endpoint has been removed." " Use the `/runs` endpoints to manage labware offsets." ), + response_model=None, responses={ status.HTTP_404_NOT_FOUND: {"model": ErrorBody}, status.HTTP_410_GONE: {"model": ErrorBody[LabwareCalibrationEndpointsRemoved]}, diff --git a/robot-server/robot_server/service/legacy/models/control.py b/robot-server/robot_server/service/legacy/models/control.py index 603a195be60..923ba29eb30 100644 --- a/robot-server/robot_server/service/legacy/models/control.py +++ b/robot-server/robot_server/service/legacy/models/control.py @@ -110,37 +110,19 @@ def root_validator(cls, values): class Config: schema_extra = { - "examples": { - "moveLeftMount": { - "description": "Move the left mount, regardless of what is " - "attached to that mount, to a specific " - "position. Since you move the mount, the end of" - " the pipette will be in different places " - "depending on what pipette is attached - but " - "you don't have to know what's attached.", - "summary": "Move left mount", - "value": { - "target": "mount", - "point": [100, 100, 80], - "mount": "left", - }, + "examples": [ + { + "target": "mount", + "point": [100, 100, 80], + "mount": "left", }, - "moveRightP300Single": { - "summary": "Move P300 Single on right mount", - "description": "Move a P300 Single attached to the right mount" - " to a specific position. You have to specify " - "that it's a P300 Single that you're moving, " - "but as long as you specify the correct model " - "the end of the pipette will always be at the " - "specified position.", - "value": { - "target": "pipette", - "mount": "right", - "model": "p300_single", - "point": [25, 25, 50], - }, + { + "target": "pipette", + "mount": "right", + "model": "p300_single", + "point": [25, 25, 50], }, - } + ] } @@ -168,18 +150,7 @@ def root_validate(cls, values): class Config: schema_extra = { - "examples": { - "homeGantry": { - "summary": "Home Gantry", - "description": "Home the robot's gantry", - "value": {"target": "robot"}, - }, - "homeRight": { - "summary": "Home right pipette", - "description": "Home only the right pipette", - "value": {"target": "pipette", "mount": "right"}, - }, - } + "examples": [{"target": "robot"}, {"target": "pipette", "mount": "right"}] } diff --git a/robot-server/robot_server/service/legacy/models/deck_calibration.py b/robot-server/robot_server/service/legacy/models/deck_calibration.py index 9126f95f28d..401589c82a2 100644 --- a/robot-server/robot_server/service/legacy/models/deck_calibration.py +++ b/robot-server/robot_server/service/legacy/models/deck_calibration.py @@ -61,8 +61,10 @@ class DeckCalibrationData(BaseModel): tiprack: typing.Optional[str] = Field( None, description="The sha256 hash of the tiprack used in this calibration" ) - source: SourceType = Field(None, description="The calibration source") - status: cal_model.CalibrationStatus = Field( + source: typing.Optional[SourceType] = Field( + None, description="The calibration source" + ) + status: typing.Optional[cal_model.CalibrationStatus] = Field( None, description="The status of this calibration as determined" "by a user performing calibration check.", diff --git a/robot-server/robot_server/service/legacy/models/modules.py b/robot-server/robot_server/service/legacy/models/modules.py index 61c68e3aa4b..992c109591a 100644 --- a/robot-server/robot_server/service/legacy/models/modules.py +++ b/robot-server/robot_server/service/legacy/models/modules.py @@ -171,119 +171,104 @@ class Modules(BaseModel): class Config: schema_extra = { - "examples": { - "nothingAttached": { - "description": "With no modules present", - "value": {"modules": []}, + "examples": [ + {"modules": []}, + { + "modules": [ + { + "name": "magdeck", + "displayName": "Magnetic Module", + "moduleModel": "magneticModuleV1", + "port": "tty01_magdeck", + "serial": "MDV2313121", + "model": "mag_deck_v4.0", + "revision": "mag_deck_v4.0", + "fwVersion": "2.1.3", + "status": "engaged", + "hasAvailableUpdate": True, + "data": {"engaged": True, "height": 10}, + } + ] }, - "magneticModuleAttached": { - "description": "With a Magnetic Module attached", - "value": { - "modules": [ - { - "name": "magdeck", - "displayName": "Magnetic Module", - "moduleModel": "magneticModuleV1", - "port": "tty01_magdeck", - "serial": "MDV2313121", - "model": "mag_deck_v4.0", - "revision": "mag_deck_v4.0", - "fwVersion": "2.1.3", - "status": "engaged", - "hasAvailableUpdate": True, - "data": {"engaged": True, "height": 10}, - } - ] - }, + { + "modules": [ + { + "name": "tempdeck", + "displayName": "Temperature Module", + "moduleModel": "temperatureModuleV1", + "revision": "temp_deck_v10", + "port": "tty2_tempdeck", + "serial": "TDV10231231", + "model": "temp_deck_v10", + "hasAvailableUpdate": False, + "fwVersion": "1.2.0", + "status": "cooling", + "data": {"currentTemp": 25, "targetTemp": 10}, + } + ] }, - "tempDeckAttached": { - "description": "With a Temperature Module attached", - "value": { - "modules": [ - { - "name": "tempdeck", - "displayName": "Temperature Module", - "moduleModel": "temperatureModuleV1", - "revision": "temp_deck_v10", - "port": "tty2_tempdeck", - "serial": "TDV10231231", - "model": "temp_deck_v10", - "hasAvailableUpdate": False, - "fwVersion": "1.2.0", - "status": "cooling", - "data": {"currentTemp": 25, "targetTemp": 10}, - } - ] - }, + { + "modules": [ + { + "name": "thermocycler", + "displayName": "Thermocycler", + "revision": "thermocycler_v10", + "moduleModel": "thermocyclerModuleV1", + "port": "tty3_thermocycler", + "serial": "TCV1006052018", + "model": "thermocycler_v10", + "hasAvailableUpdate": True, + "fwVersion": "1.0.0", + "status": "cooling", + "data": { + "lid": "closed", + "lidTarget": 10, + "lidTemp": 15, + "currentTemp": 20, + "targetTemp": 10, + "holdTime": None, + "rampRate": 10, + "currentCycleIndex": None, + "totalCycleCount": None, + "currentStepIndex": None, + "totalStepCount": None, + }, + } + ] }, - "thermocyclerAttached": { - "description": "With a Thermocycler attached", - "value": { - "modules": [ - { - "name": "thermocycler", - "displayName": "Thermocycler", - "revision": "thermocycler_v10", - "moduleModel": "thermocyclerModuleV1", - "port": "tty3_thermocycler", - "serial": "TCV1006052018", - "model": "thermocycler_v10", - "hasAvailableUpdate": True, - "fwVersion": "1.0.0", - "status": "cooling", - "data": { - "lid": "closed", - "lidTarget": 10, - "lidTemp": 15, - "currentTemp": 20, - "targetTemp": 10, - "holdTime": None, - "rampRate": 10, - "currentCycleIndex": None, - "totalCycleCount": None, - "currentStepIndex": None, - "totalStepCount": None, - }, - } - ] - }, + { + "modules": [ + { + "name": "heatershaker", + "displayName": "heatershaker", + "fwVersion": "0.0.1", + "hasAvailableUpdate": True, + "model": "heater-shaker_v10", + "moduleModel": "heaterShakerModuleV1", + "port": "/dev/ot_module_heatershaker1", + "usbPort": { + "hub": False, + "port": 1, + "portGroup": "unknown", + "hubPort": None, + }, + "revision": "heater-shaker_v10", + "serial": "HSnnnnnn", + "status": "running", + "data": { + "temperatureStatus": "heating", + "speedStatus": "holding at target", + "labwareLatchStatus": "closed", + "currentTemp": 25.5, + "targetTemp": 50, + "currentSpeed": 10, + "targetSpeed": 300, + "errorDetails": None, + }, + } + ] }, - "heaterShakerAttached": { - "description": "With a Heater-Shaker attached", - "value": { - "modules": [ - { - "name": "heatershaker", - "displayName": "heatershaker", - "fwVersion": "0.0.1", - "hasAvailableUpdate": True, - "model": "heater-shaker_v10", - "moduleModel": "heaterShakerModuleV1", - "port": "/dev/ot_module_heatershaker1", - "usbPort": { - "hub": False, - "port": 1, - "portGroup": "unknown", - "hubPort": None, - }, - "revision": "heater-shaker_v10", - "serial": "HSnnnnnn", - "status": "running", - "data": { - "temperatureStatus": "heating", - "speedStatus": "holding at target", - "labwareLatchStatus": "closed", - "currentTemp": 25.5, - "targetTemp": 50, - "currentSpeed": 10, - "targetSpeed": 300, - "errorDetails": None, - }, - } - ] - }, - }, - } + ] } @@ -305,32 +290,16 @@ class SerialCommand(BaseModel): ) class Config: - schema_extra = { - "examples": { - "tempModSetTemp": { - "summary": "Set Temperature Module temperature", - "description": "Set the temperature of an attached " - "Temperature Module", - "value": {"command_type": "set_temperature", "args": [60]}, - } - } - } + schema_extra = {"examples": [{"command_type": "set_Temperature", "args": [60]}]} class SerialCommandResponse(BaseModel): """ "The result of a successful call""" message: str = Field(..., description="A human readable string") - returnValue: str = Field(None, description="The return value from the call") + returnValue: typing.Optional[str] = Field( + None, description="The return value from the call" + ) class Config: - schema_extra = { - "examples": { - "tempModSetTemperature": { - "summary": "Set temperature OK", - "description": "A successful call to set_temperature " - "on a Temperature Module", - "value": {"message": "Success", "returnValue": None}, - } - } - } + schema_extra = {"examples": [{"message": "Success", "returnValue": None}]} diff --git a/robot-server/robot_server/service/legacy/models/networking.py b/robot-server/robot_server/service/legacy/models/networking.py index 330b5629072..c8c7a1fd2d7 100644 --- a/robot-server/robot_server/service/legacy/models/networking.py +++ b/robot-server/robot_server/service/legacy/models/networking.py @@ -21,19 +21,19 @@ class ConnectionType(str, Enum): class InterfaceStatus(BaseModel): """Status for an interface""" - ipAddress: str = Field( + ipAddress: typing.Optional[str] = Field( None, description="The interface IP address with CIDR subnet appended " "(e.g. 10.0.0.1/24)", ) - macAddress: str = Field( + macAddress: typing.Optional[str] = Field( None, description="The MAC address of this interface (at least when " "connected to this network - it may change due to " "NetworkManager's privacy functionality when " "disconnected or connected to a different network)", ) - gatewayAddress: str = Field( + gatewayAddress: typing.Optional[str] = Field( None, description="The address of the configured gateway" ) state: str = Field( @@ -143,7 +143,7 @@ class WifiConfiguration(BaseModel): ) securityType: typing.Optional[NetworkingSecurityType] - psk: SecretStr = Field( + psk: typing.Optional[SecretStr] = Field( None, description="If this is a PSK-secured network (securityType is " "wpa-psk), the PSK", @@ -201,56 +201,29 @@ def validate_configuration(cls, values): class Config: schema_extra = { - "examples": { - "unsecuredNetwork": { - "summary": "Connect to an unsecured network", - "value": {"ssid": "linksys"}, + "examples": [ + {"ssid": "linksys"}, + { + "ssid": "linksys", + "securityType": "wpa-psk", + "psk": "psksrock", }, - "pskNetwork": { - "summary": "Connect to a WPA2-PSK secured network", - "description": 'This is the "standard" way to set up a WiFi ' - "router, and is where you provide a password", - "value": { - "ssid": "linksys", - "securityType": "wpa-psk", - "psk": "psksrock", - }, - }, - "hiddenNetwork": { - "summary": "Connect to a network not broadcasting its SSID, " - "with a PSK", - "value": { - "ssid": "cantseeme", - "securityType": "wpa-psk", - "psk": "letmein", - "hidden": True, - }, + { + "ssid": "cantseeme", + "securityType": "wpa-psk", + "psk": "letmein", + "hidden": True, }, - "eapNetwork": { - "summary": "Connect to a network secured by WPA2-EAP using " - "PEAP/MSCHAPv2", - "description": "WPA2 Enterprise network security is based " - "around the EAP protocol, which is a very " - " comple tunneled authentication protocol. It " - "can be configured in many different ways. The " - "OT-2 supports several but by no means all of " - "these variants. The variants supported on a " - "given OT-2 can be found by GET " - "/wifi/eap-options. This example describes how " - "to set up PEAP/MSCHAPv2, which is an older EAP" - " variant that was at one time the mechanism " - "securing Eduroam.", - "value": { - "ssid": "Eduroam", - "securityType": "wpa-eap", - "eapConfig": { - "eapType": "peap/mschapv2", - "identity": "scientist@biology.org", - "password": "leeuwenhoek", - }, + { + "ssid": "Eduroam", + "securityType": "wpa-eap", + "eapConfig": { + "eapType": "peap/mschapv2", + "identity": "scientist@biology.org", + "password": "leeuwenhoek", }, }, - } + ] } diff --git a/robot-server/robot_server/service/legacy/models/settings.py b/robot-server/robot_server/service/legacy/models/settings.py index 4e9ba6b7251..1c8f2c1a96d 100644 --- a/robot-server/robot_server/service/legacy/models/settings.py +++ b/robot-server/robot_server/service/legacy/models/settings.py @@ -94,8 +94,8 @@ def level_id(self): class LogLevel(BaseModel): - log_level: LogLevels = Field( - None, description="The value to set (conforming to Python " "log levels)" + log_level: Optional[LogLevels] = Field( + None, description="The value to set (conforming to Python log levels)" ) @validator("log_level", pre=True) @@ -132,7 +132,7 @@ class PipetteSettingsFieldType(str, Enum): class PipetteSettingsField(BaseModel): """A pipette config element identified by the property's name""" - units: str = Field( + units: Optional[str] = Field( None, description="The physical units this value is in (e.g. mm, uL)" ) type: Optional[PipetteSettingsFieldType] @@ -152,7 +152,7 @@ class PipetteSettingsInfo(BaseModel): class BasePipetteSettingFields(BaseModel): - quirks: Dict[str, bool] = Field( + quirks: Optional[Dict[str, bool]] = Field( None, description="Quirks are behavioral changes associated with " "pipettes. For instance, some models of pipette " diff --git a/robot-server/robot_server/service/legacy/routers/networking.py b/robot-server/robot_server/service/legacy/routers/networking.py index 91a6b219a4b..de1cef29847 100644 --- a/robot-server/robot_server/service/legacy/routers/networking.py +++ b/robot-server/robot_server/service/legacy/routers/networking.py @@ -147,13 +147,22 @@ async def get_wifi_keys(): @router.post( "/wifi/keys", description="Send a new key file to the robot", - responses={status.HTTP_200_OK: {"model": AddWifiKeyFileResponse}}, + responses={ + status.HTTP_200_OK: {"model": AddWifiKeyFileResponse}, + status.HTTP_400_BAD_REQUEST: {"model": LegacyErrorResponse}, + }, response_model=AddWifiKeyFileResponse, status_code=status.HTTP_201_CREATED, response_model_exclude_unset=True, ) async def post_wifi_key(key: UploadFile = File(...)): - add_key_result = wifi.add_key(key.filename, key.file.read()) + key_name = key.filename + if not key_name: + raise LegacyErrorResponse( + message="No name for key", errorCode=ErrorCodes.GENERAL_ERROR.value.code + ).as_error(status.HTTP_400_BAD_REQUEST) + + add_key_result = wifi.add_key(key_name, key.file.read()) response = AddWifiKeyFileResponse( uri=f"/wifi/keys/{add_key_result.key.directory}", diff --git a/robot-server/robot_server/service/session/command_execution/callable_executor.py b/robot-server/robot_server/service/session/command_execution/callable_executor.py index 7ec34c37845..39a62cbe3ae 100644 --- a/robot-server/robot_server/service/session/command_execution/callable_executor.py +++ b/robot-server/robot_server/service/session/command_execution/callable_executor.py @@ -6,7 +6,7 @@ CommandHandler = typing.Callable[ - [str, typing.Dict[typing.Any, typing.Any]], typing.Coroutine + [str, typing.Dict[typing.Any, typing.Any]], typing.Coroutine[None, None, None] ] diff --git a/robot-server/robot_server/subsystems/router.py b/robot-server/robot_server/subsystems/router.py index 92cf3e9e8cd..effa6735c87 100644 --- a/robot-server/robot_server/subsystems/router.py +++ b/robot-server/robot_server/subsystems/router.py @@ -106,8 +106,9 @@ class NoOngoingUpdate(ErrorDetails): title: str = "No Ongoing Update" -@subsystems_router.get( - "/subsystems/status", +@PydanticResponse.wrap_route( + subsystems_router.get, + path="/subsystems/status", summary="Get attached subsystems.", description="Get a list of subsystems currently attached to the robot.", responses={ @@ -137,8 +138,9 @@ async def get_attached_subsystems( ) -@subsystems_router.get( - "/subsystems/status/{subsystem}", +@PydanticResponse.wrap_route( + subsystems_router.get, + path="/subsystems/status/{subsystem}", responses={ status.HTTP_200_OK: {"model": SimpleBody[PresentSubsystem]}, status.HTTP_403_FORBIDDEN: {"model": ErrorBody[NotSupportedOnOT2]}, @@ -173,8 +175,9 @@ async def get_attached_subsystem( ) -@subsystems_router.get( - "/subsystems/updates/current", +@PydanticResponse.wrap_route( + subsystems_router.get, + path="/subsystems/updates/current", summary="Get a list of currently-ongoing subsystem updates.", description="Get a list of currently-running subsystem firmware updates. This is a good snapshot of what, if anything, is currently being updated and may block other robot work. To guarantee data about an update you were previously interested in, get its id using /subsystems/updates/all.", responses={status.HTTP_200_OK: {"model": SimpleMultiBody[UpdateProgressSummary]}}, @@ -199,8 +202,9 @@ async def get_subsystem_updates( ) -@subsystems_router.get( - "/subsystems/updates/current/{subsystem}", +@PydanticResponse.wrap_route( + subsystems_router.get, + path="/subsystems/updates/current/{subsystem}", summary="Get any currently-ongoing update for a specific subsystem.", description="As /subsystems/updates/current but filtered by the route parameter.", responses={ @@ -236,8 +240,9 @@ async def get_subsystem_update( ) -@subsystems_router.get( - "/subsystems/updates/all", +@PydanticResponse.wrap_route( + subsystems_router.get, + path="/subsystems/updates/all", summary="Get a list of all updates by id.", description="Get a list of all updates, including both current updates and updates that started since the last boot but are now complete. Response includes each update's final status and whether it succeeded or failed. While an update might complete and therefore disappear from /subsystems/updates/current, you can always find that update in the response to this endpoint by its update id.", responses={status.HTTP_200_OK: {"model": SimpleMultiBody[UpdateProgressData]}}, @@ -261,8 +266,9 @@ async def get_update_processes( ) -@subsystems_router.get( - "/subsystems/updates/all/{id}", +@PydanticResponse.wrap_route( + subsystems_router.get, + path="/subsystems/updates/all/{id}", summary="Get the details of a specific update by its id.", description="As /subsystems/updates/all but returning only one resource: the one with the id matching the route parameter (if it exists).", responses={status.HTTP_200_OK: {"model": SimpleBody[UpdateProgressData]}}, @@ -291,8 +297,9 @@ async def get_update_process( ) -@subsystems_router.post( - "/subsystems/updates/{subsystem}", +@PydanticResponse.wrap_route( + subsystems_router.post, + path="/subsystems/updates/{subsystem}", summary="Start an update for a subsystem.", description="Begin a firmware update for a given subsystem.", responses={ diff --git a/robot-server/setup.py b/robot-server/setup.py index 079c8858ea0..7fcdabade82 100755 --- a/robot-server/setup.py +++ b/robot-server/setup.py @@ -55,17 +55,16 @@ def get_version(): f"opentrons=={VERSION}", f"opentrons-shared-data=={VERSION}", f"server-utils=={VERSION}", - "anyio==3.6.1", - "fastapi==0.68.1", - "python-dotenv==0.19.0", - "python-multipart==0.0.5", - "pydantic==1.9.2", + "anyio==3.7.1", + "fastapi==0.99.1", + "python-dotenv==1.0.1", + "python-multipart==0.0.6", + "pydantic==1.10.12", "typing-extensions>=4.0.0,<5", - "uvicorn==0.14.0", - "wsproto==1.0.0", + "uvicorn==0.27.0.post1", + "wsproto==1.2.0", "systemd-python==234; sys_platform=='linux'", - "sqlalchemy==1.4.32", - "aiosqlite==0.17.0", + "sqlalchemy==1.4.51", "paho-mqtt==1.6.1", ] diff --git a/robot-server/tests/conftest.py b/robot-server/tests/conftest.py index 362af0addbe..c3a225d7571 100644 --- a/robot-server/tests/conftest.py +++ b/robot-server/tests/conftest.py @@ -46,7 +46,7 @@ test_router = routing.APIRouter() -@test_router.get("/alwaysRaise") +@test_router.get("/alwaysRaise", response_model=None) async def always_raise() -> NoReturn: raise RuntimeError @@ -165,7 +165,9 @@ def api_client( _override_ot2_hardware_with_mock: None, ) -> TestClient: client = TestClient(app) - client.headers.update({API_VERSION_HEADER: LATEST_API_VERSION_HEADER_VALUE}) + client.headers.update( + {API_VERSION_HEADER: cast(str, LATEST_API_VERSION_HEADER_VALUE)} + ) return client @@ -176,7 +178,9 @@ def api_client_no_errors( """An API client that won't raise server exceptions. Use only to test 500 pages; never use this for other tests.""" client = TestClient(app, raise_server_exceptions=False) - client.headers.update({API_VERSION_HEADER: LATEST_API_VERSION_HEADER_VALUE}) + client.headers.update( + {API_VERSION_HEADER: cast(str, LATEST_API_VERSION_HEADER_VALUE)} + ) return client diff --git a/robot-server/tests/integration/http_api/runs/test_deck_slot_standardization.py b/robot-server/tests/integration/http_api/runs/test_deck_slot_standardization.py index 0627ce43c0b..aa39376cafe 100644 --- a/robot-server/tests/integration/http_api/runs/test_deck_slot_standardization.py +++ b/robot-server/tests/integration/http_api/runs/test_deck_slot_standardization.py @@ -1,7 +1,7 @@ from typing import AsyncGenerator import pytest -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from ...robot_client import RobotClient diff --git a/robot-server/tests/integration/http_api/test_deck_configuration.tavern.yaml b/robot-server/tests/integration/http_api/test_deck_configuration.tavern.yaml index 21be55b752f..8cc01fdcd24 100644 --- a/robot-server/tests/integration/http_api/test_deck_configuration.tavern.yaml +++ b/robot-server/tests/integration/http_api/test_deck_configuration.tavern.yaml @@ -153,7 +153,8 @@ stages: method: POST json: deckConfiguration: true - response: {} # Expecting any non-error response. + response: + json: !anydict - name: Get the deck configuration after the reset and make sure it's immediately gone back to the default request: diff --git a/robot-server/tests/protocols/test_protocols_router.py b/robot-server/tests/protocols/test_protocols_router.py index 995ead84a17..ac799382429 100644 --- a/robot-server/tests/protocols/test_protocols_router.py +++ b/robot-server/tests/protocols/test_protocols_router.py @@ -1,4 +1,5 @@ """Tests for the /protocols router.""" +import io import pytest from datetime import datetime from decoy import Decoy, matchers @@ -322,11 +323,11 @@ async def test_create_protocol( ) -> None: """It should store an uploaded protocol file.""" protocol_directory = Path("/dev/null") + content = bytes("some_content", encoding="utf-8") + uploaded_file = io.BytesIO(content) - protocol_file = UploadFile(filename="foo.json") - buffered_file = BufferedFile( - name="blah", contents=bytes("some_content", encoding="utf-8"), path=None - ) + protocol_file = UploadFile(filename="foo.json", file=uploaded_file) + buffered_file = BufferedFile(name="blah", contents=content, path=None) protocol_source = ProtocolSource( directory=Path("/dev/null"), @@ -355,9 +356,14 @@ async def test_create_protocol( status=AnalysisStatus.PENDING, ) - decoy.when(await file_reader_writer.read(files=[protocol_file])).then_return( - [buffered_file] - ) + decoy.when( + await file_reader_writer.read( + # TODO(mm, 2024-02-07): Recent FastAPI upgrades mean protocol_file.filename + # is typed as possibly None. Investigate whether that can actually happen in + # practice and whether we need to account for it. + files=[protocol_file] # type: ignore[list-item] + ) + ).then_return([buffered_file]) decoy.when(await file_hasher.hash(files=[buffered_file])).then_return("abc123") diff --git a/robot-server/tests/service/legacy/models/test_modules.py b/robot-server/tests/service/legacy/models/test_modules.py index 9f5c0700725..7e43d2a0774 100644 --- a/robot-server/tests/service/legacy/models/test_modules.py +++ b/robot-server/tests/service/legacy/models/test_modules.py @@ -3,7 +3,7 @@ def test_validate_command_no_type_conversion(): cmd = modules.SerialCommand(command_type="a_valid_cmd", args=["30"]) - assert type(cmd.args[0]) == str + assert isinstance(cmd.args[0], str) assert cmd.args[0] == "30" @@ -19,6 +19,6 @@ def test_validate_command_args_multiple_types(): 50.5, ], ) - assert type(cmd.args[0]) == list - assert type(cmd.args[1]) == int - assert type(cmd.args[2]) == float + assert isinstance(cmd.args[0], list) + assert isinstance(cmd.args[1], int) + assert isinstance(cmd.args[2], float) diff --git a/robot-server/tests/service/legacy/routers/test_settings.py b/robot-server/tests/service/legacy/routers/test_settings.py index b4fe6e380a3..80825e3e736 100644 --- a/robot-server/tests/service/legacy/routers/test_settings.py +++ b/robot-server/tests/service/legacy/routers/test_settings.py @@ -695,7 +695,7 @@ def mock_set_adv_setting(): def validate_response_body(body, restart): settings_list = body.get("settings") - assert type(settings_list) == list + assert isinstance(settings_list, list) for obj in settings_list: assert "id" in obj, '"id" field not found in settings object' assert "title" in obj, '"title" not found for {}'.format(obj["id"]) diff --git a/robot-server/tests/service/session/test_router.py b/robot-server/tests/service/session/test_router.py index 7a9c94cb31e..13e808e0660 100644 --- a/robot-server/tests/service/session/test_router.py +++ b/robot-server/tests/service/session/test_router.py @@ -69,7 +69,7 @@ def test_get_session(mock_session_manager): session = router.get_session(mock_session_manager, session_id) - mock_session_manager.get_by_id.called_once_with(session_id) + mock_session_manager.get_by_id.assert_called_once_with(session_id) assert session is mock_session diff --git a/robot-server/tests/service/test_logging.py b/robot-server/tests/service/test_logging.py index cd836b3b602..8da4ce278d3 100644 --- a/robot-server/tests/service/test_logging.py +++ b/robot-server/tests/service/test_logging.py @@ -2,14 +2,13 @@ import logging import pytest from robot_server.service import logging as rs_logging +from opentrons.config.types import RobotConfig @pytest.fixture def mock_robot_config(): - with patch("robot_server.service.logging.robot_configs") as m: - mock = MagicMock( - spec=rs_logging.robot_configs.robot_config # type: ignore[attr-defined] - ) + with patch("robot_server.service.logging.robot_configs", autospec=True) as m: + mock = MagicMock(spec=RobotConfig) m.load.return_value = mock yield mock diff --git a/server-utils/Config.in b/server-utils/Config.in index 79cfd4875b3..acfe2252adb 100644 --- a/server-utils/Config.in +++ b/server-utils/Config.in @@ -7,7 +7,6 @@ config BR2_PACKAGE_PYTHON_OPENTRONS_SERVER_UTILS select BR2_PACKAGE_PYTHON_MULTIPART # runtime select BR2_PACKAGE_PYTHON_PYDANTIC # runtime select BR2_PACKAGE_PYTHON_SQLALCHEMY # runtime - select BR2_PACKAGE_PYTHON_AIOSQLITE # runtime select BR2_PACKAGE_PYTHON_TYPING_EXTENSIONS # runtime select BR2_PACKAGE_PYTHON_UVICORN # runtime select BR2_PACKAGE_PYTHON_WSPROTO # runtime diff --git a/server-utils/Pipfile b/server-utils/Pipfile index ae589d277a7..b54d6962543 100755 --- a/server-utils/Pipfile +++ b/server-utils/Pipfile @@ -12,25 +12,26 @@ server-utils = { editable = true, path = "." } # https://github.com/pypa/pipenv/issues/4408#issuecomment-668324177 atomicwrites = { version = "==1.4.0", markers="sys_platform=='win32'" } colorama = { version = "==0.4.4", markers="sys_platform=='win32'" } -pytest = "~=7.1" -pytest-asyncio = "~=0.16" -pytest-cov = "==2.10.1" +pytest = "==7.4.4" +pytest-asyncio = "~=0.23.0" +pytest-cov = "==4.1.0" pytest-lazy-fixture = "==0.6.3" pytest-xdist = "~=2.5.0" -requests = "==2.27.1" -mock = "~=4.0.3" -mypy = "==0.981" -flake8 = "~=3.9.0" -flake8-annotations = "~=2.6.2" -flake8-docstrings = "~=1.6.0" -flake8-noqa = "~=1.2.1" -decoy = "~=1.10" +requests = "==2.31.0" +mock = "==5.1.0" +mypy = "==1.8.0" +flake8 = "==7.0.0" +flake8-annotations = "==3.0.1" +flake8-docstrings = "~=1.7.0" +flake8-noqa = "~=1.4.0" +decoy = "==2.1.1" httpx = "==0.18.*" black = "==22.3.0" -types-requests = "==2.25.6" -types-mock = "==4.0.1" +types-requests = "~=2.31.0" +types-mock = "~=5.1.0" sqlalchemy2-stubs = "==0.0.2a21" -python-box = "==5.4.1" +# the same version as robot-server, which is limited by tavern +python-box = "==6.1.0" [packages] idna = "==3.3" diff --git a/server-utils/Pipfile.lock b/server-utils/Pipfile.lock index 7f8c62a76ed..c9060279ba2 100644 --- a/server-utils/Pipfile.lock +++ b/server-utils/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "cc50e1adfd1023979f6306f3470f3e3f51cfc9b8defa50cac882385f9d05f71e" + "sha256": "5c9bee178723885363cdb4a226e6c1b7988731c23ae83fdde921d4ebb510090e" }, "pipfile-spec": 6, "requires": { @@ -27,29 +27,13 @@ } }, "develop": { - "aiosqlite": { - "hashes": [ - "sha256:6c49dc6d3405929b1d08eeccc72306d3677503cc5e5e43771efc1e00232e8231", - "sha256:f0e6acc24bc4864149267ac82fb46dfb3be4455f99fe21df82609cc6e6baee51" - ], - "markers": "python_version >= '3.6'", - "version": "==0.17.0" - }, "anyio": { "hashes": [ - "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b", - "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be" - ], - "markers": "python_full_version >= '3.6.2'", - "version": "==3.6.1" - }, - "asgiref": { - "hashes": [ - "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e", - "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed" + "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780", + "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5" ], "markers": "python_version >= '3.7'", - "version": "==3.7.2" + "version": "==3.7.1" }, "atomicwrites": { "hashes": [ @@ -59,6 +43,14 @@ "markers": "sys_platform == 'win32'", "version": "==1.4.0" }, + "attrs": { + "hashes": [ + "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", + "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" + ], + "markers": "python_version >= '3.7'", + "version": "==23.2.0" + }, "black": { "hashes": [ "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b", @@ -91,19 +83,107 @@ }, "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "version": "==2024.2.2" }, "charset-normalizer": { "hashes": [ - "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", - "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df" - ], - "markers": "python_version >= '3'", - "version": "==2.0.12" + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.3.2" }, "click": { "hashes": [ @@ -122,71 +202,74 @@ "version": "==0.4.4" }, "coverage": { - "hashes": [ - "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", - "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", - "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", - "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", - "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", - "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", - "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", - "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", - "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", - "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", - "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", - "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", - "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", - "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", - "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", - "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", - "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", - "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", - "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", - "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", - "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", - "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", - "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", - "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", - "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", - "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", - "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", - "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", - "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", - "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", - "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", - "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", - "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", - "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", - "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", - "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", - "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", - "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", - "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", - "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", - "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", - "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", - "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", - "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", - "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", - "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", - "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", - "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", - "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", - "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", - "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", - "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" + "extras": [ + "toml" + ], + "hashes": [ + "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61", + "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1", + "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7", + "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7", + "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75", + "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd", + "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35", + "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04", + "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6", + "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042", + "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166", + "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1", + "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d", + "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c", + "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66", + "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70", + "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1", + "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676", + "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630", + "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a", + "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74", + "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad", + "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19", + "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6", + "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448", + "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018", + "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218", + "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756", + "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54", + "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45", + "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628", + "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968", + "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d", + "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25", + "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60", + "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950", + "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06", + "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295", + "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b", + "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c", + "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc", + "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74", + "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1", + "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee", + "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011", + "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156", + "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766", + "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5", + "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581", + "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016", + "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c", + "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3" ], "markers": "python_version >= '3.8'", - "version": "==7.3.2" + "version": "==7.4.1" }, "decoy": { "hashes": [ - "sha256:57327a6ec24c4f4804d978f9c770cb0ff778d2ed751a45ffc61226bf10fc9f90", - "sha256:dea3634ed92eca686f71e66dfd43350adc1a96c814fb5492a08d3c251c531149" + "sha256:575bdbe81afb4c152cd99a34568a9aa4369461f79d6172c678279c5d5585befe", + "sha256:7ddcc08b8ce991f7705cee76fae9061dcb17352e0a1ca2d9a0d4a0306ebd51cd" ], "index": "pypi", - "markers": "python_version >= '3.6' and python_version < '4.0'", - "version": "==1.11.3" + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==2.1.1" }, "exceptiongroup": { "hashes": [ @@ -206,109 +289,47 @@ }, "fastapi": { "hashes": [ - "sha256:644bb815bae326575c4b2842469fb83053a4b974b82fa792ff9283d17fbbd99d", - "sha256:94d2820906c36b9b8303796fb7271337ec89c74223229e3cfcf056b5a7d59e23" + "sha256:976df7bab51ac7beda9f68c4513b8c4490b5c1135c72aafd0a5ee4023ec5282e", + "sha256:ac78f717cd80d657bd183f94d33b9bda84aa376a46a9dab513586b8eef1dc6fc" ], - "markers": "python_version >= '3.6'", - "version": "==0.68.1" + "markers": "python_version >= '3.7'", + "version": "==0.99.1" }, "flake8": { "hashes": [ - "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", - "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" + "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132", + "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.9.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==7.0.0" }, "flake8-annotations": { "hashes": [ - "sha256:0d6cd2e770b5095f09689c9d84cc054c51b929c41a68969ea1beb4b825cac515", - "sha256:d10c4638231f8a50c0a597c4efce42bd7b7d85df4f620a0ddaca526138936a4f" + "sha256:af78e3216ad800d7e144745ece6df706c81b3255290cbf870e54879d495e8ade", + "sha256:ff37375e71e3b83f2a5a04d443c41e2c407de557a884f3300a7fa32f3c41cb0a" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1' and python_full_version < '4.0.0'", - "version": "==2.6.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==3.0.1" }, "flake8-docstrings": { "hashes": [ - "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde", - "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b" + "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af", + "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75" ], "index": "pypi", - "version": "==1.6.0" + "markers": "python_version >= '3.7'", + "version": "==1.7.0" }, "flake8-noqa": { "hashes": [ - "sha256:26d92ca6b72dec732d294e587a2bdeb66dab01acc609ed6a064693d6baa4e789", - "sha256:445618162e0bbae1b9d983326d4e39066c5c6de71ba0c444ca2d4d1fa5b2cdb7" + "sha256:4465e16a19be433980f6f563d05540e2e54797eb11facb9feb50fed60624dc45", + "sha256:771765ab27d1efd157528379acd15131147f9ae578a72d17fb432ca197881243" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.2.9" - }, - "greenlet": { - "hashes": [ - "sha256:0a02d259510b3630f330c86557331a3b0e0c79dac3d166e449a39363beaae174", - "sha256:0b6f9f8ca7093fd4433472fd99b5650f8a26dcd8ba410e14094c1e44cd3ceddd", - "sha256:100f78a29707ca1525ea47388cec8a049405147719f47ebf3895e7509c6446aa", - "sha256:1757936efea16e3f03db20efd0cd50a1c86b06734f9f7338a90c4ba85ec2ad5a", - "sha256:19075157a10055759066854a973b3d1325d964d498a805bb68a1f9af4aaef8ec", - "sha256:19bbdf1cce0346ef7341705d71e2ecf6f41a35c311137f29b8a2dc2341374565", - "sha256:20107edf7c2c3644c67c12205dc60b1bb11d26b2610b276f97d666110d1b511d", - "sha256:22f79120a24aeeae2b4471c711dcf4f8c736a2bb2fabad2a67ac9a55ea72523c", - "sha256:2847e5d7beedb8d614186962c3d774d40d3374d580d2cbdab7f184580a39d234", - "sha256:28e89e232c7593d33cac35425b58950789962011cc274aa43ef8865f2e11f46d", - "sha256:329c5a2e5a0ee942f2992c5e3ff40be03e75f745f48847f118a3cfece7a28546", - "sha256:337322096d92808f76ad26061a8f5fccb22b0809bea39212cd6c406f6a7060d2", - "sha256:3fcc780ae8edbb1d050d920ab44790201f027d59fdbd21362340a85c79066a74", - "sha256:41bdeeb552d814bcd7fb52172b304898a35818107cc8778b5101423c9017b3de", - "sha256:4eddd98afc726f8aee1948858aed9e6feeb1758889dfd869072d4465973f6bfd", - "sha256:52e93b28db27ae7d208748f45d2db8a7b6a380e0d703f099c949d0f0d80b70e9", - "sha256:55d62807f1c5a1682075c62436702aaba941daa316e9161e4b6ccebbbf38bda3", - "sha256:5805e71e5b570d490938d55552f5a9e10f477c19400c38bf1d5190d760691846", - "sha256:599daf06ea59bfedbec564b1692b0166a0045f32b6f0933b0dd4df59a854caf2", - "sha256:60d5772e8195f4e9ebf74046a9121bbb90090f6550f81d8956a05387ba139353", - "sha256:696d8e7d82398e810f2b3622b24e87906763b6ebfd90e361e88eb85b0e554dc8", - "sha256:6e6061bf1e9565c29002e3c601cf68569c450be7fc3f7336671af7ddb4657166", - "sha256:80ac992f25d10aaebe1ee15df45ca0d7571d0f70b645c08ec68733fb7a020206", - "sha256:816bd9488a94cba78d93e1abb58000e8266fa9cc2aa9ccdd6eb0696acb24005b", - "sha256:85d2b77e7c9382f004b41d9c72c85537fac834fb141b0296942d52bf03fe4a3d", - "sha256:87c8ceb0cf8a5a51b8008b643844b7f4a8264a2c13fcbcd8a8316161725383fe", - "sha256:89ee2e967bd7ff85d84a2de09df10e021c9b38c7d91dead95b406ed6350c6997", - "sha256:8bef097455dea90ffe855286926ae02d8faa335ed8e4067326257cb571fc1445", - "sha256:8d11ebbd679e927593978aa44c10fc2092bc454b7d13fdc958d3e9d508aba7d0", - "sha256:91e6c7db42638dc45cf2e13c73be16bf83179f7859b07cfc139518941320be96", - "sha256:97e7ac860d64e2dcba5c5944cfc8fa9ea185cd84061c623536154d5a89237884", - "sha256:990066bff27c4fcf3b69382b86f4c99b3652bab2a7e685d968cd4d0cfc6f67c6", - "sha256:9fbc5b8f3dfe24784cee8ce0be3da2d8a79e46a276593db6868382d9c50d97b1", - "sha256:ac4a39d1abae48184d420aa8e5e63efd1b75c8444dd95daa3e03f6c6310e9619", - "sha256:b2c02d2ad98116e914d4f3155ffc905fd0c025d901ead3f6ed07385e19122c94", - "sha256:b2d3337dcfaa99698aa2377c81c9ca72fcd89c07e7eb62ece3f23a3fe89b2ce4", - "sha256:b489c36d1327868d207002391f662a1d163bdc8daf10ab2e5f6e41b9b96de3b1", - "sha256:b641161c302efbb860ae6b081f406839a8b7d5573f20a455539823802c655f63", - "sha256:b8ba29306c5de7717b5761b9ea74f9c72b9e2b834e24aa984da99cbfc70157fd", - "sha256:b9934adbd0f6e476f0ecff3c94626529f344f57b38c9a541f87098710b18af0a", - "sha256:ce85c43ae54845272f6f9cd8320d034d7a946e9773c693b27d620edec825e376", - "sha256:cf868e08690cb89360eebc73ba4be7fb461cfbc6168dd88e2fbbe6f31812cd57", - "sha256:d2905ce1df400360463c772b55d8e2518d0e488a87cdea13dd2c71dcb2a1fa16", - "sha256:d57e20ba591727da0c230ab2c3f200ac9d6d333860d85348816e1dca4cc4792e", - "sha256:d6a8c9d4f8692917a3dc7eb25a6fb337bff86909febe2f793ec1928cd97bedfc", - "sha256:d923ff276f1c1f9680d32832f8d6c040fe9306cbfb5d161b0911e9634be9ef0a", - "sha256:daa7197b43c707462f06d2c693ffdbb5991cbb8b80b5b984007de431493a319c", - "sha256:dbd4c177afb8a8d9ba348d925b0b67246147af806f0b104af4d24f144d461cd5", - "sha256:dc4d815b794fd8868c4d67602692c21bf5293a75e4b607bb92a11e821e2b859a", - "sha256:e9d21aaa84557d64209af04ff48e0ad5e28c5cca67ce43444e939579d085da72", - "sha256:ea6b8aa9e08eea388c5f7a276fabb1d4b6b9d6e4ceb12cc477c3d352001768a9", - "sha256:eabe7090db68c981fca689299c2d116400b553f4b713266b130cfc9e2aa9c5a9", - "sha256:f2f6d303f3dee132b322a14cd8765287b8f86cdc10d2cb6a6fae234ea488888e", - "sha256:f33f3258aae89da191c6ebaa3bc517c6c4cbc9b9f689e5d8452f7aedbb913fa8", - "sha256:f7bfb769f7efa0eefcd039dd19d843a4fbfbac52f1878b1da2ed5793ec9b1a65", - "sha256:f89e21afe925fcfa655965ca8ea10f24773a1791400989ff32f467badfe4a064", - "sha256:fa24255ae3c0ab67e613556375a4341af04a084bd58764731972bcbc8baeba36" - ], - "markers": "python_version >= '3' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))", - "version": "==3.0.1" + "version": "==1.4.0" }, "h11": { "hashes": [ @@ -354,50 +375,54 @@ }, "mccabe": { "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "version": "==0.6.1" + "markers": "python_version >= '3.6'", + "version": "==0.7.0" }, "mock": { "hashes": [ - "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62", - "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc" + "sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744", + "sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d" ], "index": "pypi", "markers": "python_version >= '3.6'", - "version": "==4.0.3" + "version": "==5.1.0" }, "mypy": { "hashes": [ - "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", - "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", - "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", - "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", - "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", - "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", - "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", - "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", - "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", - "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", - "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", - "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", - "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", - "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", - "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", - "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", - "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", - "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", - "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", - "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", - "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", - "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", - "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", - "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" + "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6", + "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d", + "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02", + "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d", + "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3", + "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3", + "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3", + "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66", + "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259", + "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835", + "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd", + "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d", + "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8", + "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07", + "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b", + "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e", + "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6", + "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae", + "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9", + "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d", + "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a", + "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592", + "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218", + "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817", + "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4", + "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410", + "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.981" + "markers": "python_version >= '3.8'", + "version": "==1.8.0" }, "mypy-extensions": { "hashes": [ @@ -417,27 +442,27 @@ }, "pathspec": { "hashes": [ - "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", - "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" + "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", + "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" ], - "markers": "python_version >= '3.7'", - "version": "==0.11.2" + "markers": "python_version >= '3.8'", + "version": "==0.12.1" }, "platformdirs": { "hashes": [ - "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", - "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", + "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "pluggy": { "hashes": [ - "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", - "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981", + "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be" ], "markers": "python_version >= '3.8'", - "version": "==1.3.0" + "version": "==1.4.0" }, "py": { "hashes": [ @@ -449,52 +474,53 @@ }, "pycodestyle": { "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" + "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.7.0" + "markers": "python_version >= '3.8'", + "version": "==2.11.1" }, "pydantic": { "hashes": [ - "sha256:1061c6ee6204f4f5a27133126854948e3b3d51fcc16ead2e5d04378c199b2f44", - "sha256:19b5686387ea0d1ea52ecc4cffb71abb21702c5e5b2ac626fd4dbaa0834aa49d", - "sha256:2bd446bdb7755c3a94e56d7bdfd3ee92396070efa8ef3a34fab9579fe6aa1d84", - "sha256:328558c9f2eed77bd8fffad3cef39dbbe3edc7044517f4625a769d45d4cf7555", - "sha256:32e0b4fb13ad4db4058a7c3c80e2569adbd810c25e6ca3bbd8b2a9cc2cc871d7", - "sha256:3ee0d69b2a5b341fc7927e92cae7ddcfd95e624dfc4870b32a85568bd65e6131", - "sha256:4aafd4e55e8ad5bd1b19572ea2df546ccace7945853832bb99422a79c70ce9b8", - "sha256:4b3946f87e5cef3ba2e7bd3a4eb5a20385fe36521d6cc1ebf3c08a6697c6cfb3", - "sha256:4de71c718c9756d679420c69f216776c2e977459f77e8f679a4a961dc7304a56", - "sha256:5565a49effe38d51882cb7bac18bda013cdb34d80ac336428e8908f0b72499b0", - "sha256:5803ad846cdd1ed0d97eb00292b870c29c1f03732a010e66908ff48a762f20e4", - "sha256:5da164119602212a3fe7e3bc08911a89db4710ae51444b4224c2382fd09ad453", - "sha256:615661bfc37e82ac677543704437ff737418e4ea04bef9cf11c6d27346606044", - "sha256:78a4d6bdfd116a559aeec9a4cfe77dda62acc6233f8b56a716edad2651023e5e", - "sha256:7d0f183b305629765910eaad707800d2f47c6ac5bcfb8c6397abdc30b69eeb15", - "sha256:7ead3cd020d526f75b4188e0a8d71c0dbbe1b4b6b5dc0ea775a93aca16256aeb", - "sha256:84d76ecc908d917f4684b354a39fd885d69dd0491be175f3465fe4b59811c001", - "sha256:8cb0bc509bfb71305d7a59d00163d5f9fc4530f0881ea32c74ff4f74c85f3d3d", - "sha256:91089b2e281713f3893cd01d8e576771cd5bfdfbff5d0ed95969f47ef6d676c3", - "sha256:9c9e04a6cdb7a363d7cb3ccf0efea51e0abb48e180c0d31dca8d247967d85c6e", - "sha256:a8c5360a0297a713b4123608a7909e6869e1b56d0e96eb0d792c27585d40757f", - "sha256:afacf6d2a41ed91fc631bade88b1d319c51ab5418870802cedb590b709c5ae3c", - "sha256:b34ba24f3e2d0b39b43f0ca62008f7ba962cff51efa56e64ee25c4af6eed987b", - "sha256:bd67cb2c2d9602ad159389c29e4ca964b86fa2f35c2faef54c3eb28b4efd36c8", - "sha256:c0f5e142ef8217019e3eef6ae1b6b55f09a7a15972958d44fbd228214cede567", - "sha256:cdb4272678db803ddf94caa4f94f8672e9a46bae4a44f167095e4d06fec12979", - "sha256:d70916235d478404a3fa8c997b003b5f33aeac4686ac1baa767234a0f8ac2326", - "sha256:d8ce3fb0841763a89322ea0432f1f59a2d3feae07a63ea2c958b2315e1ae8adb", - "sha256:e0b214e57623a535936005797567231a12d0da0c29711eb3514bc2b3cd008d0f", - "sha256:e631c70c9280e3129f071635b81207cad85e6c08e253539467e4ead0e5b219aa", - "sha256:e78578f0c7481c850d1c969aca9a65405887003484d24f6110458fb02cca7747", - "sha256:f0ca86b525264daa5f6b192f216a0d1e860b7383e3da1c65a1908f9c02f42801", - "sha256:f1a68f4f65a9ee64b6ccccb5bf7e17db07caebd2730109cb8a95863cfa9c4e55", - "sha256:fafe841be1103f340a24977f61dee76172e4ae5f647ab9e7fd1e1fca51524f08", - "sha256:ff68fc85355532ea77559ede81f35fff79a6a5543477e168ab3a381887caea76" - ], - "markers": "python_full_version >= '3.6.1'", - "version": "==1.9.2" + "sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303", + "sha256:1289c180abd4bd4555bb927c42ee42abc3aee02b0fb2d1223fb7c6e5bef87dbe", + "sha256:1eb2085c13bce1612da8537b2d90f549c8cbb05c67e8f22854e201bde5d98a47", + "sha256:2031de0967c279df0d8a1c72b4ffc411ecd06bac607a212892757db7462fc494", + "sha256:2a7bac939fa326db1ab741c9d7f44c565a1d1e80908b3797f7f81a4f86bc8d33", + "sha256:2d5a58feb9a39f481eda4d5ca220aa8b9d4f21a41274760b9bc66bfd72595b86", + "sha256:2f9a6fab5f82ada41d56b0602606a5506aab165ca54e52bc4545028382ef1c5d", + "sha256:2fcfb5296d7877af406ba1547dfde9943b1256d8928732267e2653c26938cd9c", + "sha256:549a8e3d81df0a85226963611950b12d2d334f214436a19537b2efed61b7639a", + "sha256:598da88dfa127b666852bef6d0d796573a8cf5009ffd62104094a4fe39599565", + "sha256:5d1197e462e0364906cbc19681605cb7c036f2475c899b6f296104ad42b9f5fb", + "sha256:69328e15cfda2c392da4e713443c7dbffa1505bc9d566e71e55abe14c97ddc62", + "sha256:6a9dfa722316f4acf4460afdf5d41d5246a80e249c7ff475c43a3a1e9d75cf62", + "sha256:6b30bcb8cbfccfcf02acb8f1a261143fab622831d9c0989707e0e659f77a18e0", + "sha256:6c076be61cd0177a8433c0adcb03475baf4ee91edf5a4e550161ad57fc90f523", + "sha256:771735dc43cf8383959dc9b90aa281f0b6092321ca98677c5fb6125a6f56d58d", + "sha256:795e34e6cc065f8f498c89b894a3c6da294a936ee71e644e4bd44de048af1405", + "sha256:87afda5539d5140cb8ba9e8b8c8865cb5b1463924d38490d73d3ccfd80896b3f", + "sha256:8fb2aa3ab3728d950bcc885a2e9eff6c8fc40bc0b7bb434e555c215491bcf48b", + "sha256:a1fcb59f2f355ec350073af41d927bf83a63b50e640f4dbaa01053a28b7a7718", + "sha256:a5e7add47a5b5a40c49b3036d464e3c7802f8ae0d1e66035ea16aa5b7a3923ed", + "sha256:a73f489aebd0c2121ed974054cb2759af8a9f747de120acd2c3394cf84176ccb", + "sha256:ab26038b8375581dc832a63c948f261ae0aa21f1d34c1293469f135fa92972a5", + "sha256:b0d191db0f92dfcb1dec210ca244fdae5cbe918c6050b342d619c09d31eea0cc", + "sha256:b749a43aa51e32839c9d71dc67eb1e4221bb04af1033a32e3923d46f9effa942", + "sha256:b7ccf02d7eb340b216ec33e53a3a629856afe1c6e0ef91d84a4e6f2fb2ca70fe", + "sha256:ba5b2e6fe6ca2b7e013398bc7d7b170e21cce322d266ffcd57cca313e54fb246", + "sha256:ba5c4a8552bff16c61882db58544116d021d0b31ee7c66958d14cf386a5b5350", + "sha256:c79e6a11a07da7374f46970410b41d5e266f7f38f6a17a9c4823db80dadf4303", + "sha256:ca48477862372ac3770969b9d75f1bf66131d386dba79506c46d75e6b48c1e09", + "sha256:dea7adcc33d5d105896401a1f37d56b47d443a2b2605ff8a969a0ed5543f7e33", + "sha256:e0a16d274b588767602b7646fa05af2782576a6cf1022f4ba74cbb4db66f6ca8", + "sha256:e4129b528c6baa99a429f97ce733fff478ec955513630e61b49804b6cf9b224a", + "sha256:e5f805d2d5d0a41633651a73fa4ecdd0b3d7a49de4ec3fadf062fe16501ddbf1", + "sha256:ef6c96b2baa2100ec91a4b428f80d8f28a3c9e53568219b6c298c1125572ebc6", + "sha256:fdbdd1d630195689f325c9ef1a12900524dceb503b00a987663ff4f58669b93d" + ], + "markers": "python_version >= '3.7'", + "version": "==1.10.12" }, "pydocstyle": { "hashes": [ @@ -506,38 +532,38 @@ }, "pyflakes": { "hashes": [ - "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", - "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" + "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", + "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.3.1" + "markers": "python_version >= '3.8'", + "version": "==3.2.0" }, "pytest": { "hashes": [ - "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac", - "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5" + "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", + "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==7.4.3" + "version": "==7.4.4" }, "pytest-asyncio": { "hashes": [ - "sha256:c16052382554c7b22d48782ab3438d5b10f8cf7a4bdcae7f0f67f097d95beecc", - "sha256:ea9021364e32d58f0be43b91c6233fb8d2224ccef2398d6837559e587682808f" + "sha256:2143d9d9375bf372a73260e4114541485e84fca350b0b6b92674ca56ff5f7ea2", + "sha256:b0079dfac14b60cd1ce4691fbfb1748fe939db7d0234b5aba97197d10fbe0fef" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==0.23.2" + "version": "==0.23.4" }, "pytest-cov": { "hashes": [ - "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191", - "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e" + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.10.1" + "markers": "python_version >= '3.7'", + "version": "==4.1.0" }, "pytest-forked": { "hashes": [ @@ -566,35 +592,52 @@ }, "python-box": { "hashes": [ - "sha256:60ae9156de34cf92b899bd099580950df70a5b0813e67a3310a1cdd1976457fa", - "sha256:b68e0f8abc86f3deda751b3390f64df64a0989459de51ba4db949662a7b4d8ac" + "sha256:11cbe62f0dace8a6e2a10d210a5e87b99ad1a1286865568862516794c923a988", + "sha256:1d29eafaa287857751e27fbe9a08dd856480f0037fe988b221eba4dac33e5852", + "sha256:3638d3559f19ece7fa29f6a6550bc64696cd3b65e3d4154df07a3d06982252ff", + "sha256:3f0036f91e13958d2b37d2bc74c1197aa36ffd66755342eb64910f63d8a2990f", + "sha256:53998c3b95e31d1f31e46279ef1d27ac30b137746927260901ee61457f8468a0", + "sha256:594b0363b187df855ff8649488b1301dddbbeea769629b7caeb584efe779b841", + "sha256:6e7c243b356cb36e2c0f0e5ed7850969fede6aa812a7f501de7768996c7744d7", + "sha256:7b73f26e40a7adc57b9e39f5687d026dfa8a336f48aefaf852a223b4e37392ad", + "sha256:9dbd92b67c443a97326273c9239fce04d3b6958be815d293f96ab65bc4a9dae7", + "sha256:ab13208b053525ef154a36a4a52873b98a12b18b946edd4c939a4d5080e9a218", + "sha256:ac44b3b85714a4575cc273b5dbd39ef739f938ef6c522d6757704a29e7797d16", + "sha256:af6bcee7e1abe9251e9a41ca9ab677e1f679f6059321cfbae7e78a3831e0b736", + "sha256:bdec0a5f5a17b01fc538d292602a077aa8c641fb121e1900dff0591791af80e8", + "sha256:c14aa4e72bf30f4d573e62ff8030a86548603a100c3fb534561dbedf4a83f454", + "sha256:d199cd289b4f4d053770eadd70217c76214aac30b92a23adfb9627fd8558d300", + "sha256:ed6d7fe47d756dc2d9dea448702cea103716580a2efee7c859954929295fe28e", + "sha256:fa4696b5e09ccf695bf05c16bb5ca1fcc95a141a71a31eb262eee8e2ac07189a" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==5.4.1" + "markers": "python_version >= '3.7'", + "version": "==6.1.0" }, "python-dotenv": { "hashes": [ - "sha256:aae25dc1ebe97c420f50b81fb0e5c949659af713f31fdb63c749ca68748f34b1", - "sha256:f521bc2ac9a8e03c736f62911605c5d83970021e3fa95b37d769e2bbbe9b6172" + "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", + "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a" ], - "markers": "python_version >= '3.5'", - "version": "==0.19.0" + "markers": "python_version >= '3.8'", + "version": "==1.0.1" }, "python-multipart": { "hashes": [ - "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43" + "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132", + "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18" ], - "version": "==0.0.5" + "markers": "python_version >= '3.7'", + "version": "==0.0.6" }, "requests": { "hashes": [ - "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", - "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d" + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==2.27.1" + "markers": "python_version >= '3.7'", + "version": "==2.31.0" }, "rfc3986": { "extras": [ @@ -610,14 +653,6 @@ "editable": true, "path": "." }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, "sniffio": { "hashes": [ "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", @@ -635,44 +670,55 @@ }, "sqlalchemy": { "hashes": [ - "sha256:04164e0063feb7aedd9d073db0fd496edb244be40d46ea1f0d8990815e4b8c34", - "sha256:159c2f69dd6efd28e894f261ffca1100690f28210f34cfcd70b895e0ea7a64f3", - "sha256:199dc6d0068753b6a8c0bd3aceb86a3e782df118260ebc1fa981ea31ee054674", - "sha256:1bbac3e8293b34c4403d297e21e8f10d2a57756b75cff101dc62186adec725f5", - "sha256:20e9eba7fd86ef52e0df25bea83b8b518dfdf0bce09b336cfe51671f52aaaa3f", - "sha256:290cbdf19129ae520d4bdce392648c6fcdbee763bc8f750b53a5ab51880cb9c9", - "sha256:316270e5867566376e69a0ac738b863d41396e2b63274616817e1d34156dff0e", - "sha256:3f88a4ee192142eeed3fe173f673ea6ab1f5a863810a9d85dbf6c67a9bd08f97", - "sha256:4aa96e957141006181ca58e792e900ee511085b8dae06c2d08c00f108280fb8a", - "sha256:4b2bcab3a914715d332ca783e9bda13bc570d8b9ef087563210ba63082c18c16", - "sha256:576684771456d02e24078047c2567025f2011977aa342063468577d94e194b00", - "sha256:5a2e73508f939175363d8a4be9dcdc84cf16a92578d7fa86e6e4ca0e6b3667b2", - "sha256:5ba59761c19b800bc2e1c9324da04d35ef51e4ee9621ff37534bc2290d258f71", - "sha256:5dc9801ae9884e822ba942ca493642fb50f049c06b6dbe3178691fce48ceb089", - "sha256:6fdd2dc5931daab778c2b65b03df6ae68376e028a3098eb624d0909d999885bc", - "sha256:708973b5d9e1e441188124aaf13c121e5b03b6054c2df59b32219175a25aa13e", - "sha256:7ff72b3cc9242d1a1c9b84bd945907bf174d74fc2519efe6184d6390a8df478b", - "sha256:8679f9aba5ac22e7bce54ccd8a77641d3aea3e2d96e73e4356c887ebf8ff1082", - "sha256:8b9a395122770a6f08ebfd0321546d7379f43505882c7419d7886856a07caa13", - "sha256:8e1e5d96b744a4f91163290b01045430f3f32579e46d87282449e5b14d27d4ac", - "sha256:9a0195af6b9050c9322a97cf07514f66fe511968e623ca87b2df5e3cf6349615", - "sha256:9cb5698c896fa72f88e7ef04ef62572faf56809093180771d9be8d9f2e264a13", - "sha256:b3f1d9b3aa09ab9adc7f8c4b40fc3e081eb903054c9a6f9ae1633fe15ae503b4", - "sha256:bb42f9b259c33662c6a9b866012f6908a91731a419e69304e1261ba3ab87b8d1", - "sha256:bca714d831e5b8860c3ab134c93aec63d1a4f493bed20084f54e3ce9f0a3bf99", - "sha256:bedd89c34ab62565d44745212814e4b57ef1c24ad4af9b29c504ce40f0dc6558", - "sha256:bfec934aac7f9fa95fc82147a4ba5db0a8bdc4ebf1e33b585ab8860beb10232f", - "sha256:c7046f7aa2db445daccc8424f50b47a66c4039c9f058246b43796aa818f8b751", - "sha256:d7e483f4791fbda60e23926b098702340504f7684ce7e1fd2c1bf02029288423", - "sha256:dd93162615870c976dba43963a24bb418b28448fef584f30755990c134a06a55", - "sha256:e4607d2d16330757818c9d6fba322c2e80b4b112ff24295d1343a80b876eb0ed", - "sha256:e9a680d9665f88346ed339888781f5236347933906c5a56348abb8261282ec48", - "sha256:edfcf93fd92e2f9eef640b3a7a40db20fe3c1d7c2c74faa41424c63dead61b76", - "sha256:f7e4a3c0c3c596296b37f8427c467c8e4336dc8d50f8ed38042e8ba79507b2c9", - "sha256:fff677fa4522dafb5a5e2c0cf909790d5d367326321aeabc0dffc9047cb235bd" + "sha256:0525c4905b4b52d8ccc3c203c9d7ab2a80329ffa077d4bacf31aefda7604dc65", + "sha256:0535d5b57d014d06ceeaeffd816bb3a6e2dddeb670222570b8c4953e2d2ea678", + "sha256:0892e7ac8bc76da499ad3ee8de8da4d7905a3110b952e2a35a940dab1ffa550e", + "sha256:0d661cff58c91726c601cc0ee626bf167b20cc4d7941c93c5f3ac28dc34ddbea", + "sha256:1980e6eb6c9be49ea8f89889989127daafc43f0b1b6843d71efab1514973cca0", + "sha256:1a09d5bd1a40d76ad90e5570530e082ddc000e1d92de495746f6257dc08f166b", + "sha256:245c67c88e63f1523e9216cad6ba3107dea2d3ee19adc359597a628afcabfbcb", + "sha256:2ad16880ccd971ac8e570550fbdef1385e094b022d6fc85ef3ce7df400dddad3", + "sha256:2be4e6294c53f2ec8ea36486b56390e3bcaa052bf3a9a47005687ccf376745d1", + "sha256:2c55040d8ea65414de7c47f1a23823cd9f3fad0dc93e6b6b728fee81230f817b", + "sha256:352df882088a55293f621328ec33b6ffca936ad7f23013b22520542e1ab6ad1b", + "sha256:3823dda635988e6744d4417e13f2e2b5fe76c4bf29dd67e95f98717e1b094cad", + "sha256:38ef80328e3fee2be0a1abe3fe9445d3a2e52a1282ba342d0dab6edf1fef4707", + "sha256:39b02b645632c5fe46b8dd30755682f629ffbb62ff317ecc14c998c21b2896ff", + "sha256:3b0cd89a7bd03f57ae58263d0f828a072d1b440c8c2949f38f3b446148321171", + "sha256:3ec7a0ed9b32afdf337172678a4a0e6419775ba4e649b66f49415615fa47efbd", + "sha256:3f0ef620ecbab46e81035cf3dedfb412a7da35340500ba470f9ce43a1e6c423b", + "sha256:50e074aea505f4427151c286955ea025f51752fa42f9939749336672e0674c81", + "sha256:55e699466106d09f028ab78d3c2e1f621b5ef2c8694598242259e4515715da7c", + "sha256:5e180fff133d21a800c4f050733d59340f40d42364fcb9d14f6a67764bdc48d2", + "sha256:6cacc0b2dd7d22a918a9642fc89840a5d3cee18a0e1fe41080b1141b23b10916", + "sha256:7af40425ac535cbda129d9915edcaa002afe35d84609fd3b9d6a8c46732e02ee", + "sha256:7d8139ca0b9f93890ab899da678816518af74312bb8cd71fb721436a93a93298", + "sha256:7deeae5071930abb3669b5185abb6c33ddfd2398f87660fafdb9e6a5fb0f3f2f", + "sha256:86a22143a4001f53bf58027b044da1fb10d67b62a785fc1390b5c7f089d9838c", + "sha256:8ca484ca11c65e05639ffe80f20d45e6be81fbec7683d6c9a15cd421e6e8b340", + "sha256:8d1d7d63e5d2f4e92a39ae1e897a5d551720179bb8d1254883e7113d3826d43c", + "sha256:8e702e7489f39375601c7ea5a0bef207256828a2bc5986c65cb15cd0cf097a87", + "sha256:a055ba17f4675aadcda3005df2e28a86feb731fdcc865e1f6b4f209ed1225cba", + "sha256:a33cb3f095e7d776ec76e79d92d83117438b6153510770fcd57b9c96f9ef623d", + "sha256:a61184c7289146c8cff06b6b41807c6994c6d437278e72cf00ff7fe1c7a263d1", + "sha256:af55cc207865d641a57f7044e98b08b09220da3d1b13a46f26487cc2f898a072", + "sha256:b00cf0471888823b7a9f722c6c41eb6985cf34f077edcf62695ac4bed6ec01ee", + "sha256:b03850c290c765b87102959ea53299dc9addf76ca08a06ea98383348ae205c99", + "sha256:b97fd5bb6b7c1a64b7ac0632f7ce389b8ab362e7bd5f60654c2a418496be5d7f", + "sha256:c37bc677690fd33932182b85d37433845de612962ed080c3e4d92f758d1bd894", + "sha256:cecb66492440ae8592797dd705a0cbaa6abe0555f4fa6c5f40b078bd2740fc6b", + "sha256:d0a83afab5e062abffcdcbcc74f9d3ba37b2385294dd0927ad65fc6ebe04e054", + "sha256:d3cf56cc36d42908495760b223ca9c2c0f9f0002b4eddc994b24db5fcb86a9e4", + "sha256:e646b19f47d655261b22df9976e572f588185279970efba3d45c377127d35349", + "sha256:e7908c2025eb18394e32d65dd02d2e37e17d733cdbe7d78231c2b6d7eb20cdb9", + "sha256:e8f2df79a46e130235bc5e1bbef4de0583fb19d481eaa0bffa76e8347ea45ec6", + "sha256:eaeeb2464019765bc4340214fca1143081d49972864773f3f1e95dba5c7edc7d", + "sha256:eb18549b770351b54e1ab5da37d22bc530b8bfe2ee31e22b9ebe650640d2ef12", + "sha256:f2e5b6f5cf7c18df66d082604a1d9c7a2d18f7d1dbe9514a2afaccbb51cc4fc3", + "sha256:f8cafa6f885a0ff5e39efa9325195217bb47d5929ab0051636610d24aef45ade" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.4.32" + "version": "==1.4.51" }, "sqlalchemy2-stubs": { "hashes": [ @@ -685,11 +731,11 @@ }, "starlette": { "hashes": [ - "sha256:3c8e48e52736b3161e34c9f0e8153b4f32ec5d8995a3ee1d59410d92f75162ed", - "sha256:7d49f4a27f8742262ef1470608c59ddbc66baf37c148e938c7038e6bc7a998aa" + "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75", + "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91" ], - "markers": "python_version >= '3.6'", - "version": "==0.14.2" + "markers": "python_version >= '3.7'", + "version": "==0.27.0" }, "tomli": { "hashes": [ @@ -701,50 +747,53 @@ }, "types-mock": { "hashes": [ - "sha256:1a470543be8de673e2ea14739622de3bfb8c9b10429f50338ba9ca1e868c15e9", - "sha256:1ad09970f4f5ec45a138ab1e88d032f010e851bccef7765b34737ed390bbc5c8" + "sha256:13ca379d5710ccb3f18f69ade5b08881874cb83383d8fb49b1d4dac9d5c5d090", + "sha256:3d116955495935b0bcba14954b38d97e507cd43eca3e3700fc1b8e4f5c6bf2c7" ], "index": "pypi", - "version": "==4.0.1" + "markers": "python_version >= '3.8'", + "version": "==5.1.0.20240106" }, "types-requests": { "hashes": [ - "sha256:a5a305b43ea57bf64d6731f89816946a405b591eff6de28d4c0fd58422cee779", - "sha256:e21541c0f55c066c491a639309159556dd8c5833e49fcde929c4c47bdb0002ee" + "sha256:03a28ce1d7cd54199148e043b2079cdded22d6795d19a2c2a6791a4b2b5e2eb5", + "sha256:9592a9a4cb92d6d75d9b491a41477272b710e021011a2a3061157e2fb1f1a5d1" ], "index": "pypi", - "version": "==2.25.6" + "markers": "python_version >= '3.8'", + "version": "==2.31.0.20240125" }, "typing-extensions": { "hashes": [ - "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", - "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "markers": "python_version >= '3.8'", - "version": "==4.8.0" + "version": "==4.9.0" }, "urllib3": { "hashes": [ - "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07", - "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0" + "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20", + "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.26.18" + "markers": "python_version >= '3.8'", + "version": "==2.2.0" }, "uvicorn": { "hashes": [ - "sha256:2a76bb359171a504b3d1c853409af3adbfa5cef374a4a59e5881945a97a93eae", - "sha256:45ad7dfaaa7d55cab4cd1e85e03f27e9d60bc067ddc59db52a2b0aeca8870292" + "sha256:4b85ba02b8a20429b9b205d015cbeb788a12da527f731811b643fd739ef90d5f", + "sha256:54898fcd80c13ff1cd28bf77b04ec9dbd8ff60c5259b499b4b12bb0917f22907" ], - "version": "==0.14.0" + "markers": "python_version >= '3.8'", + "version": "==0.27.0.post1" }, "wsproto": { "hashes": [ - "sha256:868776f8456997ad0d9720f7322b746bbe9193751b5b290b7f924659377c8c38", - "sha256:d8345d1808dd599b5ffb352c25a367adb6157e664e140dbecba3f9bc007edb9f" + "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", + "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736" ], - "markers": "python_full_version >= '3.6.1'", - "version": "==1.0.0" + "markers": "python_full_version >= '3.7.0'", + "version": "==1.2.0" } } } diff --git a/server-utils/server_utils/util.py b/server-utils/server_utils/util.py index 631b4b6c979..ae409452b33 100644 --- a/server-utils/server_utils/util.py +++ b/server-utils/server_utils/util.py @@ -41,7 +41,7 @@ class FileMeta: def save_upload(directory: Path, upload_file: UploadFile) -> FileMeta: """Save an uploaded file.""" - path = directory / upload_file.filename + path = directory / (upload_file.filename or "") contents = upload_file.file.read() content_hash = hashlib.sha256(contents).hexdigest() diff --git a/server-utils/setup.py b/server-utils/setup.py index 47204f4168d..41cab81de03 100755 --- a/server-utils/setup.py +++ b/server-utils/setup.py @@ -51,17 +51,16 @@ def get_version(): DESCRIPTION = "Common utilities for various Opentrons Python servers." PACKAGES = find_packages(where=".", exclude=["tests.*", "tests"]) INSTALL_REQUIRES = [ - "anyio==3.6.1", - "fastapi==0.68.1", - "python-dotenv==0.19.0", - "python-multipart==0.0.5", - "pydantic==1.9.2", + "anyio==3.7.1", + "fastapi==0.99.1", + "python-dotenv==1.0.1", + "python-multipart==0.0.6", + "pydantic==1.10.12", "typing-extensions>=4.0.0,<5", - "uvicorn==0.14.0", - "wsproto==1.0.0", + "uvicorn==0.27.0.post1", + "wsproto==1.2.0", "systemd-python==234; sys_platform=='linux'", - "sqlalchemy==1.4.32", - "aiosqlite==0.17.0", + "sqlalchemy==1.4.51", ] diff --git a/shared-data/command/schemas/8.json b/shared-data/command/schemas/8.json index 3895b046765..c2eb0a0e2a8 100644 --- a/shared-data/command/schemas/8.json +++ b/shared-data/command/schemas/8.json @@ -66,7 +66,7 @@ "calibration/moveToMaintenancePosition": "#/definitions/MoveToMaintenancePositionCreate" } }, - "anyOf": [ + "oneOf": [ { "$ref": "#/definitions/AspirateCreate" }, diff --git a/shared-data/python/Pipfile b/shared-data/python/Pipfile index 3bc47618711..0d11a1d68c9 100644 --- a/shared-data/python/Pipfile +++ b/shared-data/python/Pipfile @@ -4,17 +4,17 @@ verify_ssl = true name = "pypi" [dev-packages] -mypy = "==0.981" -flake8 = "~=3.9.0" -flake8-annotations = "~=2.6.2" -flake8-docstrings = "~=1.6.0" -flake8-noqa = "~=1.2.1" +mypy = "==1.8.0" +flake8 = "~=7.0.0" +flake8-annotations = "~=3.0.1" +flake8-docstrings = "~=1.7.0" +flake8-noqa = "~=1.4.0" twine = "==4.0.0" wheel = "==0.37.1" -pytest = "==7.1.1" -pytest-cov = "==2.10.1" -pytest-xdist = "~=2.5.0 " -typeguard = "~=2.13" +pytest = "==7.4.4" +pytest-cov = "==4.1.0" +pytest-xdist = "~=3.5.0 " +typeguard = "~=4.1.5" # specify typing-extensions explicitly to force lockfile inclusion on Python >= 3.8 typing-extensions = ">=4.0.0,<5" # pytest dependencies on windows, spec'd here to force lockfile inclusion @@ -26,3 +26,5 @@ pytest-clarity = "~=1.0.0" [packages] opentrons-shared-data = { editable = true, path = "." } +jsonschema = "==4.21.1" +pydantic = "==1.10.12" diff --git a/shared-data/python/Pipfile.lock b/shared-data/python/Pipfile.lock index 13cfff4c0b2..a125943127f 100644 --- a/shared-data/python/Pipfile.lock +++ b/shared-data/python/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2d611ea3d172368c7ba5a2fbab4f113b2eef82b00b4d3b17bbc0f853df627a60" + "sha256": "9b5174a247c5fe717a5db26f523afd532a6b0fc27943d86f6588839785ef51f4" }, "pipfile-spec": 6, "requires": {}, @@ -16,18 +16,28 @@ "default": { "attrs": { "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", + "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" ], "markers": "python_version >= '3.7'", - "version": "==23.1.0" + "version": "==23.2.0" }, "jsonschema": { "hashes": [ - "sha256:5f9c0a719ca2ce14c5de2fd350a64fd2d13e8539db29836a86adc990bb1a068f", - "sha256:8d4a2b7b6c2237e0199c8ea1a6d3e05bf118e289ae2b9d7ba444182a2959560d" + "sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f", + "sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5" ], - "version": "==3.0.2" + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==4.21.1" + }, + "jsonschema-specifications": { + "hashes": [ + "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc", + "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c" + ], + "markers": "python_version >= '3.8'", + "version": "==2023.12.1" }, "opentrons-shared-data": { "editable": true, @@ -36,106 +46,167 @@ }, "pydantic": { "hashes": [ - "sha256:1061c6ee6204f4f5a27133126854948e3b3d51fcc16ead2e5d04378c199b2f44", - "sha256:19b5686387ea0d1ea52ecc4cffb71abb21702c5e5b2ac626fd4dbaa0834aa49d", - "sha256:2bd446bdb7755c3a94e56d7bdfd3ee92396070efa8ef3a34fab9579fe6aa1d84", - "sha256:328558c9f2eed77bd8fffad3cef39dbbe3edc7044517f4625a769d45d4cf7555", - "sha256:32e0b4fb13ad4db4058a7c3c80e2569adbd810c25e6ca3bbd8b2a9cc2cc871d7", - "sha256:3ee0d69b2a5b341fc7927e92cae7ddcfd95e624dfc4870b32a85568bd65e6131", - "sha256:4aafd4e55e8ad5bd1b19572ea2df546ccace7945853832bb99422a79c70ce9b8", - "sha256:4b3946f87e5cef3ba2e7bd3a4eb5a20385fe36521d6cc1ebf3c08a6697c6cfb3", - "sha256:4de71c718c9756d679420c69f216776c2e977459f77e8f679a4a961dc7304a56", - "sha256:5565a49effe38d51882cb7bac18bda013cdb34d80ac336428e8908f0b72499b0", - "sha256:5803ad846cdd1ed0d97eb00292b870c29c1f03732a010e66908ff48a762f20e4", - "sha256:5da164119602212a3fe7e3bc08911a89db4710ae51444b4224c2382fd09ad453", - "sha256:615661bfc37e82ac677543704437ff737418e4ea04bef9cf11c6d27346606044", - "sha256:78a4d6bdfd116a559aeec9a4cfe77dda62acc6233f8b56a716edad2651023e5e", - "sha256:7d0f183b305629765910eaad707800d2f47c6ac5bcfb8c6397abdc30b69eeb15", - "sha256:7ead3cd020d526f75b4188e0a8d71c0dbbe1b4b6b5dc0ea775a93aca16256aeb", - "sha256:84d76ecc908d917f4684b354a39fd885d69dd0491be175f3465fe4b59811c001", - "sha256:8cb0bc509bfb71305d7a59d00163d5f9fc4530f0881ea32c74ff4f74c85f3d3d", - "sha256:91089b2e281713f3893cd01d8e576771cd5bfdfbff5d0ed95969f47ef6d676c3", - "sha256:9c9e04a6cdb7a363d7cb3ccf0efea51e0abb48e180c0d31dca8d247967d85c6e", - "sha256:a8c5360a0297a713b4123608a7909e6869e1b56d0e96eb0d792c27585d40757f", - "sha256:afacf6d2a41ed91fc631bade88b1d319c51ab5418870802cedb590b709c5ae3c", - "sha256:b34ba24f3e2d0b39b43f0ca62008f7ba962cff51efa56e64ee25c4af6eed987b", - "sha256:bd67cb2c2d9602ad159389c29e4ca964b86fa2f35c2faef54c3eb28b4efd36c8", - "sha256:c0f5e142ef8217019e3eef6ae1b6b55f09a7a15972958d44fbd228214cede567", - "sha256:cdb4272678db803ddf94caa4f94f8672e9a46bae4a44f167095e4d06fec12979", - "sha256:d70916235d478404a3fa8c997b003b5f33aeac4686ac1baa767234a0f8ac2326", - "sha256:d8ce3fb0841763a89322ea0432f1f59a2d3feae07a63ea2c958b2315e1ae8adb", - "sha256:e0b214e57623a535936005797567231a12d0da0c29711eb3514bc2b3cd008d0f", - "sha256:e631c70c9280e3129f071635b81207cad85e6c08e253539467e4ead0e5b219aa", - "sha256:e78578f0c7481c850d1c969aca9a65405887003484d24f6110458fb02cca7747", - "sha256:f0ca86b525264daa5f6b192f216a0d1e860b7383e3da1c65a1908f9c02f42801", - "sha256:f1a68f4f65a9ee64b6ccccb5bf7e17db07caebd2730109cb8a95863cfa9c4e55", - "sha256:fafe841be1103f340a24977f61dee76172e4ae5f647ab9e7fd1e1fca51524f08", - "sha256:ff68fc85355532ea77559ede81f35fff79a6a5543477e168ab3a381887caea76" - ], - "markers": "python_full_version >= '3.6.1'", - "version": "==1.9.2" - }, - "pyrsistent": { - "hashes": [ - "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f", - "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e", - "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958", - "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34", - "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca", - "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d", - "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d", - "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4", - "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714", - "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf", - "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee", - "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8", - "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224", - "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d", - "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054", - "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656", - "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7", - "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423", - "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce", - "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e", - "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3", - "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0", - "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f", - "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b", - "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce", - "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a", - "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174", - "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86", - "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f", - "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b", - "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98", - "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022" + "sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303", + "sha256:1289c180abd4bd4555bb927c42ee42abc3aee02b0fb2d1223fb7c6e5bef87dbe", + "sha256:1eb2085c13bce1612da8537b2d90f549c8cbb05c67e8f22854e201bde5d98a47", + "sha256:2031de0967c279df0d8a1c72b4ffc411ecd06bac607a212892757db7462fc494", + "sha256:2a7bac939fa326db1ab741c9d7f44c565a1d1e80908b3797f7f81a4f86bc8d33", + "sha256:2d5a58feb9a39f481eda4d5ca220aa8b9d4f21a41274760b9bc66bfd72595b86", + "sha256:2f9a6fab5f82ada41d56b0602606a5506aab165ca54e52bc4545028382ef1c5d", + "sha256:2fcfb5296d7877af406ba1547dfde9943b1256d8928732267e2653c26938cd9c", + "sha256:549a8e3d81df0a85226963611950b12d2d334f214436a19537b2efed61b7639a", + "sha256:598da88dfa127b666852bef6d0d796573a8cf5009ffd62104094a4fe39599565", + "sha256:5d1197e462e0364906cbc19681605cb7c036f2475c899b6f296104ad42b9f5fb", + "sha256:69328e15cfda2c392da4e713443c7dbffa1505bc9d566e71e55abe14c97ddc62", + "sha256:6a9dfa722316f4acf4460afdf5d41d5246a80e249c7ff475c43a3a1e9d75cf62", + "sha256:6b30bcb8cbfccfcf02acb8f1a261143fab622831d9c0989707e0e659f77a18e0", + "sha256:6c076be61cd0177a8433c0adcb03475baf4ee91edf5a4e550161ad57fc90f523", + "sha256:771735dc43cf8383959dc9b90aa281f0b6092321ca98677c5fb6125a6f56d58d", + "sha256:795e34e6cc065f8f498c89b894a3c6da294a936ee71e644e4bd44de048af1405", + "sha256:87afda5539d5140cb8ba9e8b8c8865cb5b1463924d38490d73d3ccfd80896b3f", + "sha256:8fb2aa3ab3728d950bcc885a2e9eff6c8fc40bc0b7bb434e555c215491bcf48b", + "sha256:a1fcb59f2f355ec350073af41d927bf83a63b50e640f4dbaa01053a28b7a7718", + "sha256:a5e7add47a5b5a40c49b3036d464e3c7802f8ae0d1e66035ea16aa5b7a3923ed", + "sha256:a73f489aebd0c2121ed974054cb2759af8a9f747de120acd2c3394cf84176ccb", + "sha256:ab26038b8375581dc832a63c948f261ae0aa21f1d34c1293469f135fa92972a5", + "sha256:b0d191db0f92dfcb1dec210ca244fdae5cbe918c6050b342d619c09d31eea0cc", + "sha256:b749a43aa51e32839c9d71dc67eb1e4221bb04af1033a32e3923d46f9effa942", + "sha256:b7ccf02d7eb340b216ec33e53a3a629856afe1c6e0ef91d84a4e6f2fb2ca70fe", + "sha256:ba5b2e6fe6ca2b7e013398bc7d7b170e21cce322d266ffcd57cca313e54fb246", + "sha256:ba5c4a8552bff16c61882db58544116d021d0b31ee7c66958d14cf386a5b5350", + "sha256:c79e6a11a07da7374f46970410b41d5e266f7f38f6a17a9c4823db80dadf4303", + "sha256:ca48477862372ac3770969b9d75f1bf66131d386dba79506c46d75e6b48c1e09", + "sha256:dea7adcc33d5d105896401a1f37d56b47d443a2b2605ff8a969a0ed5543f7e33", + "sha256:e0a16d274b588767602b7646fa05af2782576a6cf1022f4ba74cbb4db66f6ca8", + "sha256:e4129b528c6baa99a429f97ce733fff478ec955513630e61b49804b6cf9b224a", + "sha256:e5f805d2d5d0a41633651a73fa4ecdd0b3d7a49de4ec3fadf062fe16501ddbf1", + "sha256:ef6c96b2baa2100ec91a4b428f80d8f28a3c9e53568219b6c298c1125572ebc6", + "sha256:fdbdd1d630195689f325c9ef1a12900524dceb503b00a987663ff4f58669b93d" ], - "markers": "python_version >= '3.8'", - "version": "==0.20.0" + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==1.10.12" }, - "setuptools": { + "referencing": { "hashes": [ - "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2", - "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6" + "sha256:3c57da0513e9563eb7e203ebe9bb3a1b509b042016433bd1e45a2853466c3dd3", + "sha256:7e4dc12271d8e15612bfe35792f5ea1c40970dadf8624602e33db2758f7ee554" ], "markers": "python_version >= '3.8'", - "version": "==69.0.2" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + "version": "==0.32.1" + }, + "rpds-py": { + "hashes": [ + "sha256:01f58a7306b64e0a4fe042047dd2b7d411ee82e54240284bab63e325762c1147", + "sha256:0210b2668f24c078307260bf88bdac9d6f1093635df5123789bfee4d8d7fc8e7", + "sha256:02866e060219514940342a1f84303a1ef7a1dad0ac311792fbbe19b521b489d2", + "sha256:0387ce69ba06e43df54e43968090f3626e231e4bc9150e4c3246947567695f68", + "sha256:060f412230d5f19fc8c8b75f315931b408d8ebf56aec33ef4168d1b9e54200b1", + "sha256:071bc28c589b86bc6351a339114fb7a029f5cddbaca34103aa573eba7b482382", + "sha256:0bfb09bf41fe7c51413f563373e5f537eaa653d7adc4830399d4e9bdc199959d", + "sha256:10162fe3f5f47c37ebf6d8ff5a2368508fe22007e3077bf25b9c7d803454d921", + "sha256:149c5cd24f729e3567b56e1795f74577aa3126c14c11e457bec1b1c90d212e38", + "sha256:1701fc54460ae2e5efc1dd6350eafd7a760f516df8dbe51d4a1c79d69472fbd4", + "sha256:1957a2ab607f9added64478a6982742eb29f109d89d065fa44e01691a20fc20a", + "sha256:1a746a6d49665058a5896000e8d9d2f1a6acba8a03b389c1e4c06e11e0b7f40d", + "sha256:1bfcad3109c1e5ba3cbe2f421614e70439f72897515a96c462ea657261b96518", + "sha256:1d36b2b59e8cc6e576f8f7b671e32f2ff43153f0ad6d0201250a7c07f25d570e", + "sha256:1db228102ab9d1ff4c64148c96320d0be7044fa28bd865a9ce628ce98da5973d", + "sha256:1dc29db3900cb1bb40353772417800f29c3d078dbc8024fd64655a04ee3c4bdf", + "sha256:1e626b365293a2142a62b9a614e1f8e331b28f3ca57b9f05ebbf4cf2a0f0bdc5", + "sha256:1f3c3461ebb4c4f1bbc70b15d20b565759f97a5aaf13af811fcefc892e9197ba", + "sha256:20de7b7179e2031a04042e85dc463a93a82bc177eeba5ddd13ff746325558aa6", + "sha256:24e4900a6643f87058a27320f81336d527ccfe503984528edde4bb660c8c8d59", + "sha256:2528ff96d09f12e638695f3a2e0c609c7b84c6df7c5ae9bfeb9252b6fa686253", + "sha256:25f071737dae674ca8937a73d0f43f5a52e92c2d178330b4c0bb6ab05586ffa6", + "sha256:270987bc22e7e5a962b1094953ae901395e8c1e1e83ad016c5cfcfff75a15a3f", + "sha256:292f7344a3301802e7c25c53792fae7d1593cb0e50964e7bcdcc5cf533d634e3", + "sha256:2953937f83820376b5979318840f3ee47477d94c17b940fe31d9458d79ae7eea", + "sha256:2a792b2e1d3038daa83fa474d559acfd6dc1e3650ee93b2662ddc17dbff20ad1", + "sha256:2a7b2f2f56a16a6d62e55354dd329d929560442bd92e87397b7a9586a32e3e76", + "sha256:2f4eb548daf4836e3b2c662033bfbfc551db58d30fd8fe660314f86bf8510b93", + "sha256:3664d126d3388a887db44c2e293f87d500c4184ec43d5d14d2d2babdb4c64cad", + "sha256:3677fcca7fb728c86a78660c7fb1b07b69b281964673f486ae72860e13f512ad", + "sha256:380e0df2e9d5d5d339803cfc6d183a5442ad7ab3c63c2a0982e8c824566c5ccc", + "sha256:3ac732390d529d8469b831949c78085b034bff67f584559340008d0f6041a049", + "sha256:4128980a14ed805e1b91a7ed551250282a8ddf8201a4e9f8f5b7e6225f54170d", + "sha256:4341bd7579611cf50e7b20bb8c2e23512a3dc79de987a1f411cb458ab670eb90", + "sha256:436474f17733c7dca0fbf096d36ae65277e8645039df12a0fa52445ca494729d", + "sha256:4dc889a9d8a34758d0fcc9ac86adb97bab3fb7f0c4d29794357eb147536483fd", + "sha256:4e21b76075c01d65d0f0f34302b5a7457d95721d5e0667aea65e5bb3ab415c25", + "sha256:516fb8c77805159e97a689e2f1c80655c7658f5af601c34ffdb916605598cda2", + "sha256:5576ee2f3a309d2bb403ec292d5958ce03953b0e57a11d224c1f134feaf8c40f", + "sha256:5a024fa96d541fd7edaa0e9d904601c6445e95a729a2900c5aec6555fe921ed6", + "sha256:5d0e8a6434a3fbf77d11448c9c25b2f25244226cfbec1a5159947cac5b8c5fa4", + "sha256:5e7d63ec01fe7c76c2dbb7e972fece45acbb8836e72682bde138e7e039906e2c", + "sha256:60e820ee1004327609b28db8307acc27f5f2e9a0b185b2064c5f23e815f248f8", + "sha256:637b802f3f069a64436d432117a7e58fab414b4e27a7e81049817ae94de45d8d", + "sha256:65dcf105c1943cba45d19207ef51b8bc46d232a381e94dd38719d52d3980015b", + "sha256:698ea95a60c8b16b58be9d854c9f993c639f5c214cf9ba782eca53a8789d6b19", + "sha256:70fcc6c2906cfa5c6a552ba7ae2ce64b6c32f437d8f3f8eea49925b278a61453", + "sha256:720215373a280f78a1814becb1312d4e4d1077b1202a56d2b0815e95ccb99ce9", + "sha256:7450dbd659fed6dd41d1a7d47ed767e893ba402af8ae664c157c255ec6067fde", + "sha256:7b7d9ca34542099b4e185b3c2a2b2eda2e318a7dbde0b0d83357a6d4421b5296", + "sha256:7fbd70cb8b54fe745301921b0816c08b6d917593429dfc437fd024b5ba713c58", + "sha256:81038ff87a4e04c22e1d81f947c6ac46f122e0c80460b9006e6517c4d842a6ec", + "sha256:810685321f4a304b2b55577c915bece4c4a06dfe38f6e62d9cc1d6ca8ee86b99", + "sha256:82ada4a8ed9e82e443fcef87e22a3eed3654dd3adf6e3b3a0deb70f03e86142a", + "sha256:841320e1841bb53fada91c9725e766bb25009cfd4144e92298db296fb6c894fb", + "sha256:8587fd64c2a91c33cdc39d0cebdaf30e79491cc029a37fcd458ba863f8815383", + "sha256:8ffe53e1d8ef2520ebcf0c9fec15bb721da59e8ef283b6ff3079613b1e30513d", + "sha256:9051e3d2af8f55b42061603e29e744724cb5f65b128a491446cc029b3e2ea896", + "sha256:91e5a8200e65aaac342a791272c564dffcf1281abd635d304d6c4e6b495f29dc", + "sha256:93432e747fb07fa567ad9cc7aaadd6e29710e515aabf939dfbed8046041346c6", + "sha256:938eab7323a736533f015e6069a7d53ef2dcc841e4e533b782c2bfb9fb12d84b", + "sha256:9584f8f52010295a4a417221861df9bea4c72d9632562b6e59b3c7b87a1522b7", + "sha256:9737bdaa0ad33d34c0efc718741abaafce62fadae72c8b251df9b0c823c63b22", + "sha256:99da0a4686ada4ed0f778120a0ea8d066de1a0a92ab0d13ae68492a437db78bf", + "sha256:99f567dae93e10be2daaa896e07513dd4bf9c2ecf0576e0533ac36ba3b1d5394", + "sha256:9bdf1303df671179eaf2cb41e8515a07fc78d9d00f111eadbe3e14262f59c3d0", + "sha256:9f0e4dc0f17dcea4ab9d13ac5c666b6b5337042b4d8f27e01b70fae41dd65c57", + "sha256:a000133a90eea274a6f28adc3084643263b1e7c1a5a66eb0a0a7a36aa757ed74", + "sha256:a3264e3e858de4fc601741498215835ff324ff2482fd4e4af61b46512dd7fc83", + "sha256:a71169d505af63bb4d20d23a8fbd4c6ce272e7bce6cc31f617152aa784436f29", + "sha256:a967dd6afda7715d911c25a6ba1517975acd8d1092b2f326718725461a3d33f9", + "sha256:aa5bfb13f1e89151ade0eb812f7b0d7a4d643406caaad65ce1cbabe0a66d695f", + "sha256:ae35e8e6801c5ab071b992cb2da958eee76340e6926ec693b5ff7d6381441745", + "sha256:b686f25377f9c006acbac63f61614416a6317133ab7fafe5de5f7dc8a06d42eb", + "sha256:b760a56e080a826c2e5af09002c1a037382ed21d03134eb6294812dda268c811", + "sha256:b86b21b348f7e5485fae740d845c65a880f5d1eda1e063bc59bef92d1f7d0c55", + "sha256:b9412abdf0ba70faa6e2ee6c0cc62a8defb772e78860cef419865917d86c7342", + "sha256:bd345a13ce06e94c753dab52f8e71e5252aec1e4f8022d24d56decd31e1b9b23", + "sha256:be22ae34d68544df293152b7e50895ba70d2a833ad9566932d750d3625918b82", + "sha256:bf046179d011e6114daf12a534d874958b039342b347348a78b7cdf0dd9d6041", + "sha256:c3d2010656999b63e628a3c694f23020322b4178c450dc478558a2b6ef3cb9bb", + "sha256:c64602e8be701c6cfe42064b71c84ce62ce66ddc6422c15463fd8127db3d8066", + "sha256:d65e6b4f1443048eb7e833c2accb4fa7ee67cc7d54f31b4f0555b474758bee55", + "sha256:d8bbd8e56f3ba25a7d0cf980fc42b34028848a53a0e36c9918550e0280b9d0b6", + "sha256:da1ead63368c04a9bded7904757dfcae01eba0e0f9bc41d3d7f57ebf1c04015a", + "sha256:dbbb95e6fc91ea3102505d111b327004d1c4ce98d56a4a02e82cd451f9f57140", + "sha256:dbc56680ecf585a384fbd93cd42bc82668b77cb525343170a2d86dafaed2a84b", + "sha256:df3b6f45ba4515632c5064e35ca7f31d51d13d1479673185ba8f9fefbbed58b9", + "sha256:dfe07308b311a8293a0d5ef4e61411c5c20f682db6b5e73de6c7c8824272c256", + "sha256:e796051f2070f47230c745d0a77a91088fbee2cc0502e9b796b9c6471983718c", + "sha256:efa767c220d94aa4ac3a6dd3aeb986e9f229eaf5bce92d8b1b3018d06bed3772", + "sha256:f0b8bf5b8db49d8fd40f54772a1dcf262e8be0ad2ab0206b5a2ec109c176c0a4", + "sha256:f175e95a197f6a4059b50757a3dca33b32b61691bdbd22c29e8a8d21d3914cae", + "sha256:f2f3b28b40fddcb6c1f1f6c88c6f3769cd933fa493ceb79da45968a21dccc920", + "sha256:f6c43b6f97209e370124baf2bf40bb1e8edc25311a158867eb1c3a5d449ebc7a", + "sha256:f7f4cb1f173385e8a39c29510dd11a78bf44e360fb75610594973f5ea141028b", + "sha256:fad059a4bd14c45776600d223ec194e77db6c20255578bb5bcdd7c18fd169361", + "sha256:ff1dcb8e8bc2261a088821b2595ef031c91d499a0c1b031c152d43fe0a6ecec8", + "sha256:ffee088ea9b593cc6160518ba9bd319b5475e5f3e578e4552d63818773c6f56a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" + "markers": "python_version >= '3.8'", + "version": "==0.17.1" }, "typing-extensions": { "hashes": [ - "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", - "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "markers": "python_version >= '3.8'", - "version": "==4.8.0" + "version": "==4.9.0" } }, "develop": { @@ -149,11 +220,11 @@ }, "attrs": { "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", + "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" ], "markers": "python_version >= '3.7'", - "version": "==23.1.0" + "version": "==23.2.0" }, "black": { "hashes": [ @@ -306,62 +377,65 @@ "version": "==0.4.4" }, "coverage": { - "hashes": [ - "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", - "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", - "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", - "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", - "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", - "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", - "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", - "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", - "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", - "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", - "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", - "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", - "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", - "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", - "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", - "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", - "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", - "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", - "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", - "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", - "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", - "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", - "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", - "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", - "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", - "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", - "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", - "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", - "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", - "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", - "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", - "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", - "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", - "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", - "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", - "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", - "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", - "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", - "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", - "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", - "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", - "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", - "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", - "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", - "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", - "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", - "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", - "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", - "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", - "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", - "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", - "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" + "extras": [ + "toml" + ], + "hashes": [ + "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca", + "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471", + "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a", + "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058", + "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85", + "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143", + "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446", + "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590", + "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a", + "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105", + "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9", + "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a", + "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac", + "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25", + "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2", + "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450", + "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932", + "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba", + "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137", + "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae", + "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614", + "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70", + "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e", + "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505", + "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870", + "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc", + "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451", + "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7", + "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e", + "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566", + "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5", + "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26", + "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2", + "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42", + "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555", + "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43", + "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed", + "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa", + "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516", + "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952", + "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd", + "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09", + "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c", + "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f", + "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6", + "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1", + "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0", + "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e", + "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9", + "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9", + "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e", + "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06" ], "markers": "python_version >= '3.8'", - "version": "==7.3.2" + "version": "==7.4.0" }, "docutils": { "hashes": [ @@ -371,6 +445,14 @@ "markers": "python_version >= '3.7'", "version": "==0.20.1" }, + "exceptiongroup": { + "hashes": [ + "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", + "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + ], + "markers": "python_version < '3.11'", + "version": "==1.2.0" + }, "execnet": { "hashes": [ "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41", @@ -381,38 +463,39 @@ }, "flake8": { "hashes": [ - "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", - "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" + "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132", + "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.9.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==7.0.0" }, "flake8-annotations": { "hashes": [ - "sha256:0d6cd2e770b5095f09689c9d84cc054c51b929c41a68969ea1beb4b825cac515", - "sha256:d10c4638231f8a50c0a597c4efce42bd7b7d85df4f620a0ddaca526138936a4f" + "sha256:af78e3216ad800d7e144745ece6df706c81b3255290cbf870e54879d495e8ade", + "sha256:ff37375e71e3b83f2a5a04d443c41e2c407de557a884f3300a7fa32f3c41cb0a" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1' and python_full_version < '4.0.0'", - "version": "==2.6.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==3.0.1" }, "flake8-docstrings": { "hashes": [ - "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde", - "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b" + "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af", + "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75" ], "index": "pypi", - "version": "==1.6.0" + "markers": "python_version >= '3.7'", + "version": "==1.7.0" }, "flake8-noqa": { "hashes": [ - "sha256:26d92ca6b72dec732d294e587a2bdeb66dab01acc609ed6a064693d6baa4e789", - "sha256:445618162e0bbae1b9d983326d4e39066c5c6de71ba0c444ca2d4d1fa5b2cdb7" + "sha256:4465e16a19be433980f6f563d05540e2e54797eb11facb9feb50fed60624dc45", + "sha256:771765ab27d1efd157528379acd15131147f9ae578a72d17fb432ca197881243" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.2.9" + "version": "==1.4.0" }, "idna": { "hashes": [ @@ -424,11 +507,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:7fc841f8b8332803464e5dc1c63a2e59121f46ca186c0e2e182e80bf8c1319f7", - "sha256:d97503976bb81f40a193d41ee6570868479c69d5068651eb039c40d850c59d67" + "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e", + "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc" ], "markers": "python_version >= '3.8'", - "version": "==7.0.0" + "version": "==7.0.1" }, "iniconfig": { "hashes": [ @@ -464,10 +547,11 @@ }, "mccabe": { "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "version": "==0.6.1" + "markers": "python_version >= '3.6'", + "version": "==0.7.0" }, "mdurl": { "hashes": [ @@ -479,42 +563,45 @@ }, "more-itertools": { "hashes": [ - "sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a", - "sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6" + "sha256:686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "sha256:8fccb480c43d3e99a00087634c06dd02b0d50fbf088b380de5a41a015ec239e1" ], "markers": "python_version >= '3.8'", - "version": "==10.1.0" + "version": "==10.2.0" }, "mypy": { "hashes": [ - "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", - "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", - "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", - "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", - "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", - "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", - "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", - "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", - "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", - "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", - "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", - "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", - "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", - "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", - "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", - "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", - "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", - "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", - "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", - "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", - "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", - "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", - "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", - "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" + "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6", + "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d", + "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02", + "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d", + "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3", + "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3", + "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3", + "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66", + "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259", + "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835", + "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd", + "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d", + "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8", + "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07", + "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b", + "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e", + "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6", + "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae", + "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9", + "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d", + "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a", + "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592", + "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218", + "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817", + "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4", + "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410", + "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.981" + "markers": "python_version >= '3.8'", + "version": "==1.8.0" }, "mypy-extensions": { "hashes": [ @@ -555,11 +642,11 @@ }, "pathspec": { "hashes": [ - "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", - "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" + "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", + "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" ], - "markers": "python_version >= '3.7'", - "version": "==0.11.2" + "markers": "python_version >= '3.8'", + "version": "==0.12.1" }, "pkginfo": { "hashes": [ @@ -592,21 +679,13 @@ ], "version": "==0.4.0" }, - "py": { - "hashes": [ - "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", - "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.11.0" - }, "pycodestyle": { "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" + "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.7.0" + "markers": "python_version >= '3.8'", + "version": "==2.11.1" }, "pydocstyle": { "hashes": [ @@ -618,11 +697,11 @@ }, "pyflakes": { "hashes": [ - "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", - "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" + "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", + "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.3.1" + "markers": "python_version >= '3.8'", + "version": "==3.2.0" }, "pygments": { "hashes": [ @@ -634,12 +713,12 @@ }, "pytest": { "hashes": [ - "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63", - "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea" + "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", + "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==7.1.1" + "version": "==7.4.4" }, "pytest-clarity": { "hashes": [ @@ -651,29 +730,21 @@ }, "pytest-cov": { "hashes": [ - "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191", - "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e" + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.10.1" - }, - "pytest-forked": { - "hashes": [ - "sha256:4dafd46a9a600f65d822b8f605133ecf5b3e1941ebb3588e943b4e3eb71a5a3f", - "sha256:810958f66a91afb1a1e2ae83089d8dc1cd2437ac96b12963042fbb9fb4d16af0" - ], "markers": "python_version >= '3.7'", - "version": "==1.6.0" + "version": "==4.1.0" }, "pytest-xdist": { "hashes": [ - "sha256:4580deca3ff04ddb2ac53eba39d76cb5dd5edeac050cb6fbc768b0dd712b4edf", - "sha256:6fe5c74fec98906deb8f2d2b616b5c782022744978e7bd4695d39c8f42d0ce65" + "sha256:cbb36f3d67e0c478baa57fa4edc8843887e0f6cfc42d677530a36d7472b32d8a", + "sha256:d075629c7e00b611df89f490a5063944bee7a4362a5ff11c7cc7824a03dfce24" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==2.5.0" + "markers": "python_version >= '3.7'", + "version": "==3.5.0" }, "readme-renderer": { "hashes": [ @@ -727,7 +798,7 @@ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" ], - "markers": "python_version >= '3.7'", + "markers": "python_version < '3.11'", "version": "==2.0.1" }, "twine": { @@ -741,20 +812,20 @@ }, "typeguard": { "hashes": [ - "sha256:00edaa8da3a133674796cf5ea87d9f4b4c367d77476e185e80251cc13dfbb8c4", - "sha256:5e3e3be01e887e7eafae5af63d1f36c849aaa94e3a0112097312aabfa16284f1" + "sha256:8923e55f8873caec136c892c3bed1f676eae7be57cdb94819281b3d3bc9c0953", + "sha256:ea0a113bbc111bcffc90789ebb215625c963411f7096a7e9062d4e4630c155fd" ], "index": "pypi", - "markers": "python_full_version >= '3.5.3'", - "version": "==2.13.3" + "markers": "python_version >= '3.8'", + "version": "==4.1.5" }, "typing-extensions": { "hashes": [ - "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", - "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "markers": "python_version >= '3.8'", - "version": "==4.8.0" + "version": "==4.9.0" }, "urllib3": { "hashes": [ diff --git a/shared-data/python/opentrons_shared_data/labware/labware_definition.py b/shared-data/python/opentrons_shared_data/labware/labware_definition.py index 1b2e68040de..203dba1455d 100644 --- a/shared-data/python/opentrons_shared_data/labware/labware_definition.py +++ b/shared-data/python/opentrons_shared_data/labware/labware_definition.py @@ -160,7 +160,7 @@ class Parameters(BaseModel): loadName: str = Field( ..., description="Name used to reference a labware definition", - regex=SAFE_STRING_REGEX, + pattern=SAFE_STRING_REGEX, ) isMagneticModuleCompatible: bool = Field( ..., @@ -262,7 +262,7 @@ class LabwareDefinition(BaseModel): "(eg myPlate v1/v2/v3). An incrementing integer", ge=1.0, ) - namespace: str = Field(..., regex=SAFE_STRING_REGEX) + namespace: str = Field(..., pattern=SAFE_STRING_REGEX) metadata: Metadata = Field( ..., description="Properties used for search and display" ) diff --git a/shared-data/python/opentrons_shared_data/pipette/__init__.py b/shared-data/python/opentrons_shared_data/pipette/__init__.py index 273be75ea5a..3d3c392b677 100644 --- a/shared-data/python/opentrons_shared_data/pipette/__init__.py +++ b/shared-data/python/opentrons_shared_data/pipette/__init__.py @@ -95,7 +95,7 @@ def _fuse_specs_cached( # unfortunately, mypy can't verify this way to build typed dicts - we'll # make sure it's correct in the tests, and leave the function annotated # properly - return {**model_data, **name_data} # type: ignore + return {**model_data, **name_data} def dummy_model_for_name(pipette_name: PipetteName) -> PipetteModel: diff --git a/shared-data/python/opentrons_shared_data/pipette/pipette_definition.py b/shared-data/python/opentrons_shared_data/pipette/pipette_definition.py index 7374972b800..916eb880475 100644 --- a/shared-data/python/opentrons_shared_data/pipette/pipette_definition.py +++ b/shared-data/python/opentrons_shared_data/pipette/pipette_definition.py @@ -253,7 +253,7 @@ class PartialTipDefinition(BaseModel): description="Whether partial tip pick up is supported.", alias="partialTipSupported", ) - available_configurations: List[int] = Field( + available_configurations: Optional[List[int]] = Field( default=None, description="A list of the types of partial tip configurations supported, listed by channel ints", alias="availableConfigurations", diff --git a/shared-data/python/opentrons_shared_data/pipette/scripts/build_json_script.py b/shared-data/python/opentrons_shared_data/pipette/scripts/build_json_script.py index a7af2e30911..15f28ed3927 100644 --- a/shared-data/python/opentrons_shared_data/pipette/scripts/build_json_script.py +++ b/shared-data/python/opentrons_shared_data/pipette/scripts/build_json_script.py @@ -85,7 +85,8 @@ def _build_drop_tip_data( plungerEject=PlungerEjectDropTipConfiguration( current=current, speed=speed, - ) + ), + camAction=None, ) diff --git a/shared-data/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py b/shared-data/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py index 220214cd1e7..34df66bca48 100644 --- a/shared-data/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py +++ b/shared-data/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py @@ -76,7 +76,7 @@ def list_configuration_keys() -> Tuple[List[str], Dict[int, str]]: def list_available_enum(enum_type: Type[Enum]) -> List[str]: """List available pipette models""" - return [f"{i}: {v}" for (i, v) in enumerate(enum_type)] # type: ignore[var-annotated] + return [f"{i}: {v}" for (i, v) in enumerate(enum_type)] def handle_subclass_model( diff --git a/shared-data/python/setup.py b/shared-data/python/setup.py index 7e9c55e1d1d..8aebebcb408 100644 --- a/shared-data/python/setup.py +++ b/shared-data/python/setup.py @@ -143,9 +143,9 @@ def get_version(): ) PACKAGES = find_packages(where=".", exclude=["tests", "tests.*"]) INSTALL_REQUIRES = [ - "jsonschema==3.0.2", + "jsonschema>=3.0.1,<4.18.0", "typing-extensions>=4.0.0,<5", - "pydantic==1.9.2", + "pydantic>=1.10.9,<2.0.0", ] diff --git a/shared-data/python/tests/deck/test_typechecks.py b/shared-data/python/tests/deck/test_typechecks.py index 249bbf8c909..f021004b050 100644 --- a/shared-data/python/tests/deck/test_typechecks.py +++ b/shared-data/python/tests/deck/test_typechecks.py @@ -1,5 +1,3 @@ -import sys - import pytest import typeguard @@ -10,19 +8,13 @@ from opentrons_shared_data.deck.dev_types import DeckDefinitionV3, DeckDefinitionV4 -pytestmark = pytest.mark.xfail( - condition=sys.version_info >= (3, 10), - reason="https://github.com/agronholm/typeguard/issues/242", -) - - @pytest.mark.parametrize("defname", list_deck_definition_names(version=3)) def test_v3_defs(defname): defn = load_deck_definition(name=defname, version=3) - typeguard.check_type("defn", defn, DeckDefinitionV3) + typeguard.check_type(defn, DeckDefinitionV3) @pytest.mark.parametrize("defname", list_deck_definition_names(version=4)) def test_v4_defs(defname): defn = load_deck_definition(name=defname, version=4) - typeguard.check_type("defn", defn, DeckDefinitionV4) + typeguard.check_type(defn, DeckDefinitionV4) diff --git a/shared-data/python/tests/labware/test_typechecks.py b/shared-data/python/tests/labware/test_typechecks.py index 3d6e9ac4a6f..64f76679cf9 100644 --- a/shared-data/python/tests/labware/test_typechecks.py +++ b/shared-data/python/tests/labware/test_typechecks.py @@ -1,5 +1,3 @@ -import sys - import pytest import typeguard @@ -9,13 +7,7 @@ from . import get_ot_defs -pytestmark = pytest.mark.xfail( - condition=sys.version_info >= (3, 10), - reason="https://github.com/agronholm/typeguard/issues/242", -) - - @pytest.mark.parametrize("loadname,version", get_ot_defs()) def test_opentrons_definition_types(loadname, version): defdict = load_definition(loadname, version) - typeguard.check_type("defdict", defdict, LabwareDefinition) + typeguard.check_type(defdict, LabwareDefinition) diff --git a/shared-data/python/tests/module/test_typechecks.py b/shared-data/python/tests/module/test_typechecks.py index 1b11e29c7f2..9aa5ded743e 100644 --- a/shared-data/python/tests/module/test_typechecks.py +++ b/shared-data/python/tests/module/test_typechecks.py @@ -1,5 +1,3 @@ -import sys - import pytest import typeguard @@ -9,26 +7,20 @@ from . import list_v2_defs, list_v3_defs -pytestmark = pytest.mark.xfail( - condition=sys.version_info >= (3, 10), - reason="https://github.com/agronholm/typeguard/issues/242", -) - - @pytest.mark.parametrize("defname", list_v3_defs()) def test_v3_definitions_match_types(defname: str) -> None: """Test that V3 module definitions match ModuleDefinitionV3.""" def_dict = module.load_definition("3", defname) - typeguard.check_type("def_dict", def_dict, dev_types.ModuleDefinitionV3) + typeguard.check_type(def_dict, dev_types.ModuleDefinitionV3) @pytest.mark.parametrize("defname", list_v2_defs()) def test_v2_definitions_match_types(defname: str) -> None: defdict = module.load_definition("2", defname) # type: ignore [call-overload] - typeguard.check_type("defdict", defdict, dev_types.ModuleDefinitionV2) + typeguard.check_type(defdict, dev_types.ModuleDefinitionV2) @pytest.mark.parametrize("defname", ["magdeck", "tempdeck", "thermocycler"]) def test_v1_definitions_match_types(defname: str) -> None: defdict = module.load_definition("1", defname) - typeguard.check_type("defdict", defdict, dev_types.ModuleDefinitionV1) + typeguard.check_type(defdict, dev_types.ModuleDefinitionV1) diff --git a/shared-data/python/tests/pipette/test_typechecks.py b/shared-data/python/tests/pipette/test_typechecks.py index 7704cc40db8..f4d1ec91af9 100644 --- a/shared-data/python/tests/pipette/test_typechecks.py +++ b/shared-data/python/tests/pipette/test_typechecks.py @@ -1,5 +1,3 @@ -import sys - import pytest import typeguard @@ -15,20 +13,15 @@ PipetteFusedSpec, ) -pytestmark = pytest.mark.xfail( - condition=sys.version_info >= (3, 10), - reason="https://github.com/agronholm/typeguard/issues/242", -) - def test_model_config_check(): defdict = model_config() - typeguard.check_type("defdict", defdict, PipetteModelSpecs) + typeguard.check_type(defdict, PipetteModelSpecs) def test_name_config_check(): defdict = name_config() - typeguard.check_type("defdict", defdict, PipetteNameSpecs) + typeguard.check_type(defdict, PipetteNameSpecs) def build_model_name_pairs(): @@ -41,7 +34,7 @@ def build_model_name_pairs(): @pytest.mark.parametrize("model,name", list(build_model_name_pairs())) def test_fuse(model, name): defdict = fuse_specs(model, name) - typeguard.check_type("defdict", defdict, PipetteFusedSpec) + typeguard.check_type(defdict, PipetteFusedSpec) @pytest.mark.parametrize("name", list(name_config().keys())) diff --git a/shared-data/python/tests/protocol/test_typechecks.py b/shared-data/python/tests/protocol/test_typechecks.py index 02e9541cd67..934944828e2 100644 --- a/shared-data/python/tests/protocol/test_typechecks.py +++ b/shared-data/python/tests/protocol/test_typechecks.py @@ -1,5 +1,4 @@ import json -import sys import pytest import typeguard @@ -12,25 +11,19 @@ from . import list_fixtures -pytestmark = pytest.mark.xfail( - condition=sys.version_info >= (3, 10), - reason="https://github.com/agronholm/typeguard/issues/242", -) - - @pytest.mark.parametrize("defpath", list_fixtures(3)) def test_v3_types(defpath): defn = json.loads(load_shared_data(defpath)) - typeguard.check_type("defn", defn, JsonProtocolV3) + typeguard.check_type(defn, JsonProtocolV3) @pytest.mark.parametrize("defpath", list_fixtures(4)) def test_v4_types(defpath): defn = json.loads(load_shared_data(defpath)) - typeguard.check_type("defn", defn, JsonProtocolV4) + typeguard.check_type(defn, JsonProtocolV4) @pytest.mark.parametrize("defpath", list_fixtures(5)) def test_v5_types(defpath): defn = json.loads(load_shared_data(defpath)) - typeguard.check_type("defn", defn, JsonProtocolV5) + typeguard.check_type(defn, JsonProtocolV5) diff --git a/shared-data/python/tests/robot/test_typechecks.py b/shared-data/python/tests/robot/test_typechecks.py index 15495e344a3..5d838901178 100644 --- a/shared-data/python/tests/robot/test_typechecks.py +++ b/shared-data/python/tests/robot/test_typechecks.py @@ -1,5 +1,3 @@ -import sys - import pytest import typeguard @@ -7,14 +5,9 @@ from opentrons_shared_data.robot import load from opentrons_shared_data.robot.dev_types import RobotDefinition, RobotType -pytestmark = pytest.mark.xfail( - condition=sys.version_info >= (3, 10), - reason="https://github.com/agronholm/typeguard/issues/242", -) - @pytest.mark.parametrize("defname", ["OT-2 Standard", "OT-3 Standard"]) def test_v1_defs(defname: RobotType) -> None: defn = load(robot_type=defname, version=1) - typeguard.check_type("defn", defn, RobotDefinition) + typeguard.check_type(defn, RobotDefinition) assert defn["robotType"] == defname diff --git a/system-server/Pipfile b/system-server/Pipfile index 2c911138d3f..78c13a0ff55 100644 --- a/system-server/Pipfile +++ b/system-server/Pipfile @@ -4,41 +4,44 @@ verify_ssl = true name = "pypi" [packages] -fastapi = "==0.68.1" -uvicorn = "==0.14.0" -anyio = "==3.6.1" +fastapi = "==0.99.1" +uvicorn = "==0.27.0.post1" +anyio = "==3.7.1" typing-extensions = ">=4.0.0,<5" -python-dotenv = "==0.19.0" -python-multipart = "==0.0.5" -pydantic = "==1.9.2" +python-dotenv = "==1.0.1" +python-multipart = "==0.0.6" +pydantic = "==1.10.12" importlib-metadata = ">=4.13.0,<5" +sqlalchemy = "==1.4.51" +pyjwt = "==2.6.0" +systemd-python = { version = "==234", markers="sys_platform == 'linux'" } server-utils = {editable = true, path = "./../server-utils"} system_server = {path = ".", editable = true} [dev-packages] -flake8 = "~=3.9.0" -flake8-annotations = "~=2.6.2" -flake8-docstrings = "~=1.6.0" -flake8-noqa = "~=1.2.1" -pytest = "<7.3.0,>=7.1" -pytest-asyncio = "==0.18" -pytest-cov = "==2.10.1" +flake8 = "==7.0.0" +flake8-annotations = "~=3.0.1" +flake8-docstrings = "~=1.7.0" +flake8-noqa = "~=1.4.0" +pytest = "==7.2.2" +pytest-asyncio = "==0.23.0" +pytest-cov = "==4.1.0" pytest-lazy-fixture = "==0.6.3" pytest-xdist = "~=2.5.0" -tavern = "~=1.6" -coverage = "==6.3" +tavern = "~=2.9.1" +coverage = "==7.4.0" # atomicwrites and colorama are pytest dependencies on windows, # spec'd here to force lockfile inclusion # https://github.com/pypa/pipenv/issues/4408#issuecomment-668324177 atomicwrites = { version = "==1.4.0", markers="sys_platform=='win32'" } colorama = { version = "==0.4.4", markers="sys_platform=='win32'" } sqlalchemy2-stubs = "==0.0.2a21" -mypy = "==0.981" +mypy = "==1.8.0" black = "==22.3.0" -decoy = "~=1.10" -mock = "~=4.0.3" -types-mock = "==4.0.1" -types-requests = "==2.25.6" +decoy = "==2.1.1" +mock = "~=5.1.0" +types-mock = "==5.1.0" +types-requests = "==2.27.1" requests = "==2.27.1" [requires] diff --git a/system-server/Pipfile.lock b/system-server/Pipfile.lock index 493dd5be346..bbaa48e640c 100644 --- a/system-server/Pipfile.lock +++ b/system-server/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2785838ab3d5199201cc286ff042bbcf191c1a642d0ba0f4f5a980c5f04e710e" + "sha256": "a0353342ca006092f2014adfa5aab4abaa720a1ddc89c0dfe34d77b72ed525b1" }, "pipfile-spec": 6, "requires": { @@ -16,30 +16,14 @@ ] }, "default": { - "aiosqlite": { - "hashes": [ - "sha256:6c49dc6d3405929b1d08eeccc72306d3677503cc5e5e43771efc1e00232e8231", - "sha256:f0e6acc24bc4864149267ac82fb46dfb3be4455f99fe21df82609cc6e6baee51" - ], - "markers": "python_version >= '3.6'", - "version": "==0.17.0" - }, "anyio": { "hashes": [ - "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b", - "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be" + "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780", + "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5" ], "index": "pypi", - "markers": "python_full_version >= '3.6.2'", - "version": "==3.6.1" - }, - "asgiref": { - "hashes": [ - "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e", - "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed" - ], "markers": "python_version >= '3.7'", - "version": "==3.7.2" + "version": "==3.7.1" }, "click": { "hashes": [ @@ -49,78 +33,22 @@ "markers": "python_version >= '3.7'", "version": "==8.1.7" }, + "exceptiongroup": { + "hashes": [ + "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", + "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + ], + "markers": "python_version < '3.11'", + "version": "==1.2.0" + }, "fastapi": { "hashes": [ - "sha256:644bb815bae326575c4b2842469fb83053a4b974b82fa792ff9283d17fbbd99d", - "sha256:94d2820906c36b9b8303796fb7271337ec89c74223229e3cfcf056b5a7d59e23" + "sha256:976df7bab51ac7beda9f68c4513b8c4490b5c1135c72aafd0a5ee4023ec5282e", + "sha256:ac78f717cd80d657bd183f94d33b9bda84aa376a46a9dab513586b8eef1dc6fc" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==0.68.1" - }, - "greenlet": { - "hashes": [ - "sha256:006c1028ac0cfcc4e772980cfe73f5476041c8c91d15d64f52482fc571149d46", - "sha256:0acadbc3f72cb0ee85070e8d36bd2a4673d2abd10731ee73c10222cf2dd4713c", - "sha256:0c0fdb8142742ee68e97c106eb81e7d3e883cc739d9c5f2b28bc38a7bafeb6d1", - "sha256:0df7eed98ea23b20e9db64d46eb05671ba33147df9405330695bcd81a73bb0c9", - "sha256:10d247260db20887ae8857c0cbc750b9170f0b067dd7d38fb68a3f2334393bd3", - "sha256:14b5d999aefe9ffd2049ad19079f733c3aaa426190ffecadb1d5feacef8fe397", - "sha256:18fe39d70d482b22f0014e84947c5aaa7211fb8e13dc4cc1c43ed2aa1db06d9a", - "sha256:1c1129bc47266d83444c85a8e990ae22688cf05fb20d7951fd2866007c2ba9bc", - "sha256:1dac09e3c0b78265d2e6d3cbac2d7c48bd1aa4b04a8ffeda3adde9f1688df2c3", - "sha256:2c93cd03acb1499ee4de675e1a4ed8eaaa7227f7949dc55b37182047b006a7aa", - "sha256:2e9c5423046eec21f6651268cb674dfba97280701e04ef23d312776377313206", - "sha256:2ee59c4627c8c4bb3e15949fbcd499abd6b7f4ad9e0bfcb62c65c5e2cabe0ec4", - "sha256:339c0272a62fac7e602e4e6ec32a64ff9abadc638b72f17f6713556ed011d493", - "sha256:38878744926cec29b5cc3654ef47f3003f14bfbba7230e3c8492393fe29cc28b", - "sha256:3e4bfa752b3688d74ab1186e2159779ff4867644d2b1ebf16db14281f0445377", - "sha256:520fcb53a39ef90f5021c77606952dbbc1da75d77114d69b8d7bded4a8e1a813", - "sha256:5f9ea7c2c9795549653b6f7569f6bc75d2c7d1f6b2854eb8ce0bc6ec3cb2dd88", - "sha256:654b84c9527182036747938b81938f1d03fb8321377510bc1854a9370418ab66", - "sha256:6d65bec56a7bc352bcf11b275b838df618651109074d455a772d3afe25390b7d", - "sha256:7363756cc439a503505b67983237d1cc19139b66488263eb19f5719a32597836", - "sha256:80d068e4b6e2499847d916ef64176811ead6bf210a610859220d537d935ec6fd", - "sha256:8756a94ed8f293450b0e91119eca2a36332deba69feb2f9ca410d35e74eae1e4", - "sha256:89a6f6ddcbef4000cda7e205c4c20d319488ff03db961d72d4e73519d2465309", - "sha256:8f34a765c5170c0673eb747213a0275ecc749ab3652bdbec324621ed5b2edaef", - "sha256:8f8d14a0a4e8c670fbce633d8b9a1ee175673a695475acd838e372966845f764", - "sha256:950e21562818f9c771989b5b65f990e76f4ac27af66e1bb34634ae67886ede2a", - "sha256:9560c580c896030ff9c311c603aaf2282234643c90d1dec738a1d93e3e53cd51", - "sha256:9acd8fd67c248b8537953cb3af8787c18a87c33d4dcf6830e410ee1f95a63fd4", - "sha256:a37ae53cca36823597fd5f65341b6f7bac2dd69ecd6ca01334bb795460ab150b", - "sha256:aecea0442975741e7d69daff9b13c83caff8c13eeb17485afa65f6360a045765", - "sha256:b1405614692ac986490d10d3e1a05e9734f473750d4bee3cf7d1286ef7af7da6", - "sha256:b1fd25dfc5879a82103b3d9e43fa952e3026c221996ff4d32a9c72052544835d", - "sha256:b2cedf279ca38ef3f4ed0d013a6a84a7fc3d9495a716b84a5fc5ff448965f251", - "sha256:b3f0497db77cfd034f829678b28267eeeeaf2fc21b3f5041600f7617139e6773", - "sha256:bfcecc984d60b20ffe30173b03bfe9ba6cb671b0be1e95c3e2056d4fe7006590", - "sha256:c1f647fe5b94b51488b314c82fdda10a8756d650cee8d3cd29f657c6031bdf73", - "sha256:c235131bf59d2546bb3ebaa8d436126267392f2e51b85ff45ac60f3a26549af0", - "sha256:c27b142a9080bdd5869a2fa7ebf407b3c0b24bd812db925de90e9afe3c417fd6", - "sha256:c42bb589e6e9f9d8bdd79f02f044dff020d30c1afa6e84c0b56d1ce8a324553c", - "sha256:cd5bc4fde0842ff2b9cf33382ad0b4db91c2582db836793d58d174c569637144", - "sha256:cecfdc950dd25f25d6582952e58521bca749cf3eeb7a9bad69237024308c8196", - "sha256:d1fceb5351ab1601903e714c3028b37f6ea722be6873f46e349a960156c05650", - "sha256:d4d0df07a38e41a10dfb62c6fc75ede196572b580f48ee49b9282c65639f3965", - "sha256:d5547b462b8099b84746461e882a3eb8a6e3f80be46cb6afb8524eeb191d1a30", - "sha256:d64643317e76b4b41fdba659e7eca29634e5739b8bc394eda3a9127f697ed4b0", - "sha256:db4233358d3438369051a2f290f1311a360d25c49f255a6c5d10b5bcb3aa2b49", - "sha256:e0e28f5233d64c693382f66d47c362b72089ebf8ac77df7e12ac705c9fa1163d", - "sha256:e79fb5a9fb2d0bd3b6573784f5e5adabc0b0566ad3180a028af99523ce8f6138", - "sha256:e84bef3cfb6b6bfe258c98c519811c240dbc5b33a523a14933a252e486797c90", - "sha256:ed1a8a08de7f68506a38f9a2ddb26bbd1480689e66d788fcd4b5f77e2d9ecfcc", - "sha256:ed9bf77b41798e8417657245b9f3649314218a4a17aefb02bb3992862df32495", - "sha256:edf7a1daba1f7c54326291a8cde58da86ab115b78c91d502be8744f0aa8e3ffa", - "sha256:f260e6c2337871a52161824058923df2bbddb38bc11a5cbe71f3474d877c5bd9", - "sha256:f27aa32466993c92d326df982c4acccd9530fe354e938d9e9deada563e71ce76", - "sha256:f4cf532bf3c58a862196b06947b1b5cc55503884f9b63bf18582a75228d9950e", - "sha256:fb5d60805057d8948065338be6320d35e26b0a72f45db392eb32b70dd6dc9227", - "sha256:fc14dd9554f88c9c1fe04771589ae24db76cd56c8f1104e4381b383d6b71aff8", - "sha256:fefd5eb2c0b1adffdf2802ff7df45bfe65988b15f6b972706a0e55d451bffaea" - ], - "markers": "python_version >= '3' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))", - "version": "==3.0.2" + "markers": "python_version >= '3.7'", + "version": "==0.99.1" }, "h11": { "hashes": [ @@ -149,82 +77,78 @@ }, "pydantic": { "hashes": [ - "sha256:1061c6ee6204f4f5a27133126854948e3b3d51fcc16ead2e5d04378c199b2f44", - "sha256:19b5686387ea0d1ea52ecc4cffb71abb21702c5e5b2ac626fd4dbaa0834aa49d", - "sha256:2bd446bdb7755c3a94e56d7bdfd3ee92396070efa8ef3a34fab9579fe6aa1d84", - "sha256:328558c9f2eed77bd8fffad3cef39dbbe3edc7044517f4625a769d45d4cf7555", - "sha256:32e0b4fb13ad4db4058a7c3c80e2569adbd810c25e6ca3bbd8b2a9cc2cc871d7", - "sha256:3ee0d69b2a5b341fc7927e92cae7ddcfd95e624dfc4870b32a85568bd65e6131", - "sha256:4aafd4e55e8ad5bd1b19572ea2df546ccace7945853832bb99422a79c70ce9b8", - "sha256:4b3946f87e5cef3ba2e7bd3a4eb5a20385fe36521d6cc1ebf3c08a6697c6cfb3", - "sha256:4de71c718c9756d679420c69f216776c2e977459f77e8f679a4a961dc7304a56", - "sha256:5565a49effe38d51882cb7bac18bda013cdb34d80ac336428e8908f0b72499b0", - "sha256:5803ad846cdd1ed0d97eb00292b870c29c1f03732a010e66908ff48a762f20e4", - "sha256:5da164119602212a3fe7e3bc08911a89db4710ae51444b4224c2382fd09ad453", - "sha256:615661bfc37e82ac677543704437ff737418e4ea04bef9cf11c6d27346606044", - "sha256:78a4d6bdfd116a559aeec9a4cfe77dda62acc6233f8b56a716edad2651023e5e", - "sha256:7d0f183b305629765910eaad707800d2f47c6ac5bcfb8c6397abdc30b69eeb15", - "sha256:7ead3cd020d526f75b4188e0a8d71c0dbbe1b4b6b5dc0ea775a93aca16256aeb", - "sha256:84d76ecc908d917f4684b354a39fd885d69dd0491be175f3465fe4b59811c001", - "sha256:8cb0bc509bfb71305d7a59d00163d5f9fc4530f0881ea32c74ff4f74c85f3d3d", - "sha256:91089b2e281713f3893cd01d8e576771cd5bfdfbff5d0ed95969f47ef6d676c3", - "sha256:9c9e04a6cdb7a363d7cb3ccf0efea51e0abb48e180c0d31dca8d247967d85c6e", - "sha256:a8c5360a0297a713b4123608a7909e6869e1b56d0e96eb0d792c27585d40757f", - "sha256:afacf6d2a41ed91fc631bade88b1d319c51ab5418870802cedb590b709c5ae3c", - "sha256:b34ba24f3e2d0b39b43f0ca62008f7ba962cff51efa56e64ee25c4af6eed987b", - "sha256:bd67cb2c2d9602ad159389c29e4ca964b86fa2f35c2faef54c3eb28b4efd36c8", - "sha256:c0f5e142ef8217019e3eef6ae1b6b55f09a7a15972958d44fbd228214cede567", - "sha256:cdb4272678db803ddf94caa4f94f8672e9a46bae4a44f167095e4d06fec12979", - "sha256:d70916235d478404a3fa8c997b003b5f33aeac4686ac1baa767234a0f8ac2326", - "sha256:d8ce3fb0841763a89322ea0432f1f59a2d3feae07a63ea2c958b2315e1ae8adb", - "sha256:e0b214e57623a535936005797567231a12d0da0c29711eb3514bc2b3cd008d0f", - "sha256:e631c70c9280e3129f071635b81207cad85e6c08e253539467e4ead0e5b219aa", - "sha256:e78578f0c7481c850d1c969aca9a65405887003484d24f6110458fb02cca7747", - "sha256:f0ca86b525264daa5f6b192f216a0d1e860b7383e3da1c65a1908f9c02f42801", - "sha256:f1a68f4f65a9ee64b6ccccb5bf7e17db07caebd2730109cb8a95863cfa9c4e55", - "sha256:fafe841be1103f340a24977f61dee76172e4ae5f647ab9e7fd1e1fca51524f08", - "sha256:ff68fc85355532ea77559ede81f35fff79a6a5543477e168ab3a381887caea76" + "sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303", + "sha256:1289c180abd4bd4555bb927c42ee42abc3aee02b0fb2d1223fb7c6e5bef87dbe", + "sha256:1eb2085c13bce1612da8537b2d90f549c8cbb05c67e8f22854e201bde5d98a47", + "sha256:2031de0967c279df0d8a1c72b4ffc411ecd06bac607a212892757db7462fc494", + "sha256:2a7bac939fa326db1ab741c9d7f44c565a1d1e80908b3797f7f81a4f86bc8d33", + "sha256:2d5a58feb9a39f481eda4d5ca220aa8b9d4f21a41274760b9bc66bfd72595b86", + "sha256:2f9a6fab5f82ada41d56b0602606a5506aab165ca54e52bc4545028382ef1c5d", + "sha256:2fcfb5296d7877af406ba1547dfde9943b1256d8928732267e2653c26938cd9c", + "sha256:549a8e3d81df0a85226963611950b12d2d334f214436a19537b2efed61b7639a", + "sha256:598da88dfa127b666852bef6d0d796573a8cf5009ffd62104094a4fe39599565", + "sha256:5d1197e462e0364906cbc19681605cb7c036f2475c899b6f296104ad42b9f5fb", + "sha256:69328e15cfda2c392da4e713443c7dbffa1505bc9d566e71e55abe14c97ddc62", + "sha256:6a9dfa722316f4acf4460afdf5d41d5246a80e249c7ff475c43a3a1e9d75cf62", + "sha256:6b30bcb8cbfccfcf02acb8f1a261143fab622831d9c0989707e0e659f77a18e0", + "sha256:6c076be61cd0177a8433c0adcb03475baf4ee91edf5a4e550161ad57fc90f523", + "sha256:771735dc43cf8383959dc9b90aa281f0b6092321ca98677c5fb6125a6f56d58d", + "sha256:795e34e6cc065f8f498c89b894a3c6da294a936ee71e644e4bd44de048af1405", + "sha256:87afda5539d5140cb8ba9e8b8c8865cb5b1463924d38490d73d3ccfd80896b3f", + "sha256:8fb2aa3ab3728d950bcc885a2e9eff6c8fc40bc0b7bb434e555c215491bcf48b", + "sha256:a1fcb59f2f355ec350073af41d927bf83a63b50e640f4dbaa01053a28b7a7718", + "sha256:a5e7add47a5b5a40c49b3036d464e3c7802f8ae0d1e66035ea16aa5b7a3923ed", + "sha256:a73f489aebd0c2121ed974054cb2759af8a9f747de120acd2c3394cf84176ccb", + "sha256:ab26038b8375581dc832a63c948f261ae0aa21f1d34c1293469f135fa92972a5", + "sha256:b0d191db0f92dfcb1dec210ca244fdae5cbe918c6050b342d619c09d31eea0cc", + "sha256:b749a43aa51e32839c9d71dc67eb1e4221bb04af1033a32e3923d46f9effa942", + "sha256:b7ccf02d7eb340b216ec33e53a3a629856afe1c6e0ef91d84a4e6f2fb2ca70fe", + "sha256:ba5b2e6fe6ca2b7e013398bc7d7b170e21cce322d266ffcd57cca313e54fb246", + "sha256:ba5c4a8552bff16c61882db58544116d021d0b31ee7c66958d14cf386a5b5350", + "sha256:c79e6a11a07da7374f46970410b41d5e266f7f38f6a17a9c4823db80dadf4303", + "sha256:ca48477862372ac3770969b9d75f1bf66131d386dba79506c46d75e6b48c1e09", + "sha256:dea7adcc33d5d105896401a1f37d56b47d443a2b2605ff8a969a0ed5543f7e33", + "sha256:e0a16d274b588767602b7646fa05af2782576a6cf1022f4ba74cbb4db66f6ca8", + "sha256:e4129b528c6baa99a429f97ce733fff478ec955513630e61b49804b6cf9b224a", + "sha256:e5f805d2d5d0a41633651a73fa4ecdd0b3d7a49de4ec3fadf062fe16501ddbf1", + "sha256:ef6c96b2baa2100ec91a4b428f80d8f28a3c9e53568219b6c298c1125572ebc6", + "sha256:fdbdd1d630195689f325c9ef1a12900524dceb503b00a987663ff4f58669b93d" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1'", - "version": "==1.9.2" + "markers": "python_version >= '3.7'", + "version": "==1.10.12" }, "pyjwt": { "hashes": [ "sha256:69285c7e31fc44f68a1feb309e948e0df53259d579295e6cfe2b1792329f05fd", "sha256:d83c3d892a77bbb74d3e1a2cfa90afaadb60945205d1095d9221f04466f64c14" ], + "index": "pypi", "markers": "python_version >= '3.7'", "version": "==2.6.0" }, "python-dotenv": { "hashes": [ - "sha256:aae25dc1ebe97c420f50b81fb0e5c949659af713f31fdb63c749ca68748f34b1", - "sha256:f521bc2ac9a8e03c736f62911605c5d83970021e3fa95b37d769e2bbbe9b6172" + "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", + "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a" ], "index": "pypi", - "markers": "python_version >= '3.5'", - "version": "==0.19.0" + "markers": "python_version >= '3.8'", + "version": "==1.0.1" }, "python-multipart": { "hashes": [ - "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43" + "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132", + "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18" ], "index": "pypi", - "version": "==0.0.5" + "markers": "python_version >= '3.7'", + "version": "==0.0.6" }, "server-utils": { "editable": true, "path": "./../server-utils" }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, "sniffio": { "hashes": [ "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", @@ -235,52 +159,64 @@ }, "sqlalchemy": { "hashes": [ - "sha256:04164e0063feb7aedd9d073db0fd496edb244be40d46ea1f0d8990815e4b8c34", - "sha256:159c2f69dd6efd28e894f261ffca1100690f28210f34cfcd70b895e0ea7a64f3", - "sha256:199dc6d0068753b6a8c0bd3aceb86a3e782df118260ebc1fa981ea31ee054674", - "sha256:1bbac3e8293b34c4403d297e21e8f10d2a57756b75cff101dc62186adec725f5", - "sha256:20e9eba7fd86ef52e0df25bea83b8b518dfdf0bce09b336cfe51671f52aaaa3f", - "sha256:290cbdf19129ae520d4bdce392648c6fcdbee763bc8f750b53a5ab51880cb9c9", - "sha256:316270e5867566376e69a0ac738b863d41396e2b63274616817e1d34156dff0e", - "sha256:3f88a4ee192142eeed3fe173f673ea6ab1f5a863810a9d85dbf6c67a9bd08f97", - "sha256:4aa96e957141006181ca58e792e900ee511085b8dae06c2d08c00f108280fb8a", - "sha256:4b2bcab3a914715d332ca783e9bda13bc570d8b9ef087563210ba63082c18c16", - "sha256:576684771456d02e24078047c2567025f2011977aa342063468577d94e194b00", - "sha256:5a2e73508f939175363d8a4be9dcdc84cf16a92578d7fa86e6e4ca0e6b3667b2", - "sha256:5ba59761c19b800bc2e1c9324da04d35ef51e4ee9621ff37534bc2290d258f71", - "sha256:5dc9801ae9884e822ba942ca493642fb50f049c06b6dbe3178691fce48ceb089", - "sha256:6fdd2dc5931daab778c2b65b03df6ae68376e028a3098eb624d0909d999885bc", - "sha256:708973b5d9e1e441188124aaf13c121e5b03b6054c2df59b32219175a25aa13e", - "sha256:7ff72b3cc9242d1a1c9b84bd945907bf174d74fc2519efe6184d6390a8df478b", - "sha256:8679f9aba5ac22e7bce54ccd8a77641d3aea3e2d96e73e4356c887ebf8ff1082", - "sha256:8b9a395122770a6f08ebfd0321546d7379f43505882c7419d7886856a07caa13", - "sha256:8e1e5d96b744a4f91163290b01045430f3f32579e46d87282449e5b14d27d4ac", - "sha256:9a0195af6b9050c9322a97cf07514f66fe511968e623ca87b2df5e3cf6349615", - "sha256:9cb5698c896fa72f88e7ef04ef62572faf56809093180771d9be8d9f2e264a13", - "sha256:b3f1d9b3aa09ab9adc7f8c4b40fc3e081eb903054c9a6f9ae1633fe15ae503b4", - "sha256:bb42f9b259c33662c6a9b866012f6908a91731a419e69304e1261ba3ab87b8d1", - "sha256:bca714d831e5b8860c3ab134c93aec63d1a4f493bed20084f54e3ce9f0a3bf99", - "sha256:bedd89c34ab62565d44745212814e4b57ef1c24ad4af9b29c504ce40f0dc6558", - "sha256:bfec934aac7f9fa95fc82147a4ba5db0a8bdc4ebf1e33b585ab8860beb10232f", - "sha256:c7046f7aa2db445daccc8424f50b47a66c4039c9f058246b43796aa818f8b751", - "sha256:d7e483f4791fbda60e23926b098702340504f7684ce7e1fd2c1bf02029288423", - "sha256:dd93162615870c976dba43963a24bb418b28448fef584f30755990c134a06a55", - "sha256:e4607d2d16330757818c9d6fba322c2e80b4b112ff24295d1343a80b876eb0ed", - "sha256:e9a680d9665f88346ed339888781f5236347933906c5a56348abb8261282ec48", - "sha256:edfcf93fd92e2f9eef640b3a7a40db20fe3c1d7c2c74faa41424c63dead61b76", - "sha256:f7e4a3c0c3c596296b37f8427c467c8e4336dc8d50f8ed38042e8ba79507b2c9", - "sha256:fff677fa4522dafb5a5e2c0cf909790d5d367326321aeabc0dffc9047cb235bd" + "sha256:0525c4905b4b52d8ccc3c203c9d7ab2a80329ffa077d4bacf31aefda7604dc65", + "sha256:0535d5b57d014d06ceeaeffd816bb3a6e2dddeb670222570b8c4953e2d2ea678", + "sha256:0892e7ac8bc76da499ad3ee8de8da4d7905a3110b952e2a35a940dab1ffa550e", + "sha256:0d661cff58c91726c601cc0ee626bf167b20cc4d7941c93c5f3ac28dc34ddbea", + "sha256:1980e6eb6c9be49ea8f89889989127daafc43f0b1b6843d71efab1514973cca0", + "sha256:1a09d5bd1a40d76ad90e5570530e082ddc000e1d92de495746f6257dc08f166b", + "sha256:245c67c88e63f1523e9216cad6ba3107dea2d3ee19adc359597a628afcabfbcb", + "sha256:2ad16880ccd971ac8e570550fbdef1385e094b022d6fc85ef3ce7df400dddad3", + "sha256:2be4e6294c53f2ec8ea36486b56390e3bcaa052bf3a9a47005687ccf376745d1", + "sha256:2c55040d8ea65414de7c47f1a23823cd9f3fad0dc93e6b6b728fee81230f817b", + "sha256:352df882088a55293f621328ec33b6ffca936ad7f23013b22520542e1ab6ad1b", + "sha256:3823dda635988e6744d4417e13f2e2b5fe76c4bf29dd67e95f98717e1b094cad", + "sha256:38ef80328e3fee2be0a1abe3fe9445d3a2e52a1282ba342d0dab6edf1fef4707", + "sha256:39b02b645632c5fe46b8dd30755682f629ffbb62ff317ecc14c998c21b2896ff", + "sha256:3b0cd89a7bd03f57ae58263d0f828a072d1b440c8c2949f38f3b446148321171", + "sha256:3ec7a0ed9b32afdf337172678a4a0e6419775ba4e649b66f49415615fa47efbd", + "sha256:3f0ef620ecbab46e81035cf3dedfb412a7da35340500ba470f9ce43a1e6c423b", + "sha256:50e074aea505f4427151c286955ea025f51752fa42f9939749336672e0674c81", + "sha256:55e699466106d09f028ab78d3c2e1f621b5ef2c8694598242259e4515715da7c", + "sha256:5e180fff133d21a800c4f050733d59340f40d42364fcb9d14f6a67764bdc48d2", + "sha256:6cacc0b2dd7d22a918a9642fc89840a5d3cee18a0e1fe41080b1141b23b10916", + "sha256:7af40425ac535cbda129d9915edcaa002afe35d84609fd3b9d6a8c46732e02ee", + "sha256:7d8139ca0b9f93890ab899da678816518af74312bb8cd71fb721436a93a93298", + "sha256:7deeae5071930abb3669b5185abb6c33ddfd2398f87660fafdb9e6a5fb0f3f2f", + "sha256:86a22143a4001f53bf58027b044da1fb10d67b62a785fc1390b5c7f089d9838c", + "sha256:8ca484ca11c65e05639ffe80f20d45e6be81fbec7683d6c9a15cd421e6e8b340", + "sha256:8d1d7d63e5d2f4e92a39ae1e897a5d551720179bb8d1254883e7113d3826d43c", + "sha256:8e702e7489f39375601c7ea5a0bef207256828a2bc5986c65cb15cd0cf097a87", + "sha256:a055ba17f4675aadcda3005df2e28a86feb731fdcc865e1f6b4f209ed1225cba", + "sha256:a33cb3f095e7d776ec76e79d92d83117438b6153510770fcd57b9c96f9ef623d", + "sha256:a61184c7289146c8cff06b6b41807c6994c6d437278e72cf00ff7fe1c7a263d1", + "sha256:af55cc207865d641a57f7044e98b08b09220da3d1b13a46f26487cc2f898a072", + "sha256:b00cf0471888823b7a9f722c6c41eb6985cf34f077edcf62695ac4bed6ec01ee", + "sha256:b03850c290c765b87102959ea53299dc9addf76ca08a06ea98383348ae205c99", + "sha256:b97fd5bb6b7c1a64b7ac0632f7ce389b8ab362e7bd5f60654c2a418496be5d7f", + "sha256:c37bc677690fd33932182b85d37433845de612962ed080c3e4d92f758d1bd894", + "sha256:cecb66492440ae8592797dd705a0cbaa6abe0555f4fa6c5f40b078bd2740fc6b", + "sha256:d0a83afab5e062abffcdcbcc74f9d3ba37b2385294dd0927ad65fc6ebe04e054", + "sha256:d3cf56cc36d42908495760b223ca9c2c0f9f0002b4eddc994b24db5fcb86a9e4", + "sha256:e646b19f47d655261b22df9976e572f588185279970efba3d45c377127d35349", + "sha256:e7908c2025eb18394e32d65dd02d2e37e17d733cdbe7d78231c2b6d7eb20cdb9", + "sha256:e8f2df79a46e130235bc5e1bbef4de0583fb19d481eaa0bffa76e8347ea45ec6", + "sha256:eaeeb2464019765bc4340214fca1143081d49972864773f3f1e95dba5c7edc7d", + "sha256:eb18549b770351b54e1ab5da37d22bc530b8bfe2ee31e22b9ebe650640d2ef12", + "sha256:f2e5b6f5cf7c18df66d082604a1d9c7a2d18f7d1dbe9514a2afaccbb51cc4fc3", + "sha256:f8cafa6f885a0ff5e39efa9325195217bb47d5929ab0051636610d24aef45ade" ], + "index": "pypi", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.4.32" + "version": "==1.4.51" }, "starlette": { "hashes": [ - "sha256:3c8e48e52736b3161e34c9f0e8153b4f32ec5d8995a3ee1d59410d92f75162ed", - "sha256:7d49f4a27f8742262ef1470608c59ddbc66baf37c148e938c7038e6bc7a998aa" + "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75", + "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91" ], - "markers": "python_version >= '3.6'", - "version": "==0.14.2" + "markers": "python_version >= '3.7'", + "version": "==0.27.0" }, "system-server": { "editable": true, @@ -290,6 +226,7 @@ "hashes": [ "sha256:fd0e44bf70eadae45aadc292cb0a7eb5b0b6372cd1b391228047d33895db83e7" ], + "markers": "sys_platform == 'linux'", "version": "==234" }, "typing-extensions": { @@ -303,19 +240,20 @@ }, "uvicorn": { "hashes": [ - "sha256:2a76bb359171a504b3d1c853409af3adbfa5cef374a4a59e5881945a97a93eae", - "sha256:45ad7dfaaa7d55cab4cd1e85e03f27e9d60bc067ddc59db52a2b0aeca8870292" + "sha256:4b85ba02b8a20429b9b205d015cbeb788a12da527f731811b643fd739ef90d5f", + "sha256:54898fcd80c13ff1cd28bf77b04ec9dbd8ff60c5259b499b4b12bb0917f22907" ], "index": "pypi", - "version": "==0.14.0" + "markers": "python_version >= '3.8'", + "version": "==0.27.0.post1" }, "wsproto": { "hashes": [ - "sha256:868776f8456997ad0d9720f7322b746bbe9193751b5b290b7f924659377c8c38", - "sha256:d8345d1808dd599b5ffb352c25a367adb6157e664e140dbecba3f9bc007edb9f" + "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", + "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736" ], - "markers": "python_full_version >= '3.6.1'", - "version": "==1.0.0" + "markers": "python_full_version >= '3.7.0'", + "version": "==1.2.0" }, "zipp": { "hashes": [ @@ -337,11 +275,11 @@ }, "attrs": { "hashes": [ - "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", - "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" + "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", + "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.4.0" + "markers": "python_version >= '3.7'", + "version": "==23.2.0" }, "black": { "hashes": [ @@ -375,11 +313,11 @@ }, "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "version": "==2024.2.2" }, "charset-normalizer": { "hashes": [ @@ -406,61 +344,75 @@ "version": "==0.4.4" }, "coverage": { - "hashes": [ - "sha256:012157499ec4f135fc36cd2177e3d1a1840af9b236cbe80e9a5ccfc83d912a69", - "sha256:0a34d313105cdd0d3644c56df2d743fe467270d6ab93b5d4a347eb9fec8924d6", - "sha256:11e61c5548ecf74ea1f8b059730b049871f0e32b74f88bd0d670c20c819ad749", - "sha256:152cc2624381df4e4e604e21bd8e95eb8059535f7b768c1fb8b8ae0b26f47ab0", - "sha256:1b4285fde5286b946835a1a53bba3ad41ef74285ba9e8013e14b5ea93deaeafc", - "sha256:27a94db5dc098c25048b0aca155f5fac674f2cf1b1736c5272ba28ead2fc267e", - "sha256:27ac7cb84538e278e07569ceaaa6f807a029dc194b1c819a9820b9bb5dbf63ab", - "sha256:2a491e159294d756e7fc8462f98175e2d2225e4dbe062cca7d3e0d5a75ba6260", - "sha256:2bc85664b06ba42d14bb74d6ddf19d8bfc520cb660561d2d9ce5786ae72f71b5", - "sha256:32168001f33025fd756884d56d01adebb34e6c8c0b3395ca8584cdcee9c7c9d2", - "sha256:3c4ce3b647bd1792d4394f5690d9df6dc035b00bcdbc5595099c01282a59ae01", - "sha256:433b99f7b0613bdcdc0b00cc3d39ed6d756797e3b078d2c43f8a38288520aec6", - "sha256:4578728c36de2801c1deb1c6b760d31883e62e33f33c7ba8f982e609dc95167d", - "sha256:51372e24b1f7143ee2df6b45cff6a721f3abe93b1e506196f3ffa4155c2497f7", - "sha256:5d008e0f67ac800b0ca04d7914b8501312c8c6c00ad8c7ba17754609fae1231a", - "sha256:649df3641eb351cdfd0d5533c92fc9df507b6b2bf48a7ef8c71ab63cbc7b5c3c", - "sha256:6e78b1e25e5c5695dea012be473e442f7094d066925604be20b30713dbd47f89", - "sha256:72d9d186508325a456475dd05b1756f9a204c7086b07fffb227ef8cee03b1dc2", - "sha256:7d82c610a2e10372e128023c5baf9ce3d270f3029fe7274ff5bc2897c68f1318", - "sha256:7ee317486593193e066fc5e98ac0ce712178c21529a85c07b7cb978171f25d53", - "sha256:7eed8459a2b81848cafb3280b39d7d49950d5f98e403677941c752e7e7ee47cb", - "sha256:823f9325283dc9565ba0aa2d240471a93ca8999861779b2b6c7aded45b58ee0f", - "sha256:85c5fc9029043cf8b07f73fbb0a7ab6d3b717510c3b5642b77058ea55d7cacde", - "sha256:86c91c511853dfda81c2cf2360502cb72783f4b7cebabef27869f00cbe1db07d", - "sha256:8e0c3525b1a182c8ffc9bca7e56b521e0c2b8b3e82f033c8e16d6d721f1b54d6", - "sha256:987a84ff98a309994ca77ed3cc4b92424f824278e48e4bf7d1bb79a63cfe2099", - "sha256:9ed3244b415725f08ca3bdf02ed681089fd95e9465099a21c8e2d9c5d6ca2606", - "sha256:a189036c50dcd56100746139a459f0d27540fef95b09aba03e786540b8feaa5f", - "sha256:a4748349734110fd32d46ff8897b561e6300d8989a494ad5a0a2e4f0ca974fc7", - "sha256:a5d79c9af3f410a2b5acad91258b4ae179ee9c83897eb9de69151b179b0227f5", - "sha256:a7596aa2f2b8fa5604129cfc9a27ad9beec0a96f18078cb424d029fdd707468d", - "sha256:ab4fc4b866b279740e0d917402f0e9a08683e002f43fa408e9655818ed392196", - "sha256:bde4aeabc0d1b2e52c4036c54440b1ad05beeca8113f47aceb4998bb7471e2c2", - "sha256:c72bb4679283c6737f452eeb9b2a0e570acaef2197ad255fb20162adc80bea76", - "sha256:c8582e9280f8d0f38114fe95a92ae8d0790b56b099d728cc4f8a2e14b1c4a18c", - "sha256:ca29c352389ea27a24c79acd117abdd8a865c6eb01576b6f0990cd9a4e9c9f48", - "sha256:ce443a3e6df90d692c38762f108fc4c88314bf477689f04de76b3f252e7a351c", - "sha256:da1a428bdbe71f9a8c270c7baab29e9552ac9d0e0cba5e7e9a4c9ee6465d258d", - "sha256:e67ccd53da5958ea1ec833a160b96357f90859c220a00150de011b787c27b98d", - "sha256:e8071e7d9ba9f457fc674afc3de054450be2c9b195c470147fbbc082468d8ff7", - "sha256:fff16a30fdf57b214778eff86391301c4509e327a65b877862f7c929f10a4253" + "extras": [ + "toml" + ], + "hashes": [ + "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca", + "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471", + "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a", + "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058", + "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85", + "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143", + "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446", + "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590", + "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a", + "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105", + "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9", + "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a", + "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac", + "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25", + "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2", + "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450", + "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932", + "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba", + "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137", + "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae", + "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614", + "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70", + "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e", + "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505", + "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870", + "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc", + "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451", + "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7", + "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e", + "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566", + "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5", + "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26", + "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2", + "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42", + "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555", + "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43", + "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed", + "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa", + "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516", + "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952", + "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd", + "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09", + "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c", + "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f", + "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6", + "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1", + "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0", + "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e", + "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9", + "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9", + "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e", + "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==6.3" + "markers": "python_version >= '3.8'", + "version": "==7.4.0" }, "decoy": { "hashes": [ - "sha256:57327a6ec24c4f4804d978f9c770cb0ff778d2ed751a45ffc61226bf10fc9f90", - "sha256:dea3634ed92eca686f71e66dfd43350adc1a96c814fb5492a08d3c251c531149" + "sha256:575bdbe81afb4c152cd99a34568a9aa4369461f79d6172c678279c5d5585befe", + "sha256:7ddcc08b8ce991f7705cee76fae9061dcb17352e0a1ca2d9a0d4a0306ebd51cd" ], "index": "pypi", - "markers": "python_version >= '3.6' and python_version < '4.0'", - "version": "==1.11.3" + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==2.1.1" }, "docopt": { "hashes": [ @@ -486,38 +438,39 @@ }, "flake8": { "hashes": [ - "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", - "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" + "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132", + "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.9.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==7.0.0" }, "flake8-annotations": { "hashes": [ - "sha256:0d6cd2e770b5095f09689c9d84cc054c51b929c41a68969ea1beb4b825cac515", - "sha256:d10c4638231f8a50c0a597c4efce42bd7b7d85df4f620a0ddaca526138936a4f" + "sha256:af78e3216ad800d7e144745ece6df706c81b3255290cbf870e54879d495e8ade", + "sha256:ff37375e71e3b83f2a5a04d443c41e2c407de557a884f3300a7fa32f3c41cb0a" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1' and python_full_version < '4.0.0'", - "version": "==2.6.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==3.0.1" }, "flake8-docstrings": { "hashes": [ - "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde", - "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b" + "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af", + "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75" ], "index": "pypi", - "version": "==1.6.0" + "markers": "python_version >= '3.7'", + "version": "==1.7.0" }, "flake8-noqa": { "hashes": [ - "sha256:26d92ca6b72dec732d294e587a2bdeb66dab01acc609ed6a064693d6baa4e789", - "sha256:445618162e0bbae1b9d983326d4e39066c5c6de71ba0c444ca2d4d1fa5b2cdb7" + "sha256:4465e16a19be433980f6f563d05540e2e54797eb11facb9feb50fed60624dc45", + "sha256:771765ab27d1efd157528379acd15131147f9ae578a72d17fb432ca197881243" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.2.9" + "version": "==1.4.0" }, "idna": { "hashes": [ @@ -537,65 +490,78 @@ }, "jmespath": { "hashes": [ - "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9", - "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f" + "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", + "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.0" + "markers": "python_version >= '3.7'", + "version": "==1.0.1" }, "jsonschema": { "hashes": [ - "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163", - "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a" + "sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f", + "sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5" ], - "version": "==3.2.0" + "markers": "python_version >= '3.8'", + "version": "==4.21.1" + }, + "jsonschema-specifications": { + "hashes": [ + "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc", + "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c" + ], + "markers": "python_version >= '3.8'", + "version": "==2023.12.1" }, "mccabe": { "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "version": "==0.6.1" + "markers": "python_version >= '3.6'", + "version": "==0.7.0" }, "mock": { "hashes": [ - "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62", - "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc" + "sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744", + "sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d" ], "index": "pypi", "markers": "python_version >= '3.6'", - "version": "==4.0.3" + "version": "==5.1.0" }, "mypy": { "hashes": [ - "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", - "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", - "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", - "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", - "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", - "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", - "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", - "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", - "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", - "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", - "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", - "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", - "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", - "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", - "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", - "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", - "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", - "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", - "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", - "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", - "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", - "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", - "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", - "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" + "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6", + "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d", + "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02", + "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d", + "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3", + "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3", + "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3", + "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66", + "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259", + "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835", + "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd", + "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d", + "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8", + "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07", + "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b", + "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e", + "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6", + "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae", + "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9", + "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d", + "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a", + "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592", + "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218", + "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817", + "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4", + "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410", + "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.981" + "markers": "python_version >= '3.8'", + "version": "==1.8.0" }, "mypy-extensions": { "hashes": [ @@ -615,9 +581,9 @@ }, "paho-mqtt": { "hashes": [ - "sha256:9feb068e822be7b3a116324e01fb6028eb1d66412bf98595ae72698965cb1cae" + "sha256:2a8291c81623aec00372b5a85558a372c747cbca8e9934dfe218638b8eefc26f" ], - "version": "==1.5.1" + "version": "==1.6.1" }, "pathspec": { "hashes": [ @@ -637,19 +603,19 @@ }, "platformdirs": { "hashes": [ - "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", - "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", + "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "pluggy": { "hashes": [ - "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", - "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981", + "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be" ], "markers": "python_version >= '3.8'", - "version": "==1.3.0" + "version": "==1.4.0" }, "py": { "hashes": [ @@ -661,11 +627,11 @@ }, "pycodestyle": { "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" + "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.7.0" + "markers": "python_version >= '3.8'", + "version": "==2.11.1" }, "pydocstyle": { "hashes": [ @@ -677,17 +643,18 @@ }, "pyflakes": { "hashes": [ - "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", - "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" + "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", + "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.3.1" + "markers": "python_version >= '3.8'", + "version": "==3.2.0" }, "pyjwt": { "hashes": [ "sha256:69285c7e31fc44f68a1feb309e948e0df53259d579295e6cfe2b1792329f05fd", "sha256:d83c3d892a77bbb74d3e1a2cfa90afaadb60945205d1095d9221f04466f64c14" ], + "index": "pypi", "markers": "python_version >= '3.7'", "version": "==2.6.0" }, @@ -698,44 +665,6 @@ ], "version": "==1.8.0" }, - "pyrsistent": { - "hashes": [ - "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f", - "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e", - "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958", - "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34", - "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca", - "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d", - "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d", - "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4", - "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714", - "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf", - "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee", - "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8", - "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224", - "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d", - "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054", - "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656", - "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7", - "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423", - "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce", - "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e", - "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3", - "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0", - "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f", - "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b", - "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce", - "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a", - "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174", - "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86", - "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f", - "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b", - "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98", - "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022" - ], - "markers": "python_version >= '3.8'", - "version": "==0.20.0" - }, "pytest": { "hashes": [ "sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e", @@ -747,21 +676,21 @@ }, "pytest-asyncio": { "hashes": [ - "sha256:5c510e5d3ad0f97bab0ae0223363d2aa6329bbbafb0981d96dbed6a804a99349", - "sha256:5e33f5010402309ff4e8cdec04e76b057ae73e0c132f12c6aa2fa6ec8cabfbf1" + "sha256:236e89745b8be43b3b473640b523f26fe3c62a2afa7548e38532e9f201d22fc3", + "sha256:91ef405536331eb9971511aeb08225869985d800cf491015f7407044e7d1d7f8" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.18.0" + "markers": "python_version >= '3.8'", + "version": "==0.23.0" }, "pytest-cov": { "hashes": [ - "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191", - "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e" + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.10.1" + "markers": "python_version >= '3.7'", + "version": "==4.1.0" }, "pytest-forked": { "hashes": [ @@ -790,11 +719,26 @@ }, "python-box": { "hashes": [ - "sha256:60ae9156de34cf92b899bd099580950df70a5b0813e67a3310a1cdd1976457fa", - "sha256:b68e0f8abc86f3deda751b3390f64df64a0989459de51ba4db949662a7b4d8ac" + "sha256:11cbe62f0dace8a6e2a10d210a5e87b99ad1a1286865568862516794c923a988", + "sha256:1d29eafaa287857751e27fbe9a08dd856480f0037fe988b221eba4dac33e5852", + "sha256:3638d3559f19ece7fa29f6a6550bc64696cd3b65e3d4154df07a3d06982252ff", + "sha256:3f0036f91e13958d2b37d2bc74c1197aa36ffd66755342eb64910f63d8a2990f", + "sha256:53998c3b95e31d1f31e46279ef1d27ac30b137746927260901ee61457f8468a0", + "sha256:594b0363b187df855ff8649488b1301dddbbeea769629b7caeb584efe779b841", + "sha256:6e7c243b356cb36e2c0f0e5ed7850969fede6aa812a7f501de7768996c7744d7", + "sha256:7b73f26e40a7adc57b9e39f5687d026dfa8a336f48aefaf852a223b4e37392ad", + "sha256:9dbd92b67c443a97326273c9239fce04d3b6958be815d293f96ab65bc4a9dae7", + "sha256:ab13208b053525ef154a36a4a52873b98a12b18b946edd4c939a4d5080e9a218", + "sha256:ac44b3b85714a4575cc273b5dbd39ef739f938ef6c522d6757704a29e7797d16", + "sha256:af6bcee7e1abe9251e9a41ca9ab677e1f679f6059321cfbae7e78a3831e0b736", + "sha256:bdec0a5f5a17b01fc538d292602a077aa8c641fb121e1900dff0591791af80e8", + "sha256:c14aa4e72bf30f4d573e62ff8030a86548603a100c3fb534561dbedf4a83f454", + "sha256:d199cd289b4f4d053770eadd70217c76214aac30b92a23adfb9627fd8558d300", + "sha256:ed6d7fe47d756dc2d9dea448702cea103716580a2efee7c859954929295fe28e", + "sha256:fa4696b5e09ccf695bf05c16bb5ca1fcc95a141a71a31eb262eee8e2ac07189a" ], - "markers": "python_version >= '3.6'", - "version": "==5.4.1" + "markers": "python_version >= '3.7'", + "version": "==6.1.0" }, "python-dateutil": { "hashes": [ @@ -835,6 +779,7 @@ "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", @@ -860,6 +805,14 @@ "markers": "python_version >= '3.6'", "version": "==6.0.1" }, + "referencing": { + "hashes": [ + "sha256:39240f2ecc770258f28b642dd47fd74bc8b02484de54e1882b74b35ebd779bd5", + "sha256:c775fedf74bc0f9189c2a3be1c12fd03e8c23f4d371dce795df44e06c5b412f7" + ], + "markers": "python_version >= '3.8'", + "version": "==0.33.0" + }, "requests": { "hashes": [ "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", @@ -869,6 +822,111 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "version": "==2.27.1" }, + "rpds-py": { + "hashes": [ + "sha256:01f58a7306b64e0a4fe042047dd2b7d411ee82e54240284bab63e325762c1147", + "sha256:0210b2668f24c078307260bf88bdac9d6f1093635df5123789bfee4d8d7fc8e7", + "sha256:02866e060219514940342a1f84303a1ef7a1dad0ac311792fbbe19b521b489d2", + "sha256:0387ce69ba06e43df54e43968090f3626e231e4bc9150e4c3246947567695f68", + "sha256:060f412230d5f19fc8c8b75f315931b408d8ebf56aec33ef4168d1b9e54200b1", + "sha256:071bc28c589b86bc6351a339114fb7a029f5cddbaca34103aa573eba7b482382", + "sha256:0bfb09bf41fe7c51413f563373e5f537eaa653d7adc4830399d4e9bdc199959d", + "sha256:10162fe3f5f47c37ebf6d8ff5a2368508fe22007e3077bf25b9c7d803454d921", + "sha256:149c5cd24f729e3567b56e1795f74577aa3126c14c11e457bec1b1c90d212e38", + "sha256:1701fc54460ae2e5efc1dd6350eafd7a760f516df8dbe51d4a1c79d69472fbd4", + "sha256:1957a2ab607f9added64478a6982742eb29f109d89d065fa44e01691a20fc20a", + "sha256:1a746a6d49665058a5896000e8d9d2f1a6acba8a03b389c1e4c06e11e0b7f40d", + "sha256:1bfcad3109c1e5ba3cbe2f421614e70439f72897515a96c462ea657261b96518", + "sha256:1d36b2b59e8cc6e576f8f7b671e32f2ff43153f0ad6d0201250a7c07f25d570e", + "sha256:1db228102ab9d1ff4c64148c96320d0be7044fa28bd865a9ce628ce98da5973d", + "sha256:1dc29db3900cb1bb40353772417800f29c3d078dbc8024fd64655a04ee3c4bdf", + "sha256:1e626b365293a2142a62b9a614e1f8e331b28f3ca57b9f05ebbf4cf2a0f0bdc5", + "sha256:1f3c3461ebb4c4f1bbc70b15d20b565759f97a5aaf13af811fcefc892e9197ba", + "sha256:20de7b7179e2031a04042e85dc463a93a82bc177eeba5ddd13ff746325558aa6", + "sha256:24e4900a6643f87058a27320f81336d527ccfe503984528edde4bb660c8c8d59", + "sha256:2528ff96d09f12e638695f3a2e0c609c7b84c6df7c5ae9bfeb9252b6fa686253", + "sha256:25f071737dae674ca8937a73d0f43f5a52e92c2d178330b4c0bb6ab05586ffa6", + "sha256:270987bc22e7e5a962b1094953ae901395e8c1e1e83ad016c5cfcfff75a15a3f", + "sha256:292f7344a3301802e7c25c53792fae7d1593cb0e50964e7bcdcc5cf533d634e3", + "sha256:2953937f83820376b5979318840f3ee47477d94c17b940fe31d9458d79ae7eea", + "sha256:2a792b2e1d3038daa83fa474d559acfd6dc1e3650ee93b2662ddc17dbff20ad1", + "sha256:2a7b2f2f56a16a6d62e55354dd329d929560442bd92e87397b7a9586a32e3e76", + "sha256:2f4eb548daf4836e3b2c662033bfbfc551db58d30fd8fe660314f86bf8510b93", + "sha256:3664d126d3388a887db44c2e293f87d500c4184ec43d5d14d2d2babdb4c64cad", + "sha256:3677fcca7fb728c86a78660c7fb1b07b69b281964673f486ae72860e13f512ad", + "sha256:380e0df2e9d5d5d339803cfc6d183a5442ad7ab3c63c2a0982e8c824566c5ccc", + "sha256:3ac732390d529d8469b831949c78085b034bff67f584559340008d0f6041a049", + "sha256:4128980a14ed805e1b91a7ed551250282a8ddf8201a4e9f8f5b7e6225f54170d", + "sha256:4341bd7579611cf50e7b20bb8c2e23512a3dc79de987a1f411cb458ab670eb90", + "sha256:436474f17733c7dca0fbf096d36ae65277e8645039df12a0fa52445ca494729d", + "sha256:4dc889a9d8a34758d0fcc9ac86adb97bab3fb7f0c4d29794357eb147536483fd", + "sha256:4e21b76075c01d65d0f0f34302b5a7457d95721d5e0667aea65e5bb3ab415c25", + "sha256:516fb8c77805159e97a689e2f1c80655c7658f5af601c34ffdb916605598cda2", + "sha256:5576ee2f3a309d2bb403ec292d5958ce03953b0e57a11d224c1f134feaf8c40f", + "sha256:5a024fa96d541fd7edaa0e9d904601c6445e95a729a2900c5aec6555fe921ed6", + "sha256:5d0e8a6434a3fbf77d11448c9c25b2f25244226cfbec1a5159947cac5b8c5fa4", + "sha256:5e7d63ec01fe7c76c2dbb7e972fece45acbb8836e72682bde138e7e039906e2c", + "sha256:60e820ee1004327609b28db8307acc27f5f2e9a0b185b2064c5f23e815f248f8", + "sha256:637b802f3f069a64436d432117a7e58fab414b4e27a7e81049817ae94de45d8d", + "sha256:65dcf105c1943cba45d19207ef51b8bc46d232a381e94dd38719d52d3980015b", + "sha256:698ea95a60c8b16b58be9d854c9f993c639f5c214cf9ba782eca53a8789d6b19", + "sha256:70fcc6c2906cfa5c6a552ba7ae2ce64b6c32f437d8f3f8eea49925b278a61453", + "sha256:720215373a280f78a1814becb1312d4e4d1077b1202a56d2b0815e95ccb99ce9", + "sha256:7450dbd659fed6dd41d1a7d47ed767e893ba402af8ae664c157c255ec6067fde", + "sha256:7b7d9ca34542099b4e185b3c2a2b2eda2e318a7dbde0b0d83357a6d4421b5296", + "sha256:7fbd70cb8b54fe745301921b0816c08b6d917593429dfc437fd024b5ba713c58", + "sha256:81038ff87a4e04c22e1d81f947c6ac46f122e0c80460b9006e6517c4d842a6ec", + "sha256:810685321f4a304b2b55577c915bece4c4a06dfe38f6e62d9cc1d6ca8ee86b99", + "sha256:82ada4a8ed9e82e443fcef87e22a3eed3654dd3adf6e3b3a0deb70f03e86142a", + "sha256:841320e1841bb53fada91c9725e766bb25009cfd4144e92298db296fb6c894fb", + "sha256:8587fd64c2a91c33cdc39d0cebdaf30e79491cc029a37fcd458ba863f8815383", + "sha256:8ffe53e1d8ef2520ebcf0c9fec15bb721da59e8ef283b6ff3079613b1e30513d", + "sha256:9051e3d2af8f55b42061603e29e744724cb5f65b128a491446cc029b3e2ea896", + "sha256:91e5a8200e65aaac342a791272c564dffcf1281abd635d304d6c4e6b495f29dc", + "sha256:93432e747fb07fa567ad9cc7aaadd6e29710e515aabf939dfbed8046041346c6", + "sha256:938eab7323a736533f015e6069a7d53ef2dcc841e4e533b782c2bfb9fb12d84b", + "sha256:9584f8f52010295a4a417221861df9bea4c72d9632562b6e59b3c7b87a1522b7", + "sha256:9737bdaa0ad33d34c0efc718741abaafce62fadae72c8b251df9b0c823c63b22", + "sha256:99da0a4686ada4ed0f778120a0ea8d066de1a0a92ab0d13ae68492a437db78bf", + "sha256:99f567dae93e10be2daaa896e07513dd4bf9c2ecf0576e0533ac36ba3b1d5394", + "sha256:9bdf1303df671179eaf2cb41e8515a07fc78d9d00f111eadbe3e14262f59c3d0", + "sha256:9f0e4dc0f17dcea4ab9d13ac5c666b6b5337042b4d8f27e01b70fae41dd65c57", + "sha256:a000133a90eea274a6f28adc3084643263b1e7c1a5a66eb0a0a7a36aa757ed74", + "sha256:a3264e3e858de4fc601741498215835ff324ff2482fd4e4af61b46512dd7fc83", + "sha256:a71169d505af63bb4d20d23a8fbd4c6ce272e7bce6cc31f617152aa784436f29", + "sha256:a967dd6afda7715d911c25a6ba1517975acd8d1092b2f326718725461a3d33f9", + "sha256:aa5bfb13f1e89151ade0eb812f7b0d7a4d643406caaad65ce1cbabe0a66d695f", + "sha256:ae35e8e6801c5ab071b992cb2da958eee76340e6926ec693b5ff7d6381441745", + "sha256:b686f25377f9c006acbac63f61614416a6317133ab7fafe5de5f7dc8a06d42eb", + "sha256:b760a56e080a826c2e5af09002c1a037382ed21d03134eb6294812dda268c811", + "sha256:b86b21b348f7e5485fae740d845c65a880f5d1eda1e063bc59bef92d1f7d0c55", + "sha256:b9412abdf0ba70faa6e2ee6c0cc62a8defb772e78860cef419865917d86c7342", + "sha256:bd345a13ce06e94c753dab52f8e71e5252aec1e4f8022d24d56decd31e1b9b23", + "sha256:be22ae34d68544df293152b7e50895ba70d2a833ad9566932d750d3625918b82", + "sha256:bf046179d011e6114daf12a534d874958b039342b347348a78b7cdf0dd9d6041", + "sha256:c3d2010656999b63e628a3c694f23020322b4178c450dc478558a2b6ef3cb9bb", + "sha256:c64602e8be701c6cfe42064b71c84ce62ce66ddc6422c15463fd8127db3d8066", + "sha256:d65e6b4f1443048eb7e833c2accb4fa7ee67cc7d54f31b4f0555b474758bee55", + "sha256:d8bbd8e56f3ba25a7d0cf980fc42b34028848a53a0e36c9918550e0280b9d0b6", + "sha256:da1ead63368c04a9bded7904757dfcae01eba0e0f9bc41d3d7f57ebf1c04015a", + "sha256:dbbb95e6fc91ea3102505d111b327004d1c4ce98d56a4a02e82cd451f9f57140", + "sha256:dbc56680ecf585a384fbd93cd42bc82668b77cb525343170a2d86dafaed2a84b", + "sha256:df3b6f45ba4515632c5064e35ca7f31d51d13d1479673185ba8f9fefbbed58b9", + "sha256:dfe07308b311a8293a0d5ef4e61411c5c20f682db6b5e73de6c7c8824272c256", + "sha256:e796051f2070f47230c745d0a77a91088fbee2cc0502e9b796b9c6471983718c", + "sha256:efa767c220d94aa4ac3a6dd3aeb986e9f229eaf5bce92d8b1b3018d06bed3772", + "sha256:f0b8bf5b8db49d8fd40f54772a1dcf262e8be0ad2ab0206b5a2ec109c176c0a4", + "sha256:f175e95a197f6a4059b50757a3dca33b32b61691bdbd22c29e8a8d21d3914cae", + "sha256:f2f3b28b40fddcb6c1f1f6c88c6f3769cd933fa493ceb79da45968a21dccc920", + "sha256:f6c43b6f97209e370124baf2bf40bb1e8edc25311a158867eb1c3a5d449ebc7a", + "sha256:f7f4cb1f173385e8a39c29510dd11a78bf44e360fb75610594973f5ea141028b", + "sha256:fad059a4bd14c45776600d223ec194e77db6c20255578bb5bcdd7c18fd169361", + "sha256:ff1dcb8e8bc2261a088821b2595ef031c91d499a0c1b031c152d43fe0a6ecec8", + "sha256:ffee088ea9b593cc6160518ba9bd319b5475e5f3e578e4552d63818773c6f56a" + ], + "markers": "python_version >= '3.8'", + "version": "==0.17.1" + }, "ruamel.yaml": { "hashes": [ "sha256:61917e3a35a569c1133a8f772e1226961bf5a1198bea7e23f06a0841dea1ab0e", @@ -933,14 +991,6 @@ "markers": "python_version < '3.13' and platform_python_implementation == 'CPython'", "version": "==0.2.8" }, - "setuptools": { - "hashes": [ - "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2", - "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6" - ], - "markers": "python_version >= '3.8'", - "version": "==69.0.2" - }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -967,19 +1017,20 @@ }, "stevedore": { "hashes": [ - "sha256:4e485ad9b087d1ce475b747d8abd21c328cd7410b5a7a70ca73431be29dc5bac", - "sha256:937f644e83276ca231e21376b400ffe56637d24258bbcc47db6e80be1f60894f" + "sha256:7f8aeb6e3f90f96832c301bff21a7eb5eefbe894c88c506483d355565d88cc1a", + "sha256:aa6436565c069b2946fe4ebff07f5041e0c8bf18c7376dd29edf80cf7d524e4e" ], - "markers": "python_version >= '3.6'", - "version": "==3.3.3" + "markers": "python_version >= '3.8'", + "version": "==4.1.1" }, "tavern": { "hashes": [ - "sha256:18ea77cfe0d0be1b99900b447487279e7769c21e23b53e9865be40035da71fc6" + "sha256:056c4c45e27c97552ae9a3eb6a249701820a09465b4131cc4e71489166d8442d", + "sha256:21ce0c29f9e15e4b613f5f43df6da96ed0e115e5d52b4b8c1501e898708e9d35" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==1.25.2" + "markers": "python_version >= '3.8'", + "version": "==2.9.1" }, "tomli": { "hashes": [ @@ -991,19 +1042,19 @@ }, "types-mock": { "hashes": [ - "sha256:1a470543be8de673e2ea14739622de3bfb8c9b10429f50338ba9ca1e868c15e9", - "sha256:1ad09970f4f5ec45a138ab1e88d032f010e851bccef7765b34737ed390bbc5c8" + "sha256:89ee23530e4943670d3b12c90633ace99d53983d5416469af90a425b65d1751e", + "sha256:bf541bff83092d0bc89ff63598c0f4374cf59d8358348461227732bc0614f41e" ], "index": "pypi", - "version": "==4.0.1" + "version": "==5.1.0.0" }, "types-requests": { "hashes": [ - "sha256:a5a305b43ea57bf64d6731f89816946a405b591eff6de28d4c0fd58422cee779", - "sha256:e21541c0f55c066c491a639309159556dd8c5833e49fcde929c4c47bdb0002ee" + "sha256:59ae7a60ed4b61ece7ff6f0ccff394e4d65a6df9b2970cfeb7a0015cb0c91b7e", + "sha256:d03823054e34cb683ffcc4a05035482224c264096b20e1e14adb99f2b1775f09" ], "index": "pypi", - "version": "==2.25.6" + "version": "==2.27.1" }, "typing-extensions": { "hashes": [ diff --git a/system-server/setup.py b/system-server/setup.py index 81adff440fa..4aeed436d55 100644 --- a/system-server/setup.py +++ b/system-server/setup.py @@ -49,7 +49,7 @@ def get_version(): INSTALL_REQUIRES = [ "pyjwt==2.6.0", "systemd-python==234; sys_platform=='linux'", - "sqlalchemy==1.4.32", + "sqlalchemy==1.4.51", ] diff --git a/system-server/system_server/__main__.py b/system-server/system_server/__main__.py index df3596249b2..15e4f9bf78a 100644 --- a/system-server/system_server/__main__.py +++ b/system-server/system_server/__main__.py @@ -2,7 +2,7 @@ import logging from . import systemd from .cli import build_root_parser -import uvicorn # type: ignore[import] +import uvicorn LOG = logging.getLogger(__name__) diff --git a/system-server/system_server/settings/settings.py b/system-server/system_server/settings/settings.py index 0019cd9e3b6..a042b76b91d 100644 --- a/system-server/system_server/settings/settings.py +++ b/system-server/system_server/settings/settings.py @@ -27,7 +27,8 @@ class Environment(BaseSettings): """Environment related settings.""" dot_env_path: typing.Optional[str] = Field( - None, description="Path to a .env file to define system server settings." + default=None, + description="Path to a .env file to define system server settings.", ) class Config: @@ -45,7 +46,7 @@ class SystemServerSettings(BaseSettings): """ persistence_directory: typing.Optional[str] = Field( - None, + default=None, description=( "A directory for the server to store things persistently across boots." " If this directory doesn't already exist, the server will create it." diff --git a/system-server/tests/persistence/test_migrations.py b/system-server/tests/persistence/test_migrations.py index 3e83a8760ff..d24fc93f467 100644 --- a/system-server/tests/persistence/test_migrations.py +++ b/system-server/tests/persistence/test_migrations.py @@ -4,7 +4,7 @@ import pytest import sqlalchemy -from pytest_lazyfixture import lazy_fixture # type: ignore[import] +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from system_server.persistence.database import create_sql_engine from system_server.persistence import ( diff --git a/update-server/Pipfile b/update-server/Pipfile index d5d6c65b5db..975e075afb9 100644 --- a/update-server/Pipfile +++ b/update-server/Pipfile @@ -4,27 +4,27 @@ verify_ssl = true name = "pypi" [packages] -typing-extensions = "==3.10.0.0" +typing-extensions = ">=4.0.0,<5" otupdate = {path = ".", editable = true} [dev-packages] -flake8 = "~=3.9.0" -flake8-annotations = "~=2.6.2" -flake8-docstrings = "~=1.6.0" -flake8-noqa = "~=1.1.0" -pytest = "==7.1.1" +flake8 = "~=7.0.0" +flake8-annotations = "~=3.0.1" +flake8-docstrings = "~=1.7.0" +flake8-noqa = "~=1.4.0" +pytest = "==7.4.4." pytest-watch = "~=4.2.0" -pytest-cov = "==2.10.1" -pytest-aiohttp = "==0.3.0" -coverage = "==6.3.2" +pytest-cov = "==4.1.0" +pytest-aiohttp = "==1.0.5" +coverage = "==7.4.1" # atomicwrites and colorama are pytest dependencies on windows, # spec'd here to force lockfile inclusion # https://github.com/pypa/pipenv/issues/4408#issuecomment-668324177 atomicwrites = {version="==1.4.0", markers="sys_platform=='win32'"} colorama = {version="==0.4.4", markers="sys_platform=='win32'"} -mypy = "==0.981" +mypy = "==1.8.0" black = "==22.3.0" -decoy = "~=1.10" +decoy = "~=2.1.1" [requires] python_version = "3.10" diff --git a/update-server/Pipfile.lock b/update-server/Pipfile.lock index da290ac820d..9f26d21c134 100644 --- a/update-server/Pipfile.lock +++ b/update-server/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d7a20a1572e3ed9bc64264b322c786b3a5013f95b263633fe4a449a77f165827" + "sha256": "115cd9d2eae2f695378fed0db8301eb63a0d84ac581e0ee0b606f0d77293206e" }, "pipfile-spec": 6, "requires": { @@ -18,96 +18,85 @@ "default": { "aiohttp": { "hashes": [ - "sha256:03543dcf98a6619254b409be2d22b51f21ec66272be4ebda7b04e6412e4b2e14", - "sha256:03baa76b730e4e15a45f81dfe29a8d910314143414e528737f8589ec60cf7391", - "sha256:0a63f03189a6fa7c900226e3ef5ba4d3bd047e18f445e69adbd65af433add5a2", - "sha256:10c8cefcff98fd9168cdd86c4da8b84baaa90bf2da2269c6161984e6737bf23e", - "sha256:147ae376f14b55f4f3c2b118b95be50a369b89b38a971e80a17c3fd623f280c9", - "sha256:176a64b24c0935869d5bbc4c96e82f89f643bcdf08ec947701b9dbb3c956b7dd", - "sha256:17b79c2963db82086229012cff93ea55196ed31f6493bb1ccd2c62f1724324e4", - "sha256:1a45865451439eb320784918617ba54b7a377e3501fb70402ab84d38c2cd891b", - "sha256:1b3ea7edd2d24538959c1c1abf97c744d879d4e541d38305f9bd7d9b10c9ec41", - "sha256:22f6eab15b6db242499a16de87939a342f5a950ad0abaf1532038e2ce7d31567", - "sha256:3032dcb1c35bc330134a5b8a5d4f68c1a87252dfc6e1262c65a7e30e62298275", - "sha256:33587f26dcee66efb2fff3c177547bd0449ab7edf1b73a7f5dea1e38609a0c54", - "sha256:34ce9f93a4a68d1272d26030655dd1b58ff727b3ed2a33d80ec433561b03d67a", - "sha256:3a80464982d41b1fbfe3154e440ba4904b71c1a53e9cd584098cd41efdb188ef", - "sha256:3b90467ebc3d9fa5b0f9b6489dfb2c304a1db7b9946fa92aa76a831b9d587e99", - "sha256:3d89efa095ca7d442a6d0cbc755f9e08190ba40069b235c9886a8763b03785da", - "sha256:3d8ef1a630519a26d6760bc695842579cb09e373c5f227a21b67dc3eb16cfea4", - "sha256:3f43255086fe25e36fd5ed8f2ee47477408a73ef00e804cb2b5cba4bf2ac7f5e", - "sha256:40653609b3bf50611356e6b6554e3a331f6879fa7116f3959b20e3528783e699", - "sha256:41a86a69bb63bb2fc3dc9ad5ea9f10f1c9c8e282b471931be0268ddd09430b04", - "sha256:493f5bc2f8307286b7799c6d899d388bbaa7dfa6c4caf4f97ef7521b9cb13719", - "sha256:4a6cadebe132e90cefa77e45f2d2f1a4b2ce5c6b1bfc1656c1ddafcfe4ba8131", - "sha256:4c745b109057e7e5f1848c689ee4fb3a016c8d4d92da52b312f8a509f83aa05e", - "sha256:4d347a172f866cd1d93126d9b239fcbe682acb39b48ee0873c73c933dd23bd0f", - "sha256:4dac314662f4e2aa5009977b652d9b8db7121b46c38f2073bfeed9f4049732cd", - "sha256:4ddaae3f3d32fc2cb4c53fab020b69a05c8ab1f02e0e59665c6f7a0d3a5be54f", - "sha256:5393fb786a9e23e4799fec788e7e735de18052f83682ce2dfcabaf1c00c2c08e", - "sha256:59f029a5f6e2d679296db7bee982bb3d20c088e52a2977e3175faf31d6fb75d1", - "sha256:5a7bdf9e57126dc345b683c3632e8ba317c31d2a41acd5800c10640387d193ed", - "sha256:5b3f2e06a512e94722886c0827bee9807c86a9f698fac6b3aee841fab49bbfb4", - "sha256:5ce45967538fb747370308d3145aa68a074bdecb4f3a300869590f725ced69c1", - "sha256:5e14f25765a578a0a634d5f0cd1e2c3f53964553a00347998dfdf96b8137f777", - "sha256:618c901dd3aad4ace71dfa0f5e82e88b46ef57e3239fc7027773cb6d4ed53531", - "sha256:652b1bff4f15f6287550b4670546a2947f2a4575b6c6dff7760eafb22eacbf0b", - "sha256:6c08e8ed6fa3d477e501ec9db169bfac8140e830aa372d77e4a43084d8dd91ab", - "sha256:6ddb2a2026c3f6a68c3998a6c47ab6795e4127315d2e35a09997da21865757f8", - "sha256:6e601588f2b502c93c30cd5a45bfc665faaf37bbe835b7cfd461753068232074", - "sha256:6e74dd54f7239fcffe07913ff8b964e28b712f09846e20de78676ce2a3dc0bfc", - "sha256:7235604476a76ef249bd64cb8274ed24ccf6995c4a8b51a237005ee7a57e8643", - "sha256:7ab43061a0c81198d88f39aaf90dae9a7744620978f7ef3e3708339b8ed2ef01", - "sha256:7c7837fe8037e96b6dd5cfcf47263c1620a9d332a87ec06a6ca4564e56bd0f36", - "sha256:80575ba9377c5171407a06d0196b2310b679dc752d02a1fcaa2bc20b235dbf24", - "sha256:80a37fe8f7c1e6ce8f2d9c411676e4bc633a8462844e38f46156d07a7d401654", - "sha256:8189c56eb0ddbb95bfadb8f60ea1b22fcfa659396ea36f6adcc521213cd7b44d", - "sha256:854f422ac44af92bfe172d8e73229c270dc09b96535e8a548f99c84f82dde241", - "sha256:880e15bb6dad90549b43f796b391cfffd7af373f4646784795e20d92606b7a51", - "sha256:8b631e26df63e52f7cce0cce6507b7a7f1bc9b0c501fcde69742130b32e8782f", - "sha256:8c29c77cc57e40f84acef9bfb904373a4e89a4e8b74e71aa8075c021ec9078c2", - "sha256:91f6d540163f90bbaef9387e65f18f73ffd7c79f5225ac3d3f61df7b0d01ad15", - "sha256:92c0cea74a2a81c4c76b62ea1cac163ecb20fb3ba3a75c909b9fa71b4ad493cf", - "sha256:9bcb89336efa095ea21b30f9e686763f2be4478f1b0a616969551982c4ee4c3b", - "sha256:a1f4689c9a1462f3df0a1f7e797791cd6b124ddbee2b570d34e7f38ade0e2c71", - "sha256:a3fec6a4cb5551721cdd70473eb009d90935b4063acc5f40905d40ecfea23e05", - "sha256:a5d794d1ae64e7753e405ba58e08fcfa73e3fad93ef9b7e31112ef3c9a0efb52", - "sha256:a86d42d7cba1cec432d47ab13b6637bee393a10f664c425ea7b305d1301ca1a3", - "sha256:adfbc22e87365a6e564c804c58fc44ff7727deea782d175c33602737b7feadb6", - "sha256:aeb29c84bb53a84b1a81c6c09d24cf33bb8432cc5c39979021cc0f98c1292a1a", - "sha256:aede4df4eeb926c8fa70de46c340a1bc2c6079e1c40ccf7b0eae1313ffd33519", - "sha256:b744c33b6f14ca26b7544e8d8aadff6b765a80ad6164fb1a430bbadd593dfb1a", - "sha256:b7a00a9ed8d6e725b55ef98b1b35c88013245f35f68b1b12c5cd4100dddac333", - "sha256:bb96fa6b56bb536c42d6a4a87dfca570ff8e52de2d63cabebfd6fb67049c34b6", - "sha256:bbcf1a76cf6f6dacf2c7f4d2ebd411438c275faa1dc0c68e46eb84eebd05dd7d", - "sha256:bca5f24726e2919de94f047739d0a4fc01372801a3672708260546aa2601bf57", - "sha256:bf2e1a9162c1e441bf805a1fd166e249d574ca04e03b34f97e2928769e91ab5c", - "sha256:c4eb3b82ca349cf6fadcdc7abcc8b3a50ab74a62e9113ab7a8ebc268aad35bb9", - "sha256:c6cc15d58053c76eacac5fa9152d7d84b8d67b3fde92709195cb984cfb3475ea", - "sha256:c6cd05ea06daca6ad6a4ca3ba7fe7dc5b5de063ff4daec6170ec0f9979f6c332", - "sha256:c844fd628851c0bc309f3c801b3a3d58ce430b2ce5b359cd918a5a76d0b20cb5", - "sha256:c9cb1565a7ad52e096a6988e2ee0397f72fe056dadf75d17fa6b5aebaea05622", - "sha256:cab9401de3ea52b4b4c6971db5fb5c999bd4260898af972bf23de1c6b5dd9d71", - "sha256:cd468460eefef601ece4428d3cf4562459157c0f6523db89365202c31b6daebb", - "sha256:d1e6a862b76f34395a985b3cd39a0d949ca80a70b6ebdea37d3ab39ceea6698a", - "sha256:d1f9282c5f2b5e241034a009779e7b2a1aa045f667ff521e7948ea9b56e0c5ff", - "sha256:d265f09a75a79a788237d7f9054f929ced2e69eb0bb79de3798c468d8a90f945", - "sha256:db3fc6120bce9f446d13b1b834ea5b15341ca9ff3f335e4a951a6ead31105480", - "sha256:dbf3a08a06b3f433013c143ebd72c15cac33d2914b8ea4bea7ac2c23578815d6", - "sha256:de04b491d0e5007ee1b63a309956eaed959a49f5bb4e84b26c8f5d49de140fa9", - "sha256:e4b09863aae0dc965c3ef36500d891a3ff495a2ea9ae9171e4519963c12ceefd", - "sha256:e595432ac259af2d4630008bf638873d69346372d38255774c0e286951e8b79f", - "sha256:e75b89ac3bd27d2d043b234aa7b734c38ba1b0e43f07787130a0ecac1e12228a", - "sha256:ea9eb976ffdd79d0e893869cfe179a8f60f152d42cb64622fca418cd9b18dc2a", - "sha256:eafb3e874816ebe2a92f5e155f17260034c8c341dad1df25672fb710627c6949", - "sha256:ee3c36df21b5714d49fc4580247947aa64bcbe2939d1b77b4c8dcb8f6c9faecc", - "sha256:f352b62b45dff37b55ddd7b9c0c8672c4dd2eb9c0f9c11d395075a84e2c40f75", - "sha256:fabb87dd8850ef0f7fe2b366d44b77d7e6fa2ea87861ab3844da99291e81e60f", - "sha256:fe11310ae1e4cd560035598c3f29d86cef39a83d244c7466f95c27ae04850f10", - "sha256:fe7ba4a51f33ab275515f66b0a236bcde4fb5561498fe8f898d4e549b2e4509f" + "sha256:017a21b0df49039c8f46ca0971b3a7fdc1f56741ab1240cb90ca408049766168", + "sha256:039df344b45ae0b34ac885ab5b53940b174530d4dd8a14ed8b0e2155b9dddccb", + "sha256:055ce4f74b82551678291473f66dc9fb9048a50d8324278751926ff0ae7715e5", + "sha256:06a9b2c8837d9a94fae16c6223acc14b4dfdff216ab9b7202e07a9a09541168f", + "sha256:07b837ef0d2f252f96009e9b8435ec1fef68ef8b1461933253d318748ec1acdc", + "sha256:0ed621426d961df79aa3b963ac7af0d40392956ffa9be022024cd16297b30c8c", + "sha256:0fa43c32d1643f518491d9d3a730f85f5bbaedcbd7fbcae27435bb8b7a061b29", + "sha256:1f5a71d25cd8106eab05f8704cd9167b6e5187bcdf8f090a66c6d88b634802b4", + "sha256:1f5cd333fcf7590a18334c90f8c9147c837a6ec8a178e88d90a9b96ea03194cc", + "sha256:27468897f628c627230dba07ec65dc8d0db566923c48f29e084ce382119802bc", + "sha256:298abd678033b8571995650ccee753d9458dfa0377be4dba91e4491da3f2be63", + "sha256:2c895a656dd7e061b2fd6bb77d971cc38f2afc277229ce7dd3552de8313a483e", + "sha256:361a1026c9dd4aba0109e4040e2aecf9884f5cfe1b1b1bd3d09419c205e2e53d", + "sha256:363afe77cfcbe3a36353d8ea133e904b108feea505aa4792dad6585a8192c55a", + "sha256:38a19bc3b686ad55804ae931012f78f7a534cce165d089a2059f658f6c91fa60", + "sha256:38f307b41e0bea3294a9a2a87833191e4bcf89bb0365e83a8be3a58b31fb7f38", + "sha256:3e59c23c52765951b69ec45ddbbc9403a8761ee6f57253250c6e1536cacc758b", + "sha256:4b4af9f25b49a7be47c0972139e59ec0e8285c371049df1a63b6ca81fdd216a2", + "sha256:504b6981675ace64c28bf4a05a508af5cde526e36492c98916127f5a02354d53", + "sha256:50fca156d718f8ced687a373f9e140c1bb765ca16e3d6f4fe116e3df7c05b2c5", + "sha256:522a11c934ea660ff8953eda090dcd2154d367dec1ae3c540aff9f8a5c109ab4", + "sha256:52df73f14ed99cee84865b95a3d9e044f226320a87af208f068ecc33e0c35b96", + "sha256:595f105710293e76b9dc09f52e0dd896bd064a79346234b521f6b968ffdd8e58", + "sha256:59c26c95975f26e662ca78fdf543d4eeaef70e533a672b4113dd888bd2423caa", + "sha256:5bce0dc147ca85caa5d33debc4f4d65e8e8b5c97c7f9f660f215fa74fc49a321", + "sha256:5eafe2c065df5401ba06821b9a054d9cb2848867f3c59801b5d07a0be3a380ae", + "sha256:5ed3e046ea7b14938112ccd53d91c1539af3e6679b222f9469981e3dac7ba1ce", + "sha256:5fe9ce6c09668063b8447f85d43b8d1c4e5d3d7e92c63173e6180b2ac5d46dd8", + "sha256:648056db9a9fa565d3fa851880f99f45e3f9a771dd3ff3bb0c048ea83fb28194", + "sha256:69361bfdca5468c0488d7017b9b1e5ce769d40b46a9f4a2eed26b78619e9396c", + "sha256:6b0e029353361f1746bac2e4cc19b32f972ec03f0f943b390c4ab3371840aabf", + "sha256:6b88f9386ff1ad91ace19d2a1c0225896e28815ee09fc6a8932fded8cda97c3d", + "sha256:770d015888c2a598b377bd2f663adfd947d78c0124cfe7b959e1ef39f5b13869", + "sha256:7943c414d3a8d9235f5f15c22ace69787c140c80b718dcd57caaade95f7cd93b", + "sha256:7cf5c9458e1e90e3c390c2639f1017a0379a99a94fdfad3a1fd966a2874bba52", + "sha256:7f46acd6a194287b7e41e87957bfe2ad1ad88318d447caf5b090012f2c5bb528", + "sha256:82e6aa28dd46374f72093eda8bcd142f7771ee1eb9d1e223ff0fa7177a96b4a5", + "sha256:835a55b7ca49468aaaac0b217092dfdff370e6c215c9224c52f30daaa735c1c1", + "sha256:84871a243359bb42c12728f04d181a389718710129b36b6aad0fc4655a7647d4", + "sha256:8aacb477dc26797ee089721536a292a664846489c49d3ef9725f992449eda5a8", + "sha256:8e2c45c208c62e955e8256949eb225bd8b66a4c9b6865729a786f2aa79b72e9d", + "sha256:90842933e5d1ff760fae6caca4b2b3edba53ba8f4b71e95dacf2818a2aca06f7", + "sha256:938a9653e1e0c592053f815f7028e41a3062e902095e5a7dc84617c87267ebd5", + "sha256:939677b61f9d72a4fa2a042a5eee2a99a24001a67c13da113b2e30396567db54", + "sha256:9d3c9b50f19704552f23b4eaea1fc082fdd82c63429a6506446cbd8737823da3", + "sha256:a6fe5571784af92b6bc2fda8d1925cccdf24642d49546d3144948a6a1ed58ca5", + "sha256:a78ed8a53a1221393d9637c01870248a6f4ea5b214a59a92a36f18151739452c", + "sha256:ab40e6251c3873d86ea9b30a1ac6d7478c09277b32e14745d0d3c6e76e3c7e29", + "sha256:abf151955990d23f84205286938796c55ff11bbfb4ccfada8c9c83ae6b3c89a3", + "sha256:acef0899fea7492145d2bbaaaec7b345c87753168589cc7faf0afec9afe9b747", + "sha256:b40670ec7e2156d8e57f70aec34a7216407848dfe6c693ef131ddf6e76feb672", + "sha256:b791a3143681a520c0a17e26ae7465f1b6f99461a28019d1a2f425236e6eedb5", + "sha256:b955ed993491f1a5da7f92e98d5dad3c1e14dc175f74517c4e610b1f2456fb11", + "sha256:ba39e9c8627edc56544c8628cc180d88605df3892beeb2b94c9bc857774848ca", + "sha256:bca77a198bb6e69795ef2f09a5f4c12758487f83f33d63acde5f0d4919815768", + "sha256:c3452ea726c76e92f3b9fae4b34a151981a9ec0a4847a627c43d71a15ac32aa6", + "sha256:c46956ed82961e31557b6857a5ca153c67e5476972e5f7190015018760938da2", + "sha256:c7c8b816c2b5af5c8a436df44ca08258fc1a13b449393a91484225fcb7545533", + "sha256:cd73265a9e5ea618014802ab01babf1940cecb90c9762d8b9e7d2cc1e1969ec6", + "sha256:dad46e6f620574b3b4801c68255492e0159d1712271cc99d8bdf35f2043ec266", + "sha256:dc9b311743a78043b26ffaeeb9715dc360335e5517832f5a8e339f8a43581e4d", + "sha256:df822ee7feaaeffb99c1a9e5e608800bd8eda6e5f18f5cfb0dc7eeb2eaa6bbec", + "sha256:e083c285857b78ee21a96ba1eb1b5339733c3563f72980728ca2b08b53826ca5", + "sha256:e5e46b578c0e9db71d04c4b506a2121c0cb371dd89af17a0586ff6769d4c58c1", + "sha256:e99abf0bba688259a496f966211c49a514e65afa9b3073a1fcee08856e04425b", + "sha256:ee43080e75fc92bf36219926c8e6de497f9b247301bbf88c5c7593d931426679", + "sha256:f033d80bc6283092613882dfe40419c6a6a1527e04fc69350e87a9df02bbc283", + "sha256:f1088fa100bf46e7b398ffd9904f4808a0612e1d966b4aa43baa535d1b6341eb", + "sha256:f56455b0c2c7cc3b0c584815264461d07b177f903a04481dfc33e08a89f0c26b", + "sha256:f59dfe57bb1ec82ac0698ebfcdb7bcd0e99c255bd637ff613760d5f33e7c81b3", + "sha256:f7217af2e14da0856e082e96ff637f14ae45c10a5714b63c77f26d8884cf1051", + "sha256:f734e38fd8666f53da904c52a23ce517f1b07722118d750405af7e4123933511", + "sha256:f95511dd5d0e05fd9728bac4096319f80615aaef4acbecb35a990afebe953b0e", + "sha256:fdd215b7b7fd4a53994f238d0f46b7ba4ac4c0adb12452beee724ddd0743ae5d", + "sha256:feeb18a801aacb098220e2c3eea59a512362eb408d4afd0c242044c33ad6d542", + "sha256:ff30218887e62209942f91ac1be902cc80cddb86bf00fbc6783b7a43b2bea26f" ], - "markers": "python_version >= '3.6'", - "version": "==3.8.4" + "markers": "python_version >= '3.8'", + "version": "==3.9.3" }, "aiosignal": { "hashes": [ @@ -122,7 +111,7 @@ "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028" ], - "markers": "python_version >= '3.7'", + "markers": "python_version < '3.11'", "version": "==4.0.3" }, "attrs": { @@ -133,102 +122,6 @@ "markers": "python_version >= '3.7'", "version": "==23.2.0" }, - "charset-normalizer": { - "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" - }, "frozenlist": { "hashes": [ "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", @@ -322,83 +215,99 @@ }, "multidict": { "hashes": [ - "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9", - "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8", - "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03", - "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710", - "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161", - "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664", - "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569", - "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067", - "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313", - "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706", - "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2", - "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636", - "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49", - "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93", - "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603", - "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0", - "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60", - "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4", - "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e", - "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1", - "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60", - "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951", - "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc", - "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe", - "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95", - "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d", - "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8", - "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed", - "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2", - "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775", - "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87", - "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c", - "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2", - "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98", - "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3", - "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe", - "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78", - "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660", - "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176", - "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e", - "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988", - "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c", - "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c", - "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0", - "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449", - "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f", - "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde", - "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5", - "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d", - "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac", - "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a", - "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9", - "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca", - "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11", - "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35", - "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063", - "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b", - "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982", - "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258", - "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1", - "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52", - "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480", - "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7", - "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461", - "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d", - "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc", - "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779", - "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a", - "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547", - "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0", - "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171", - "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf", - "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d", - "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba" + "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556", + "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c", + "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29", + "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b", + "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8", + "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7", + "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd", + "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40", + "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6", + "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3", + "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c", + "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9", + "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5", + "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae", + "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442", + "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9", + "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc", + "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c", + "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea", + "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5", + "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50", + "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182", + "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453", + "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e", + "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600", + "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733", + "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda", + "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241", + "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461", + "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e", + "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e", + "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b", + "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e", + "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7", + "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386", + "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd", + "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9", + "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf", + "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee", + "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5", + "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a", + "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271", + "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54", + "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4", + "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496", + "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb", + "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319", + "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3", + "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f", + "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527", + "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed", + "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604", + "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef", + "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8", + "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5", + "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5", + "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626", + "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c", + "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d", + "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c", + "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc", + "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc", + "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b", + "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38", + "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450", + "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1", + "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f", + "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3", + "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755", + "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226", + "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a", + "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046", + "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf", + "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479", + "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e", + "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1", + "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a", + "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83", + "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929", + "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93", + "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a", + "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c", + "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44", + "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89", + "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba", + "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e", + "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da", + "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24", + "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423", + "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef" ], "markers": "python_version >= '3.7'", - "version": "==6.0.4" + "version": "==6.0.5" }, "otupdate": { "editable": true, @@ -406,12 +315,12 @@ }, "typing-extensions": { "hashes": [ - "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", - "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", - "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "index": "pypi", - "version": "==3.10.0.0" + "markers": "python_version >= '3.8'", + "version": "==4.9.0" }, "yarl": { "hashes": [ @@ -513,96 +422,85 @@ "develop": { "aiohttp": { "hashes": [ - "sha256:03543dcf98a6619254b409be2d22b51f21ec66272be4ebda7b04e6412e4b2e14", - "sha256:03baa76b730e4e15a45f81dfe29a8d910314143414e528737f8589ec60cf7391", - "sha256:0a63f03189a6fa7c900226e3ef5ba4d3bd047e18f445e69adbd65af433add5a2", - "sha256:10c8cefcff98fd9168cdd86c4da8b84baaa90bf2da2269c6161984e6737bf23e", - "sha256:147ae376f14b55f4f3c2b118b95be50a369b89b38a971e80a17c3fd623f280c9", - "sha256:176a64b24c0935869d5bbc4c96e82f89f643bcdf08ec947701b9dbb3c956b7dd", - "sha256:17b79c2963db82086229012cff93ea55196ed31f6493bb1ccd2c62f1724324e4", - "sha256:1a45865451439eb320784918617ba54b7a377e3501fb70402ab84d38c2cd891b", - "sha256:1b3ea7edd2d24538959c1c1abf97c744d879d4e541d38305f9bd7d9b10c9ec41", - "sha256:22f6eab15b6db242499a16de87939a342f5a950ad0abaf1532038e2ce7d31567", - "sha256:3032dcb1c35bc330134a5b8a5d4f68c1a87252dfc6e1262c65a7e30e62298275", - "sha256:33587f26dcee66efb2fff3c177547bd0449ab7edf1b73a7f5dea1e38609a0c54", - "sha256:34ce9f93a4a68d1272d26030655dd1b58ff727b3ed2a33d80ec433561b03d67a", - "sha256:3a80464982d41b1fbfe3154e440ba4904b71c1a53e9cd584098cd41efdb188ef", - "sha256:3b90467ebc3d9fa5b0f9b6489dfb2c304a1db7b9946fa92aa76a831b9d587e99", - "sha256:3d89efa095ca7d442a6d0cbc755f9e08190ba40069b235c9886a8763b03785da", - "sha256:3d8ef1a630519a26d6760bc695842579cb09e373c5f227a21b67dc3eb16cfea4", - "sha256:3f43255086fe25e36fd5ed8f2ee47477408a73ef00e804cb2b5cba4bf2ac7f5e", - "sha256:40653609b3bf50611356e6b6554e3a331f6879fa7116f3959b20e3528783e699", - "sha256:41a86a69bb63bb2fc3dc9ad5ea9f10f1c9c8e282b471931be0268ddd09430b04", - "sha256:493f5bc2f8307286b7799c6d899d388bbaa7dfa6c4caf4f97ef7521b9cb13719", - "sha256:4a6cadebe132e90cefa77e45f2d2f1a4b2ce5c6b1bfc1656c1ddafcfe4ba8131", - "sha256:4c745b109057e7e5f1848c689ee4fb3a016c8d4d92da52b312f8a509f83aa05e", - "sha256:4d347a172f866cd1d93126d9b239fcbe682acb39b48ee0873c73c933dd23bd0f", - "sha256:4dac314662f4e2aa5009977b652d9b8db7121b46c38f2073bfeed9f4049732cd", - "sha256:4ddaae3f3d32fc2cb4c53fab020b69a05c8ab1f02e0e59665c6f7a0d3a5be54f", - "sha256:5393fb786a9e23e4799fec788e7e735de18052f83682ce2dfcabaf1c00c2c08e", - "sha256:59f029a5f6e2d679296db7bee982bb3d20c088e52a2977e3175faf31d6fb75d1", - "sha256:5a7bdf9e57126dc345b683c3632e8ba317c31d2a41acd5800c10640387d193ed", - "sha256:5b3f2e06a512e94722886c0827bee9807c86a9f698fac6b3aee841fab49bbfb4", - "sha256:5ce45967538fb747370308d3145aa68a074bdecb4f3a300869590f725ced69c1", - "sha256:5e14f25765a578a0a634d5f0cd1e2c3f53964553a00347998dfdf96b8137f777", - "sha256:618c901dd3aad4ace71dfa0f5e82e88b46ef57e3239fc7027773cb6d4ed53531", - "sha256:652b1bff4f15f6287550b4670546a2947f2a4575b6c6dff7760eafb22eacbf0b", - "sha256:6c08e8ed6fa3d477e501ec9db169bfac8140e830aa372d77e4a43084d8dd91ab", - "sha256:6ddb2a2026c3f6a68c3998a6c47ab6795e4127315d2e35a09997da21865757f8", - "sha256:6e601588f2b502c93c30cd5a45bfc665faaf37bbe835b7cfd461753068232074", - "sha256:6e74dd54f7239fcffe07913ff8b964e28b712f09846e20de78676ce2a3dc0bfc", - "sha256:7235604476a76ef249bd64cb8274ed24ccf6995c4a8b51a237005ee7a57e8643", - "sha256:7ab43061a0c81198d88f39aaf90dae9a7744620978f7ef3e3708339b8ed2ef01", - "sha256:7c7837fe8037e96b6dd5cfcf47263c1620a9d332a87ec06a6ca4564e56bd0f36", - "sha256:80575ba9377c5171407a06d0196b2310b679dc752d02a1fcaa2bc20b235dbf24", - "sha256:80a37fe8f7c1e6ce8f2d9c411676e4bc633a8462844e38f46156d07a7d401654", - "sha256:8189c56eb0ddbb95bfadb8f60ea1b22fcfa659396ea36f6adcc521213cd7b44d", - "sha256:854f422ac44af92bfe172d8e73229c270dc09b96535e8a548f99c84f82dde241", - "sha256:880e15bb6dad90549b43f796b391cfffd7af373f4646784795e20d92606b7a51", - "sha256:8b631e26df63e52f7cce0cce6507b7a7f1bc9b0c501fcde69742130b32e8782f", - "sha256:8c29c77cc57e40f84acef9bfb904373a4e89a4e8b74e71aa8075c021ec9078c2", - "sha256:91f6d540163f90bbaef9387e65f18f73ffd7c79f5225ac3d3f61df7b0d01ad15", - "sha256:92c0cea74a2a81c4c76b62ea1cac163ecb20fb3ba3a75c909b9fa71b4ad493cf", - "sha256:9bcb89336efa095ea21b30f9e686763f2be4478f1b0a616969551982c4ee4c3b", - "sha256:a1f4689c9a1462f3df0a1f7e797791cd6b124ddbee2b570d34e7f38ade0e2c71", - "sha256:a3fec6a4cb5551721cdd70473eb009d90935b4063acc5f40905d40ecfea23e05", - "sha256:a5d794d1ae64e7753e405ba58e08fcfa73e3fad93ef9b7e31112ef3c9a0efb52", - "sha256:a86d42d7cba1cec432d47ab13b6637bee393a10f664c425ea7b305d1301ca1a3", - "sha256:adfbc22e87365a6e564c804c58fc44ff7727deea782d175c33602737b7feadb6", - "sha256:aeb29c84bb53a84b1a81c6c09d24cf33bb8432cc5c39979021cc0f98c1292a1a", - "sha256:aede4df4eeb926c8fa70de46c340a1bc2c6079e1c40ccf7b0eae1313ffd33519", - "sha256:b744c33b6f14ca26b7544e8d8aadff6b765a80ad6164fb1a430bbadd593dfb1a", - "sha256:b7a00a9ed8d6e725b55ef98b1b35c88013245f35f68b1b12c5cd4100dddac333", - "sha256:bb96fa6b56bb536c42d6a4a87dfca570ff8e52de2d63cabebfd6fb67049c34b6", - "sha256:bbcf1a76cf6f6dacf2c7f4d2ebd411438c275faa1dc0c68e46eb84eebd05dd7d", - "sha256:bca5f24726e2919de94f047739d0a4fc01372801a3672708260546aa2601bf57", - "sha256:bf2e1a9162c1e441bf805a1fd166e249d574ca04e03b34f97e2928769e91ab5c", - "sha256:c4eb3b82ca349cf6fadcdc7abcc8b3a50ab74a62e9113ab7a8ebc268aad35bb9", - "sha256:c6cc15d58053c76eacac5fa9152d7d84b8d67b3fde92709195cb984cfb3475ea", - "sha256:c6cd05ea06daca6ad6a4ca3ba7fe7dc5b5de063ff4daec6170ec0f9979f6c332", - "sha256:c844fd628851c0bc309f3c801b3a3d58ce430b2ce5b359cd918a5a76d0b20cb5", - "sha256:c9cb1565a7ad52e096a6988e2ee0397f72fe056dadf75d17fa6b5aebaea05622", - "sha256:cab9401de3ea52b4b4c6971db5fb5c999bd4260898af972bf23de1c6b5dd9d71", - "sha256:cd468460eefef601ece4428d3cf4562459157c0f6523db89365202c31b6daebb", - "sha256:d1e6a862b76f34395a985b3cd39a0d949ca80a70b6ebdea37d3ab39ceea6698a", - "sha256:d1f9282c5f2b5e241034a009779e7b2a1aa045f667ff521e7948ea9b56e0c5ff", - "sha256:d265f09a75a79a788237d7f9054f929ced2e69eb0bb79de3798c468d8a90f945", - "sha256:db3fc6120bce9f446d13b1b834ea5b15341ca9ff3f335e4a951a6ead31105480", - "sha256:dbf3a08a06b3f433013c143ebd72c15cac33d2914b8ea4bea7ac2c23578815d6", - "sha256:de04b491d0e5007ee1b63a309956eaed959a49f5bb4e84b26c8f5d49de140fa9", - "sha256:e4b09863aae0dc965c3ef36500d891a3ff495a2ea9ae9171e4519963c12ceefd", - "sha256:e595432ac259af2d4630008bf638873d69346372d38255774c0e286951e8b79f", - "sha256:e75b89ac3bd27d2d043b234aa7b734c38ba1b0e43f07787130a0ecac1e12228a", - "sha256:ea9eb976ffdd79d0e893869cfe179a8f60f152d42cb64622fca418cd9b18dc2a", - "sha256:eafb3e874816ebe2a92f5e155f17260034c8c341dad1df25672fb710627c6949", - "sha256:ee3c36df21b5714d49fc4580247947aa64bcbe2939d1b77b4c8dcb8f6c9faecc", - "sha256:f352b62b45dff37b55ddd7b9c0c8672c4dd2eb9c0f9c11d395075a84e2c40f75", - "sha256:fabb87dd8850ef0f7fe2b366d44b77d7e6fa2ea87861ab3844da99291e81e60f", - "sha256:fe11310ae1e4cd560035598c3f29d86cef39a83d244c7466f95c27ae04850f10", - "sha256:fe7ba4a51f33ab275515f66b0a236bcde4fb5561498fe8f898d4e549b2e4509f" + "sha256:017a21b0df49039c8f46ca0971b3a7fdc1f56741ab1240cb90ca408049766168", + "sha256:039df344b45ae0b34ac885ab5b53940b174530d4dd8a14ed8b0e2155b9dddccb", + "sha256:055ce4f74b82551678291473f66dc9fb9048a50d8324278751926ff0ae7715e5", + "sha256:06a9b2c8837d9a94fae16c6223acc14b4dfdff216ab9b7202e07a9a09541168f", + "sha256:07b837ef0d2f252f96009e9b8435ec1fef68ef8b1461933253d318748ec1acdc", + "sha256:0ed621426d961df79aa3b963ac7af0d40392956ffa9be022024cd16297b30c8c", + "sha256:0fa43c32d1643f518491d9d3a730f85f5bbaedcbd7fbcae27435bb8b7a061b29", + "sha256:1f5a71d25cd8106eab05f8704cd9167b6e5187bcdf8f090a66c6d88b634802b4", + "sha256:1f5cd333fcf7590a18334c90f8c9147c837a6ec8a178e88d90a9b96ea03194cc", + "sha256:27468897f628c627230dba07ec65dc8d0db566923c48f29e084ce382119802bc", + "sha256:298abd678033b8571995650ccee753d9458dfa0377be4dba91e4491da3f2be63", + "sha256:2c895a656dd7e061b2fd6bb77d971cc38f2afc277229ce7dd3552de8313a483e", + "sha256:361a1026c9dd4aba0109e4040e2aecf9884f5cfe1b1b1bd3d09419c205e2e53d", + "sha256:363afe77cfcbe3a36353d8ea133e904b108feea505aa4792dad6585a8192c55a", + "sha256:38a19bc3b686ad55804ae931012f78f7a534cce165d089a2059f658f6c91fa60", + "sha256:38f307b41e0bea3294a9a2a87833191e4bcf89bb0365e83a8be3a58b31fb7f38", + "sha256:3e59c23c52765951b69ec45ddbbc9403a8761ee6f57253250c6e1536cacc758b", + "sha256:4b4af9f25b49a7be47c0972139e59ec0e8285c371049df1a63b6ca81fdd216a2", + "sha256:504b6981675ace64c28bf4a05a508af5cde526e36492c98916127f5a02354d53", + "sha256:50fca156d718f8ced687a373f9e140c1bb765ca16e3d6f4fe116e3df7c05b2c5", + "sha256:522a11c934ea660ff8953eda090dcd2154d367dec1ae3c540aff9f8a5c109ab4", + "sha256:52df73f14ed99cee84865b95a3d9e044f226320a87af208f068ecc33e0c35b96", + "sha256:595f105710293e76b9dc09f52e0dd896bd064a79346234b521f6b968ffdd8e58", + "sha256:59c26c95975f26e662ca78fdf543d4eeaef70e533a672b4113dd888bd2423caa", + "sha256:5bce0dc147ca85caa5d33debc4f4d65e8e8b5c97c7f9f660f215fa74fc49a321", + "sha256:5eafe2c065df5401ba06821b9a054d9cb2848867f3c59801b5d07a0be3a380ae", + "sha256:5ed3e046ea7b14938112ccd53d91c1539af3e6679b222f9469981e3dac7ba1ce", + "sha256:5fe9ce6c09668063b8447f85d43b8d1c4e5d3d7e92c63173e6180b2ac5d46dd8", + "sha256:648056db9a9fa565d3fa851880f99f45e3f9a771dd3ff3bb0c048ea83fb28194", + "sha256:69361bfdca5468c0488d7017b9b1e5ce769d40b46a9f4a2eed26b78619e9396c", + "sha256:6b0e029353361f1746bac2e4cc19b32f972ec03f0f943b390c4ab3371840aabf", + "sha256:6b88f9386ff1ad91ace19d2a1c0225896e28815ee09fc6a8932fded8cda97c3d", + "sha256:770d015888c2a598b377bd2f663adfd947d78c0124cfe7b959e1ef39f5b13869", + "sha256:7943c414d3a8d9235f5f15c22ace69787c140c80b718dcd57caaade95f7cd93b", + "sha256:7cf5c9458e1e90e3c390c2639f1017a0379a99a94fdfad3a1fd966a2874bba52", + "sha256:7f46acd6a194287b7e41e87957bfe2ad1ad88318d447caf5b090012f2c5bb528", + "sha256:82e6aa28dd46374f72093eda8bcd142f7771ee1eb9d1e223ff0fa7177a96b4a5", + "sha256:835a55b7ca49468aaaac0b217092dfdff370e6c215c9224c52f30daaa735c1c1", + "sha256:84871a243359bb42c12728f04d181a389718710129b36b6aad0fc4655a7647d4", + "sha256:8aacb477dc26797ee089721536a292a664846489c49d3ef9725f992449eda5a8", + "sha256:8e2c45c208c62e955e8256949eb225bd8b66a4c9b6865729a786f2aa79b72e9d", + "sha256:90842933e5d1ff760fae6caca4b2b3edba53ba8f4b71e95dacf2818a2aca06f7", + "sha256:938a9653e1e0c592053f815f7028e41a3062e902095e5a7dc84617c87267ebd5", + "sha256:939677b61f9d72a4fa2a042a5eee2a99a24001a67c13da113b2e30396567db54", + "sha256:9d3c9b50f19704552f23b4eaea1fc082fdd82c63429a6506446cbd8737823da3", + "sha256:a6fe5571784af92b6bc2fda8d1925cccdf24642d49546d3144948a6a1ed58ca5", + "sha256:a78ed8a53a1221393d9637c01870248a6f4ea5b214a59a92a36f18151739452c", + "sha256:ab40e6251c3873d86ea9b30a1ac6d7478c09277b32e14745d0d3c6e76e3c7e29", + "sha256:abf151955990d23f84205286938796c55ff11bbfb4ccfada8c9c83ae6b3c89a3", + "sha256:acef0899fea7492145d2bbaaaec7b345c87753168589cc7faf0afec9afe9b747", + "sha256:b40670ec7e2156d8e57f70aec34a7216407848dfe6c693ef131ddf6e76feb672", + "sha256:b791a3143681a520c0a17e26ae7465f1b6f99461a28019d1a2f425236e6eedb5", + "sha256:b955ed993491f1a5da7f92e98d5dad3c1e14dc175f74517c4e610b1f2456fb11", + "sha256:ba39e9c8627edc56544c8628cc180d88605df3892beeb2b94c9bc857774848ca", + "sha256:bca77a198bb6e69795ef2f09a5f4c12758487f83f33d63acde5f0d4919815768", + "sha256:c3452ea726c76e92f3b9fae4b34a151981a9ec0a4847a627c43d71a15ac32aa6", + "sha256:c46956ed82961e31557b6857a5ca153c67e5476972e5f7190015018760938da2", + "sha256:c7c8b816c2b5af5c8a436df44ca08258fc1a13b449393a91484225fcb7545533", + "sha256:cd73265a9e5ea618014802ab01babf1940cecb90c9762d8b9e7d2cc1e1969ec6", + "sha256:dad46e6f620574b3b4801c68255492e0159d1712271cc99d8bdf35f2043ec266", + "sha256:dc9b311743a78043b26ffaeeb9715dc360335e5517832f5a8e339f8a43581e4d", + "sha256:df822ee7feaaeffb99c1a9e5e608800bd8eda6e5f18f5cfb0dc7eeb2eaa6bbec", + "sha256:e083c285857b78ee21a96ba1eb1b5339733c3563f72980728ca2b08b53826ca5", + "sha256:e5e46b578c0e9db71d04c4b506a2121c0cb371dd89af17a0586ff6769d4c58c1", + "sha256:e99abf0bba688259a496f966211c49a514e65afa9b3073a1fcee08856e04425b", + "sha256:ee43080e75fc92bf36219926c8e6de497f9b247301bbf88c5c7593d931426679", + "sha256:f033d80bc6283092613882dfe40419c6a6a1527e04fc69350e87a9df02bbc283", + "sha256:f1088fa100bf46e7b398ffd9904f4808a0612e1d966b4aa43baa535d1b6341eb", + "sha256:f56455b0c2c7cc3b0c584815264461d07b177f903a04481dfc33e08a89f0c26b", + "sha256:f59dfe57bb1ec82ac0698ebfcdb7bcd0e99c255bd637ff613760d5f33e7c81b3", + "sha256:f7217af2e14da0856e082e96ff637f14ae45c10a5714b63c77f26d8884cf1051", + "sha256:f734e38fd8666f53da904c52a23ce517f1b07722118d750405af7e4123933511", + "sha256:f95511dd5d0e05fd9728bac4096319f80615aaef4acbecb35a990afebe953b0e", + "sha256:fdd215b7b7fd4a53994f238d0f46b7ba4ac4c0adb12452beee724ddd0743ae5d", + "sha256:feeb18a801aacb098220e2c3eea59a512362eb408d4afd0c242044c33ad6d542", + "sha256:ff30218887e62209942f91ac1be902cc80cddb86bf00fbc6783b7a43b2bea26f" ], - "markers": "python_version >= '3.6'", - "version": "==3.8.4" + "markers": "python_version >= '3.8'", + "version": "==3.9.3" }, "aiosignal": { "hashes": [ @@ -617,7 +515,7 @@ "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028" ], - "markers": "python_version >= '3.7'", + "markers": "python_version < '3.11'", "version": "==4.0.3" }, "atomicwrites": { @@ -683,61 +581,75 @@ "version": "==0.4.4" }, "coverage": { + "extras": [ + "toml" + ], "hashes": [ - "sha256:03e2a7826086b91ef345ff18742ee9fc47a6839ccd517061ef8fa1976e652ce9", - "sha256:07e6db90cd9686c767dcc593dff16c8c09f9814f5e9c51034066cad3373b914d", - "sha256:18d520c6860515a771708937d2f78f63cc47ab3b80cb78e86573b0a760161faf", - "sha256:1ebf730d2381158ecf3dfd4453fbca0613e16eaa547b4170e2450c9707665ce7", - "sha256:21b7745788866028adeb1e0eca3bf1101109e2dc58456cb49d2d9b99a8c516e6", - "sha256:26e2deacd414fc2f97dd9f7676ee3eaecd299ca751412d89f40bc01557a6b1b4", - "sha256:2c6dbb42f3ad25760010c45191e9757e7dce981cbfb90e42feef301d71540059", - "sha256:2fea046bfb455510e05be95e879f0e768d45c10c11509e20e06d8fcaa31d9e39", - "sha256:34626a7eee2a3da12af0507780bb51eb52dca0e1751fd1471d0810539cefb536", - "sha256:37d1141ad6b2466a7b53a22e08fe76994c2d35a5b6b469590424a9953155afac", - "sha256:46191097ebc381fbf89bdce207a6c107ac4ec0890d8d20f3360345ff5976155c", - "sha256:4dd8bafa458b5c7d061540f1ee9f18025a68e2d8471b3e858a9dad47c8d41903", - "sha256:4e21876082ed887baed0146fe222f861b5815455ada3b33b890f4105d806128d", - "sha256:58303469e9a272b4abdb9e302a780072c0633cdcc0165db7eec0f9e32f901e05", - "sha256:5ca5aeb4344b30d0bec47481536b8ba1181d50dbe783b0e4ad03c95dc1296684", - "sha256:68353fe7cdf91f109fc7d474461b46e7f1f14e533e911a2a2cbb8b0fc8613cf1", - "sha256:6f89d05e028d274ce4fa1a86887b071ae1755082ef94a6740238cd7a8178804f", - "sha256:7a15dc0a14008f1da3d1ebd44bdda3e357dbabdf5a0b5034d38fcde0b5c234b7", - "sha256:8bdde1177f2311ee552f47ae6e5aa7750c0e3291ca6b75f71f7ffe1f1dab3dca", - "sha256:8ce257cac556cb03be4a248d92ed36904a59a4a5ff55a994e92214cde15c5bad", - "sha256:8cf5cfcb1521dc3255d845d9dca3ff204b3229401994ef8d1984b32746bb45ca", - "sha256:8fbbdc8d55990eac1b0919ca69eb5a988a802b854488c34b8f37f3e2025fa90d", - "sha256:9548f10d8be799551eb3a9c74bbf2b4934ddb330e08a73320123c07f95cc2d92", - "sha256:96f8a1cb43ca1422f36492bebe63312d396491a9165ed3b9231e778d43a7fca4", - "sha256:9b27d894748475fa858f9597c0ee1d4829f44683f3813633aaf94b19cb5453cf", - "sha256:9baff2a45ae1f17c8078452e9e5962e518eab705e50a0aa8083733ea7d45f3a6", - "sha256:a2a8b8bcc399edb4347a5ca8b9b87e7524c0967b335fbb08a83c8421489ddee1", - "sha256:acf53bc2cf7282ab9b8ba346746afe703474004d9e566ad164c91a7a59f188a4", - "sha256:b0be84e5a6209858a1d3e8d1806c46214e867ce1b0fd32e4ea03f4bd8b2e3359", - "sha256:b31651d018b23ec463e95cf10070d0b2c548aa950a03d0b559eaa11c7e5a6fa3", - "sha256:b78e5afb39941572209f71866aa0b206c12f0109835aa0d601e41552f9b3e620", - "sha256:c76aeef1b95aff3905fb2ae2d96e319caca5b76fa41d3470b19d4e4a3a313512", - "sha256:dd035edafefee4d573140a76fdc785dc38829fe5a455c4bb12bac8c20cfc3d69", - "sha256:dd6fe30bd519694b356cbfcaca9bd5c1737cddd20778c6a581ae20dc8c04def2", - "sha256:e5f4e1edcf57ce94e5475fe09e5afa3e3145081318e5fd1a43a6b4539a97e518", - "sha256:ec6bc7fe73a938933d4178c9b23c4e0568e43e220aef9472c4f6044bfc6dd0f0", - "sha256:f1555ea6d6da108e1999b2463ea1003fe03f29213e459145e70edbaf3e004aaa", - "sha256:f5fa5803f47e095d7ad8443d28b01d48c0359484fec1b9d8606d0e3282084bc4", - "sha256:f7331dbf301b7289013175087636bbaf5b2405e57259dd2c42fdcc9fcc47325e", - "sha256:f9987b0354b06d4df0f4d3e0ec1ae76d7ce7cbca9a2f98c25041eb79eec766f1", - "sha256:fd9e830e9d8d89b20ab1e5af09b32d33e1a08ef4c4e14411e559556fd788e6b2" + "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61", + "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1", + "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7", + "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7", + "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75", + "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd", + "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35", + "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04", + "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6", + "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042", + "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166", + "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1", + "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d", + "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c", + "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66", + "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70", + "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1", + "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676", + "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630", + "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a", + "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74", + "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad", + "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19", + "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6", + "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448", + "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018", + "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218", + "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756", + "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54", + "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45", + "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628", + "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968", + "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d", + "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25", + "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60", + "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950", + "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06", + "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295", + "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b", + "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c", + "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc", + "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74", + "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1", + "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee", + "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011", + "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156", + "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766", + "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5", + "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581", + "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016", + "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c", + "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==6.3.2" + "markers": "python_version >= '3.8'", + "version": "==7.4.1" }, "decoy": { "hashes": [ - "sha256:57327a6ec24c4f4804d978f9c770cb0ff778d2ed751a45ffc61226bf10fc9f90", - "sha256:dea3634ed92eca686f71e66dfd43350adc1a96c814fb5492a08d3c251c531149" + "sha256:575bdbe81afb4c152cd99a34568a9aa4369461f79d6172c678279c5d5585befe", + "sha256:7ddcc08b8ce991f7705cee76fae9061dcb17352e0a1ca2d9a0d4a0306ebd51cd" ], "index": "pypi", - "markers": "python_version >= '3.6' and python_version < '4.0'", - "version": "==1.11.3" + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==2.1.1" }, "docopt": { "hashes": [ @@ -745,39 +657,49 @@ ], "version": "==0.6.2" }, + "exceptiongroup": { + "hashes": [ + "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", + "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + ], + "markers": "python_version < '3.11'", + "version": "==1.2.0" + }, "flake8": { "hashes": [ - "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", - "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" + "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132", + "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.9.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==7.0.0" }, "flake8-annotations": { "hashes": [ - "sha256:0d6cd2e770b5095f09689c9d84cc054c51b929c41a68969ea1beb4b825cac515", - "sha256:d10c4638231f8a50c0a597c4efce42bd7b7d85df4f620a0ddaca526138936a4f" + "sha256:af78e3216ad800d7e144745ece6df706c81b3255290cbf870e54879d495e8ade", + "sha256:ff37375e71e3b83f2a5a04d443c41e2c407de557a884f3300a7fa32f3c41cb0a" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1' and python_full_version < '4.0.0'", - "version": "==2.6.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==3.0.1" }, "flake8-docstrings": { "hashes": [ - "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde", - "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b" + "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af", + "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75" ], "index": "pypi", - "version": "==1.6.0" + "markers": "python_version >= '3.7'", + "version": "==1.7.0" }, "flake8-noqa": { "hashes": [ - "sha256:fda12487f74a639c6f2652335f7584fafcef45e084544f374687ea4ddea85b94" + "sha256:4465e16a19be433980f6f563d05540e2e54797eb11facb9feb50fed60624dc45", + "sha256:771765ab27d1efd157528379acd15131147f9ae578a72d17fb432ca197881243" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==1.1.0" + "markers": "python_version >= '3.7'", + "version": "==1.4.0" }, "frozenlist": { "hashes": [ @@ -880,121 +802,141 @@ }, "mccabe": { "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "version": "==0.6.1" + "markers": "python_version >= '3.6'", + "version": "==0.7.0" }, "multidict": { "hashes": [ - "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9", - "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8", - "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03", - "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710", - "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161", - "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664", - "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569", - "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067", - "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313", - "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706", - "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2", - "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636", - "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49", - "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93", - "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603", - "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0", - "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60", - "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4", - "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e", - "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1", - "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60", - "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951", - "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc", - "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe", - "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95", - "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d", - "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8", - "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed", - "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2", - "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775", - "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87", - "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c", - "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2", - "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98", - "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3", - "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe", - "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78", - "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660", - "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176", - "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e", - "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988", - "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c", - "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c", - "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0", - "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449", - "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f", - "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde", - "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5", - "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d", - "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac", - "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a", - "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9", - "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca", - "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11", - "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35", - "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063", - "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b", - "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982", - "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258", - "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1", - "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52", - "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480", - "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7", - "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461", - "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d", - "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc", - "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779", - "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a", - "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547", - "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0", - "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171", - "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf", - "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d", - "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba" + "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556", + "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c", + "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29", + "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b", + "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8", + "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7", + "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd", + "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40", + "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6", + "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3", + "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c", + "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9", + "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5", + "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae", + "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442", + "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9", + "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc", + "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c", + "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea", + "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5", + "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50", + "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182", + "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453", + "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e", + "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600", + "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733", + "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda", + "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241", + "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461", + "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e", + "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e", + "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b", + "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e", + "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7", + "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386", + "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd", + "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9", + "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf", + "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee", + "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5", + "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a", + "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271", + "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54", + "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4", + "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496", + "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb", + "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319", + "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3", + "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f", + "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527", + "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed", + "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604", + "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef", + "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8", + "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5", + "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5", + "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626", + "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c", + "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d", + "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c", + "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc", + "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc", + "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b", + "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38", + "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450", + "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1", + "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f", + "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3", + "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755", + "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226", + "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a", + "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046", + "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf", + "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479", + "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e", + "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1", + "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a", + "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83", + "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929", + "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93", + "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a", + "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c", + "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44", + "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89", + "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba", + "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e", + "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da", + "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24", + "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423", + "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef" ], "markers": "python_version >= '3.7'", - "version": "==6.0.4" + "version": "==6.0.5" }, "mypy": { "hashes": [ - "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", - "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", - "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", - "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", - "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", - "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", - "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", - "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", - "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", - "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", - "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", - "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", - "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", - "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", - "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", - "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", - "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", - "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", - "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", - "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", - "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", - "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", - "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", - "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" + "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6", + "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d", + "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02", + "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d", + "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3", + "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3", + "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3", + "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66", + "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259", + "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835", + "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd", + "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d", + "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8", + "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07", + "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b", + "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e", + "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6", + "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae", + "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9", + "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d", + "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a", + "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592", + "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218", + "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817", + "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4", + "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410", + "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.981" + "markers": "python_version >= '3.8'", + "version": "==1.8.0" }, "mypy-extensions": { "hashes": [ @@ -1022,35 +964,27 @@ }, "platformdirs": { "hashes": [ - "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", - "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", + "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "pluggy": { "hashes": [ - "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", - "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981", + "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be" ], "markers": "python_version >= '3.8'", - "version": "==1.3.0" - }, - "py": { - "hashes": [ - "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", - "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.11.0" + "version": "==1.4.0" }, "pycodestyle": { "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" + "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.7.0" + "markers": "python_version >= '3.8'", + "version": "==2.11.1" }, "pydocstyle": { "hashes": [ @@ -1062,37 +996,46 @@ }, "pyflakes": { "hashes": [ - "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", - "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" + "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", + "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.3.1" + "markers": "python_version >= '3.8'", + "version": "==3.2.0" }, "pytest": { "hashes": [ - "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63", - "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea" + "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", + "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==7.1.1" + "version": "==7.4.4" }, "pytest-aiohttp": { "hashes": [ - "sha256:0b9b660b146a65e1313e2083d0d2e1f63047797354af9a28d6b7c9f0726fa33d", - "sha256:c929854339637977375838703b62fef63528598bc0a9d451639eba95f4aaa44f" + "sha256:63a5360fd2f34dda4ab8e6baee4c5f5be4cd186a403cabd498fced82ac9c561e", + "sha256:880262bc5951e934463b15e3af8bb298f11f7d4d3ebac970aab425aff10a780a" ], "index": "pypi", - "version": "==0.3.0" + "markers": "python_version >= '3.7'", + "version": "==1.0.5" + }, + "pytest-asyncio": { + "hashes": [ + "sha256:2143d9d9375bf372a73260e4114541485e84fca350b0b6b92674ca56ff5f7ea2", + "sha256:b0079dfac14b60cd1ce4691fbfb1748fe939db7d0234b5aba97197d10fbe0fef" + ], + "markers": "python_version >= '3.8'", + "version": "==0.23.4" }, "pytest-cov": { "hashes": [ - "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191", - "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e" + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.10.1" + "markers": "python_version >= '3.7'", + "version": "==4.1.0" }, "pytest-watch": { "hashes": [ @@ -1113,17 +1056,17 @@ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" ], - "markers": "python_version >= '3.7'", + "markers": "python_version < '3.11'", "version": "==2.0.1" }, "typing-extensions": { "hashes": [ - "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", - "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", - "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "index": "pypi", - "version": "==3.10.0.0" + "markers": "python_version >= '3.8'", + "version": "==4.9.0" }, "watchdog": { "hashes": [ diff --git a/update-server/setup.py b/update-server/setup.py index 5137d4dcb6e..9ca418a22de 100644 --- a/update-server/setup.py +++ b/update-server/setup.py @@ -46,7 +46,7 @@ def get_version(): "A server to update software and firmware on Opentrons robots") PACKAGES = find_packages(where='.', exclude=["tests.*", "tests"]) INSTALL_REQUIRES = [ - 'aiohttp==3.8.4', + 'aiohttp==3.9.3', ] diff --git a/update-server/tests/buildroot/test_ssh_key_management.py b/update-server/tests/buildroot/test_ssh_key_management.py index eba7e69506d..cce68732529 100644 --- a/update-server/tests/buildroot/test_ssh_key_management.py +++ b/update-server/tests/buildroot/test_ssh_key_management.py @@ -10,7 +10,7 @@ @pytest.fixture def dummy_authorized_keys(tmpdir, monkeypatch): path = os.path.join(tmpdir, "authorized_keys") - ak = open(path, "w").write("") + open(path, "w").write("") @contextlib.contextmanager def ak(mode="r"): diff --git a/update-server/tests/common/name_management/test_name_synchronizer.py b/update-server/tests/common/name_management/test_name_synchronizer.py index e26cc79e07d..3b432128221 100644 --- a/update-server/tests/common/name_management/test_name_synchronizer.py +++ b/update-server/tests/common/name_management/test_name_synchronizer.py @@ -165,7 +165,9 @@ async def test_advertises_initial_name( """ decoy.when(await mock_get_pretty_hostname()).then_return("initial name") - mock_collision_subscription_context_manager = decoy.mock() + mock_collision_subscription_context_manager = decoy.mock( + name="mock_collision_subscription_context_manager" + ) decoy.when( mock_avahi_client.listen_for_collisions(matchers.Anything()) ).then_return(mock_collision_subscription_context_manager) @@ -212,7 +214,7 @@ async def test_collision_handling( # # When it does, save the function that it provided as `some_callback_func` # into `collision_callback_captor.value`. - mock_listen_context_manager = decoy.mock() + mock_listen_context_manager = decoy.mock(name="mock_listen_context_manager") collision_callback_captor = matchers.Captor() decoy.when( mock_avahi_client.listen_for_collisions(collision_callback_captor) diff --git a/usb-bridge/Pipfile b/usb-bridge/Pipfile index 717f98d0c9a..2743d3ab675 100644 --- a/usb-bridge/Pipfile +++ b/usb-bridge/Pipfile @@ -4,34 +4,34 @@ verify_ssl = true name = "pypi" [packages] -typing-extensions = "==3.10.0.0" +typing-extensions = ">=4.0.0,<5" pyserial = "==3.5" pyudev = "==0.23.2" ot3usb = {path = ".", editable = true} [dev-packages] -flake8 = "~=3.9.0" -flake8-annotations = "~=2.6.2" -flake8-docstrings = "~=1.6.0" -flake8-noqa = "~=1.1.0" -pytest = "==7.1.1" -pytest-asyncio = "~=0.16" +flake8 = "==7.0.0" +flake8-annotations = "~=3.0.1" +flake8-docstrings = "~=1.7.0" +flake8-noqa = "~=1.4.0" +pytest = "==7.4.4" +pytest-asyncio = "~=0.23.0" pytest-lazy-fixture = "==0.6.3" pytest-watch = "~=4.2.0" -pytest-cov = "==2.10.1" -pytest-aiohttp = "==0.3.0" +pytest-cov = "==4.1.0" +pytest-aiohttp = "==1.0.5" pytest-xdist = "~=2.5.0" -coverage = "==6.2" +coverage = "==7.4.1" # atomicwrites and colorama are pytest dependencies on windows, # spec'd here to force lockfile inclusion # https://github.com/pypa/pipenv/issues/4408#issuecomment-668324177 atomicwrites = {version="==1.4.0", markers="sys_platform=='win32'"} colorama = {version="==0.4.4", markers="sys_platform=='win32'"} -mypy = "==0.981" +mypy = "==1.8.0" black = "==22.3.0" -decoy = "~=1.10" -mock = "~=4.0.3" -types-mock = "==4.0.1" +decoy = "==2.1.1" +mock = "~=5.1.0" +types-mock = "~=5.1.0" [requires] python_version = "3.10" diff --git a/usb-bridge/Pipfile.lock b/usb-bridge/Pipfile.lock index 05b2c413745..6b7e9e62891 100644 --- a/usb-bridge/Pipfile.lock +++ b/usb-bridge/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d25f73de0f26592d520cc28d592ddacefa7dddb008e21a90ab17f4cd2fbebf7d" + "sha256": "0b53af0693972f92ea86d9477ff4af66c57874db5089a27727368fb15b48e534" }, "pipfile-spec": 6, "requires": { @@ -46,96 +46,96 @@ }, "typing-extensions": { "hashes": [ - "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", - "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", - "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "index": "pypi", - "version": "==3.10.0.0" + "markers": "python_version >= '3.8'", + "version": "==4.9.0" } }, "develop": { "aiohttp": { "hashes": [ - "sha256:02ab6006ec3c3463b528374c4cdce86434e7b89ad355e7bf29e2f16b46c7dd6f", - "sha256:04fa38875e53eb7e354ece1607b1d2fdee2d175ea4e4d745f6ec9f751fe20c7c", - "sha256:0b0a6a36ed7e164c6df1e18ee47afbd1990ce47cb428739d6c99aaabfaf1b3af", - "sha256:0d406b01a9f5a7e232d1b0d161b40c05275ffbcbd772dc18c1d5a570961a1ca4", - "sha256:0e49b08eafa4f5707ecfb321ab9592717a319e37938e301d462f79b4e860c32a", - "sha256:0e7ba7ff228c0d9a2cd66194e90f2bca6e0abca810b786901a569c0de082f489", - "sha256:11cb254e397a82efb1805d12561e80124928e04e9c4483587ce7390b3866d213", - "sha256:11ff168d752cb41e8492817e10fb4f85828f6a0142b9726a30c27c35a1835f01", - "sha256:176df045597e674fa950bf5ae536be85699e04cea68fa3a616cf75e413737eb5", - "sha256:219a16763dc0294842188ac8a12262b5671817042b35d45e44fd0a697d8c8361", - "sha256:22698f01ff5653fe66d16ffb7658f582a0ac084d7da1323e39fd9eab326a1f26", - "sha256:237533179d9747080bcaad4d02083ce295c0d2eab3e9e8ce103411a4312991a0", - "sha256:289ba9ae8e88d0ba16062ecf02dd730b34186ea3b1e7489046fc338bdc3361c4", - "sha256:2c59e0076ea31c08553e868cec02d22191c086f00b44610f8ab7363a11a5d9d8", - "sha256:2c9376e2b09895c8ca8b95362283365eb5c03bdc8428ade80a864160605715f1", - "sha256:3135713c5562731ee18f58d3ad1bf41e1d8883eb68b363f2ffde5b2ea4b84cc7", - "sha256:3b9c7426923bb7bd66d409da46c41e3fb40f5caf679da624439b9eba92043fa6", - "sha256:3c0266cd6f005e99f3f51e583012de2778e65af6b73860038b968a0a8888487a", - "sha256:41473de252e1797c2d2293804e389a6d6986ef37cbb4a25208de537ae32141dd", - "sha256:4831df72b053b1eed31eb00a2e1aff6896fb4485301d4ccb208cac264b648db4", - "sha256:49f0c1b3c2842556e5de35f122fc0f0b721334ceb6e78c3719693364d4af8499", - "sha256:4b4c452d0190c5a820d3f5c0f3cd8a28ace48c54053e24da9d6041bf81113183", - "sha256:4ee8caa925aebc1e64e98432d78ea8de67b2272252b0a931d2ac3bd876ad5544", - "sha256:500f1c59906cd142d452074f3811614be04819a38ae2b3239a48b82649c08821", - "sha256:5216b6082c624b55cfe79af5d538e499cd5f5b976820eac31951fb4325974501", - "sha256:54311eb54f3a0c45efb9ed0d0a8f43d1bc6060d773f6973efd90037a51cd0a3f", - "sha256:54631fb69a6e44b2ba522f7c22a6fb2667a02fd97d636048478db2fd8c4e98fe", - "sha256:565760d6812b8d78d416c3c7cfdf5362fbe0d0d25b82fed75d0d29e18d7fc30f", - "sha256:598db66eaf2e04aa0c8900a63b0101fdc5e6b8a7ddd805c56d86efb54eb66672", - "sha256:5c4fa235d534b3547184831c624c0b7c1e262cd1de847d95085ec94c16fddcd5", - "sha256:69985d50a2b6f709412d944ffb2e97d0be154ea90600b7a921f95a87d6f108a2", - "sha256:69da0f3ed3496808e8cbc5123a866c41c12c15baaaead96d256477edf168eb57", - "sha256:6c93b7c2e52061f0925c3382d5cb8980e40f91c989563d3d32ca280069fd6a87", - "sha256:70907533db712f7aa791effb38efa96f044ce3d4e850e2d7691abd759f4f0ae0", - "sha256:81b77f868814346662c96ab36b875d7814ebf82340d3284a31681085c051320f", - "sha256:82eefaf1a996060602f3cc1112d93ba8b201dbf5d8fd9611227de2003dddb3b7", - "sha256:85c3e3c9cb1d480e0b9a64c658cd66b3cfb8e721636ab8b0e746e2d79a7a9eed", - "sha256:8a22a34bc594d9d24621091d1b91511001a7eea91d6652ea495ce06e27381f70", - "sha256:8cef8710fb849d97c533f259103f09bac167a008d7131d7b2b0e3a33269185c0", - "sha256:8d44e7bf06b0c0a70a20f9100af9fcfd7f6d9d3913e37754c12d424179b4e48f", - "sha256:8d7f98fde213f74561be1d6d3fa353656197f75d4edfbb3d94c9eb9b0fc47f5d", - "sha256:8d8e4450e7fe24d86e86b23cc209e0023177b6d59502e33807b732d2deb6975f", - "sha256:8fc49a87ac269d4529da45871e2ffb6874e87779c3d0e2ccd813c0899221239d", - "sha256:90ec72d231169b4b8d6085be13023ece8fa9b1bb495e4398d847e25218e0f431", - "sha256:91c742ca59045dce7ba76cab6e223e41d2c70d79e82c284a96411f8645e2afff", - "sha256:9b05d33ff8e6b269e30a7957bd3244ffbce2a7a35a81b81c382629b80af1a8bf", - "sha256:9b05d5cbe9dafcdc733262c3a99ccf63d2f7ce02543620d2bd8db4d4f7a22f83", - "sha256:9c5857612c9813796960c00767645cb5da815af16dafb32d70c72a8390bbf690", - "sha256:a34086c5cc285be878622e0a6ab897a986a6e8bf5b67ecb377015f06ed316587", - "sha256:ab221850108a4a063c5b8a70f00dd7a1975e5a1713f87f4ab26a46e5feac5a0e", - "sha256:b796b44111f0cab6bbf66214186e44734b5baab949cb5fb56154142a92989aeb", - "sha256:b8c3a67eb87394386847d188996920f33b01b32155f0a94f36ca0e0c635bf3e3", - "sha256:bcb6532b9814ea7c5a6a3299747c49de30e84472fa72821b07f5a9818bce0f66", - "sha256:bcc0ea8d5b74a41b621ad4a13d96c36079c81628ccc0b30cfb1603e3dfa3a014", - "sha256:bea94403a21eb94c93386d559bce297381609153e418a3ffc7d6bf772f59cc35", - "sha256:bff7e2811814fa2271be95ab6e84c9436d027a0e59665de60edf44e529a42c1f", - "sha256:c72444d17777865734aa1a4d167794c34b63e5883abb90356a0364a28904e6c0", - "sha256:c7b5d5d64e2a14e35a9240b33b89389e0035e6de8dbb7ffa50d10d8b65c57449", - "sha256:c7e939f1ae428a86e4abbb9a7c4732bf4706048818dfd979e5e2839ce0159f23", - "sha256:c88a15f272a0ad3d7773cf3a37cc7b7d077cbfc8e331675cf1346e849d97a4e5", - "sha256:c9110c06eaaac7e1f5562caf481f18ccf8f6fdf4c3323feab28a93d34cc646bd", - "sha256:ca7ca5abfbfe8d39e653870fbe8d7710be7a857f8a8386fc9de1aae2e02ce7e4", - "sha256:cae4c0c2ca800c793cae07ef3d40794625471040a87e1ba392039639ad61ab5b", - "sha256:cdefe289681507187e375a5064c7599f52c40343a8701761c802c1853a504558", - "sha256:cf2a0ac0615842b849f40c4d7f304986a242f1e68286dbf3bd7a835e4f83acfd", - "sha256:cfeadf42840c1e870dc2042a232a8748e75a36b52d78968cda6736de55582766", - "sha256:d737e69d193dac7296365a6dcb73bbbf53bb760ab25a3727716bbd42022e8d7a", - "sha256:d7481f581251bb5558ba9f635db70908819caa221fc79ee52a7f58392778c636", - "sha256:df9cf74b9bc03d586fc53ba470828d7b77ce51b0582d1d0b5b2fb673c0baa32d", - "sha256:e1f80197f8b0b846a8d5cf7b7ec6084493950d0882cc5537fb7b96a69e3c8590", - "sha256:ecca113f19d5e74048c001934045a2b9368d77b0b17691d905af18bd1c21275e", - "sha256:ee2527134f95e106cc1653e9ac78846f3a2ec1004cf20ef4e02038035a74544d", - "sha256:f27fdaadce22f2ef950fc10dcdf8048407c3b42b73779e48a4e76b3c35bca26c", - "sha256:f694dc8a6a3112059258a725a4ebe9acac5fe62f11c77ac4dcf896edfa78ca28", - "sha256:f800164276eec54e0af5c99feb9494c295118fc10a11b997bbb1348ba1a52065", - "sha256:ffcd828e37dc219a72c9012ec44ad2e7e3066bec6ff3aaa19e7d435dbf4032ca" + "sha256:017a21b0df49039c8f46ca0971b3a7fdc1f56741ab1240cb90ca408049766168", + "sha256:039df344b45ae0b34ac885ab5b53940b174530d4dd8a14ed8b0e2155b9dddccb", + "sha256:055ce4f74b82551678291473f66dc9fb9048a50d8324278751926ff0ae7715e5", + "sha256:06a9b2c8837d9a94fae16c6223acc14b4dfdff216ab9b7202e07a9a09541168f", + "sha256:07b837ef0d2f252f96009e9b8435ec1fef68ef8b1461933253d318748ec1acdc", + "sha256:0ed621426d961df79aa3b963ac7af0d40392956ffa9be022024cd16297b30c8c", + "sha256:0fa43c32d1643f518491d9d3a730f85f5bbaedcbd7fbcae27435bb8b7a061b29", + "sha256:1f5a71d25cd8106eab05f8704cd9167b6e5187bcdf8f090a66c6d88b634802b4", + "sha256:1f5cd333fcf7590a18334c90f8c9147c837a6ec8a178e88d90a9b96ea03194cc", + "sha256:27468897f628c627230dba07ec65dc8d0db566923c48f29e084ce382119802bc", + "sha256:298abd678033b8571995650ccee753d9458dfa0377be4dba91e4491da3f2be63", + "sha256:2c895a656dd7e061b2fd6bb77d971cc38f2afc277229ce7dd3552de8313a483e", + "sha256:361a1026c9dd4aba0109e4040e2aecf9884f5cfe1b1b1bd3d09419c205e2e53d", + "sha256:363afe77cfcbe3a36353d8ea133e904b108feea505aa4792dad6585a8192c55a", + "sha256:38a19bc3b686ad55804ae931012f78f7a534cce165d089a2059f658f6c91fa60", + "sha256:38f307b41e0bea3294a9a2a87833191e4bcf89bb0365e83a8be3a58b31fb7f38", + "sha256:3e59c23c52765951b69ec45ddbbc9403a8761ee6f57253250c6e1536cacc758b", + "sha256:4b4af9f25b49a7be47c0972139e59ec0e8285c371049df1a63b6ca81fdd216a2", + "sha256:504b6981675ace64c28bf4a05a508af5cde526e36492c98916127f5a02354d53", + "sha256:50fca156d718f8ced687a373f9e140c1bb765ca16e3d6f4fe116e3df7c05b2c5", + "sha256:522a11c934ea660ff8953eda090dcd2154d367dec1ae3c540aff9f8a5c109ab4", + "sha256:52df73f14ed99cee84865b95a3d9e044f226320a87af208f068ecc33e0c35b96", + "sha256:595f105710293e76b9dc09f52e0dd896bd064a79346234b521f6b968ffdd8e58", + "sha256:59c26c95975f26e662ca78fdf543d4eeaef70e533a672b4113dd888bd2423caa", + "sha256:5bce0dc147ca85caa5d33debc4f4d65e8e8b5c97c7f9f660f215fa74fc49a321", + "sha256:5eafe2c065df5401ba06821b9a054d9cb2848867f3c59801b5d07a0be3a380ae", + "sha256:5ed3e046ea7b14938112ccd53d91c1539af3e6679b222f9469981e3dac7ba1ce", + "sha256:5fe9ce6c09668063b8447f85d43b8d1c4e5d3d7e92c63173e6180b2ac5d46dd8", + "sha256:648056db9a9fa565d3fa851880f99f45e3f9a771dd3ff3bb0c048ea83fb28194", + "sha256:69361bfdca5468c0488d7017b9b1e5ce769d40b46a9f4a2eed26b78619e9396c", + "sha256:6b0e029353361f1746bac2e4cc19b32f972ec03f0f943b390c4ab3371840aabf", + "sha256:6b88f9386ff1ad91ace19d2a1c0225896e28815ee09fc6a8932fded8cda97c3d", + "sha256:770d015888c2a598b377bd2f663adfd947d78c0124cfe7b959e1ef39f5b13869", + "sha256:7943c414d3a8d9235f5f15c22ace69787c140c80b718dcd57caaade95f7cd93b", + "sha256:7cf5c9458e1e90e3c390c2639f1017a0379a99a94fdfad3a1fd966a2874bba52", + "sha256:7f46acd6a194287b7e41e87957bfe2ad1ad88318d447caf5b090012f2c5bb528", + "sha256:82e6aa28dd46374f72093eda8bcd142f7771ee1eb9d1e223ff0fa7177a96b4a5", + "sha256:835a55b7ca49468aaaac0b217092dfdff370e6c215c9224c52f30daaa735c1c1", + "sha256:84871a243359bb42c12728f04d181a389718710129b36b6aad0fc4655a7647d4", + "sha256:8aacb477dc26797ee089721536a292a664846489c49d3ef9725f992449eda5a8", + "sha256:8e2c45c208c62e955e8256949eb225bd8b66a4c9b6865729a786f2aa79b72e9d", + "sha256:90842933e5d1ff760fae6caca4b2b3edba53ba8f4b71e95dacf2818a2aca06f7", + "sha256:938a9653e1e0c592053f815f7028e41a3062e902095e5a7dc84617c87267ebd5", + "sha256:939677b61f9d72a4fa2a042a5eee2a99a24001a67c13da113b2e30396567db54", + "sha256:9d3c9b50f19704552f23b4eaea1fc082fdd82c63429a6506446cbd8737823da3", + "sha256:a6fe5571784af92b6bc2fda8d1925cccdf24642d49546d3144948a6a1ed58ca5", + "sha256:a78ed8a53a1221393d9637c01870248a6f4ea5b214a59a92a36f18151739452c", + "sha256:ab40e6251c3873d86ea9b30a1ac6d7478c09277b32e14745d0d3c6e76e3c7e29", + "sha256:abf151955990d23f84205286938796c55ff11bbfb4ccfada8c9c83ae6b3c89a3", + "sha256:acef0899fea7492145d2bbaaaec7b345c87753168589cc7faf0afec9afe9b747", + "sha256:b40670ec7e2156d8e57f70aec34a7216407848dfe6c693ef131ddf6e76feb672", + "sha256:b791a3143681a520c0a17e26ae7465f1b6f99461a28019d1a2f425236e6eedb5", + "sha256:b955ed993491f1a5da7f92e98d5dad3c1e14dc175f74517c4e610b1f2456fb11", + "sha256:ba39e9c8627edc56544c8628cc180d88605df3892beeb2b94c9bc857774848ca", + "sha256:bca77a198bb6e69795ef2f09a5f4c12758487f83f33d63acde5f0d4919815768", + "sha256:c3452ea726c76e92f3b9fae4b34a151981a9ec0a4847a627c43d71a15ac32aa6", + "sha256:c46956ed82961e31557b6857a5ca153c67e5476972e5f7190015018760938da2", + "sha256:c7c8b816c2b5af5c8a436df44ca08258fc1a13b449393a91484225fcb7545533", + "sha256:cd73265a9e5ea618014802ab01babf1940cecb90c9762d8b9e7d2cc1e1969ec6", + "sha256:dad46e6f620574b3b4801c68255492e0159d1712271cc99d8bdf35f2043ec266", + "sha256:dc9b311743a78043b26ffaeeb9715dc360335e5517832f5a8e339f8a43581e4d", + "sha256:df822ee7feaaeffb99c1a9e5e608800bd8eda6e5f18f5cfb0dc7eeb2eaa6bbec", + "sha256:e083c285857b78ee21a96ba1eb1b5339733c3563f72980728ca2b08b53826ca5", + "sha256:e5e46b578c0e9db71d04c4b506a2121c0cb371dd89af17a0586ff6769d4c58c1", + "sha256:e99abf0bba688259a496f966211c49a514e65afa9b3073a1fcee08856e04425b", + "sha256:ee43080e75fc92bf36219926c8e6de497f9b247301bbf88c5c7593d931426679", + "sha256:f033d80bc6283092613882dfe40419c6a6a1527e04fc69350e87a9df02bbc283", + "sha256:f1088fa100bf46e7b398ffd9904f4808a0612e1d966b4aa43baa535d1b6341eb", + "sha256:f56455b0c2c7cc3b0c584815264461d07b177f903a04481dfc33e08a89f0c26b", + "sha256:f59dfe57bb1ec82ac0698ebfcdb7bcd0e99c255bd637ff613760d5f33e7c81b3", + "sha256:f7217af2e14da0856e082e96ff637f14ae45c10a5714b63c77f26d8884cf1051", + "sha256:f734e38fd8666f53da904c52a23ce517f1b07722118d750405af7e4123933511", + "sha256:f95511dd5d0e05fd9728bac4096319f80615aaef4acbecb35a990afebe953b0e", + "sha256:fdd215b7b7fd4a53994f238d0f46b7ba4ac4c0adb12452beee724ddd0743ae5d", + "sha256:feeb18a801aacb098220e2c3eea59a512362eb408d4afd0c242044c33ad6d542", + "sha256:ff30218887e62209942f91ac1be902cc80cddb86bf00fbc6783b7a43b2bea26f" ], "markers": "python_version >= '3.8'", - "version": "==3.9.1" + "version": "==3.9.3" }, "aiosignal": { "hashes": [ @@ -216,67 +216,75 @@ "version": "==0.4.4" }, "coverage": { - "hashes": [ - "sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0", - "sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd", - "sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884", - "sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48", - "sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76", - "sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0", - "sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64", - "sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685", - "sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47", - "sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d", - "sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840", - "sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f", - "sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971", - "sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c", - "sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a", - "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de", - "sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17", - "sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4", - "sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521", - "sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57", - "sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b", - "sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282", - "sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644", - "sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475", - "sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d", - "sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da", - "sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953", - "sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2", - "sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e", - "sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c", - "sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc", - "sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64", - "sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74", - "sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617", - "sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3", - "sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d", - "sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa", - "sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739", - "sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8", - "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8", - "sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781", - "sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58", - "sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9", - "sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c", - "sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd", - "sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e", - "sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49" + "extras": [ + "toml" + ], + "hashes": [ + "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61", + "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1", + "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7", + "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7", + "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75", + "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd", + "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35", + "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04", + "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6", + "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042", + "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166", + "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1", + "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d", + "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c", + "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66", + "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70", + "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1", + "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676", + "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630", + "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a", + "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74", + "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad", + "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19", + "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6", + "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448", + "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018", + "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218", + "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756", + "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54", + "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45", + "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628", + "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968", + "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d", + "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25", + "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60", + "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950", + "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06", + "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295", + "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b", + "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c", + "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc", + "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74", + "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1", + "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee", + "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011", + "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156", + "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766", + "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5", + "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581", + "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016", + "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c", + "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==6.2" + "markers": "python_version >= '3.8'", + "version": "==7.4.1" }, "decoy": { "hashes": [ - "sha256:57327a6ec24c4f4804d978f9c770cb0ff778d2ed751a45ffc61226bf10fc9f90", - "sha256:dea3634ed92eca686f71e66dfd43350adc1a96c814fb5492a08d3c251c531149" + "sha256:575bdbe81afb4c152cd99a34568a9aa4369461f79d6172c678279c5d5585befe", + "sha256:7ddcc08b8ce991f7705cee76fae9061dcb17352e0a1ca2d9a0d4a0306ebd51cd" ], "index": "pypi", - "markers": "python_version >= '3.6' and python_version < '4.0'", - "version": "==1.11.3" + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==2.1.1" }, "docopt": { "hashes": [ @@ -284,6 +292,14 @@ ], "version": "==0.6.2" }, + "exceptiongroup": { + "hashes": [ + "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", + "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + ], + "markers": "python_version < '3.11'", + "version": "==1.2.0" + }, "execnet": { "hashes": [ "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41", @@ -294,37 +310,39 @@ }, "flake8": { "hashes": [ - "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b", - "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" + "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132", + "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.9.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==7.0.0" }, "flake8-annotations": { "hashes": [ - "sha256:0d6cd2e770b5095f09689c9d84cc054c51b929c41a68969ea1beb4b825cac515", - "sha256:d10c4638231f8a50c0a597c4efce42bd7b7d85df4f620a0ddaca526138936a4f" + "sha256:af78e3216ad800d7e144745ece6df706c81b3255290cbf870e54879d495e8ade", + "sha256:ff37375e71e3b83f2a5a04d443c41e2c407de557a884f3300a7fa32f3c41cb0a" ], "index": "pypi", - "markers": "python_full_version >= '3.6.1' and python_full_version < '4.0.0'", - "version": "==2.6.2" + "markers": "python_full_version >= '3.8.1'", + "version": "==3.0.1" }, "flake8-docstrings": { "hashes": [ - "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde", - "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b" + "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af", + "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75" ], "index": "pypi", - "version": "==1.6.0" + "markers": "python_version >= '3.7'", + "version": "==1.7.0" }, "flake8-noqa": { "hashes": [ - "sha256:fda12487f74a639c6f2652335f7584fafcef45e084544f374687ea4ddea85b94" + "sha256:4465e16a19be433980f6f563d05540e2e54797eb11facb9feb50fed60624dc45", + "sha256:771765ab27d1efd157528379acd15131147f9ae578a72d17fb432ca197881243" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==1.1.0" + "markers": "python_version >= '3.7'", + "version": "==1.4.0" }, "frozenlist": { "hashes": [ @@ -427,130 +445,150 @@ }, "mccabe": { "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "version": "==0.6.1" + "markers": "python_version >= '3.6'", + "version": "==0.7.0" }, "mock": { "hashes": [ - "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62", - "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc" + "sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744", + "sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d" ], "index": "pypi", "markers": "python_version >= '3.6'", - "version": "==4.0.3" + "version": "==5.1.0" }, "multidict": { "hashes": [ - "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9", - "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8", - "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03", - "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710", - "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161", - "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664", - "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569", - "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067", - "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313", - "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706", - "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2", - "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636", - "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49", - "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93", - "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603", - "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0", - "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60", - "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4", - "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e", - "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1", - "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60", - "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951", - "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc", - "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe", - "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95", - "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d", - "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8", - "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed", - "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2", - "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775", - "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87", - "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c", - "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2", - "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98", - "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3", - "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe", - "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78", - "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660", - "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176", - "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e", - "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988", - "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c", - "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c", - "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0", - "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449", - "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f", - "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde", - "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5", - "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d", - "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac", - "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a", - "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9", - "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca", - "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11", - "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35", - "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063", - "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b", - "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982", - "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258", - "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1", - "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52", - "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480", - "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7", - "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461", - "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d", - "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc", - "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779", - "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a", - "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547", - "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0", - "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171", - "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf", - "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d", - "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba" + "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556", + "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c", + "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29", + "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b", + "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8", + "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7", + "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd", + "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40", + "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6", + "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3", + "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c", + "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9", + "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5", + "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae", + "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442", + "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9", + "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc", + "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c", + "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea", + "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5", + "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50", + "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182", + "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453", + "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e", + "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600", + "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733", + "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda", + "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241", + "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461", + "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e", + "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e", + "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b", + "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e", + "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7", + "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386", + "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd", + "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9", + "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf", + "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee", + "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5", + "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a", + "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271", + "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54", + "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4", + "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496", + "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb", + "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319", + "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3", + "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f", + "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527", + "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed", + "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604", + "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef", + "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8", + "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5", + "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5", + "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626", + "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c", + "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d", + "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c", + "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc", + "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc", + "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b", + "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38", + "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450", + "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1", + "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f", + "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3", + "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755", + "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226", + "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a", + "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046", + "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf", + "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479", + "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e", + "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1", + "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a", + "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83", + "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929", + "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93", + "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a", + "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c", + "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44", + "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89", + "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba", + "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e", + "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da", + "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24", + "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423", + "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef" ], "markers": "python_version >= '3.7'", - "version": "==6.0.4" + "version": "==6.0.5" }, "mypy": { "hashes": [ - "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", - "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", - "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", - "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", - "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", - "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", - "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", - "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", - "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", - "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", - "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", - "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", - "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", - "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", - "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", - "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", - "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", - "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", - "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", - "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", - "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", - "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", - "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", - "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" + "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6", + "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d", + "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02", + "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d", + "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3", + "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3", + "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3", + "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66", + "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259", + "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835", + "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd", + "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d", + "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8", + "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07", + "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b", + "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e", + "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6", + "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae", + "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9", + "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d", + "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a", + "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592", + "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218", + "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817", + "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4", + "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410", + "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.981" + "markers": "python_version >= '3.8'", + "version": "==1.8.0" }, "mypy-extensions": { "hashes": [ @@ -578,19 +616,19 @@ }, "platformdirs": { "hashes": [ - "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", - "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", + "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "pluggy": { "hashes": [ - "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", - "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981", + "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be" ], "markers": "python_version >= '3.8'", - "version": "==1.3.0" + "version": "==1.4.0" }, "py": { "hashes": [ @@ -602,11 +640,11 @@ }, "pycodestyle": { "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" + "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.7.0" + "markers": "python_version >= '3.8'", + "version": "==2.11.1" }, "pydocstyle": { "hashes": [ @@ -618,46 +656,47 @@ }, "pyflakes": { "hashes": [ - "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3", - "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db" + "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", + "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.3.1" + "markers": "python_version >= '3.8'", + "version": "==3.2.0" }, "pytest": { "hashes": [ - "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63", - "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea" + "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", + "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==7.1.1" + "version": "==7.4.4" }, "pytest-aiohttp": { "hashes": [ - "sha256:0b9b660b146a65e1313e2083d0d2e1f63047797354af9a28d6b7c9f0726fa33d", - "sha256:c929854339637977375838703b62fef63528598bc0a9d451639eba95f4aaa44f" + "sha256:63a5360fd2f34dda4ab8e6baee4c5f5be4cd186a403cabd498fced82ac9c561e", + "sha256:880262bc5951e934463b15e3af8bb298f11f7d4d3ebac970aab425aff10a780a" ], "index": "pypi", - "version": "==0.3.0" + "markers": "python_version >= '3.7'", + "version": "==1.0.5" }, "pytest-asyncio": { "hashes": [ - "sha256:37a9d912e8338ee7b4a3e917381d1c95bfc8682048cb0fbc35baba316ec1faba", - "sha256:af313ce900a62fbe2b1aed18e37ad757f1ef9940c6b6a88e2954de38d6b1fb9f" + "sha256:2143d9d9375bf372a73260e4114541485e84fca350b0b6b92674ca56ff5f7ea2", + "sha256:b0079dfac14b60cd1ce4691fbfb1748fe939db7d0234b5aba97197d10fbe0fef" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==0.23.3" + "version": "==0.23.4" }, "pytest-cov": { "hashes": [ - "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191", - "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e" + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.10.1" + "markers": "python_version >= '3.7'", + "version": "==4.1.0" }, "pytest-forked": { "hashes": [ @@ -703,25 +742,26 @@ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" ], - "markers": "python_version >= '3.7'", + "markers": "python_version < '3.11'", "version": "==2.0.1" }, "types-mock": { "hashes": [ - "sha256:1a470543be8de673e2ea14739622de3bfb8c9b10429f50338ba9ca1e868c15e9", - "sha256:1ad09970f4f5ec45a138ab1e88d032f010e851bccef7765b34737ed390bbc5c8" + "sha256:13ca379d5710ccb3f18f69ade5b08881874cb83383d8fb49b1d4dac9d5c5d090", + "sha256:3d116955495935b0bcba14954b38d97e507cd43eca3e3700fc1b8e4f5c6bf2c7" ], "index": "pypi", - "version": "==4.0.1" + "markers": "python_version >= '3.8'", + "version": "==5.1.0.20240106" }, "typing-extensions": { "hashes": [ - "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", - "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", - "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "index": "pypi", - "version": "==3.10.0.0" + "markers": "python_version >= '3.8'", + "version": "==4.9.0" }, "watchdog": { "hashes": [ diff --git a/usb-bridge/ot3usb/listener.py b/usb-bridge/ot3usb/listener.py index 7e8b18621ca..1d45d56e794 100644 --- a/usb-bridge/ot3usb/listener.py +++ b/usb-bridge/ot3usb/listener.py @@ -3,7 +3,7 @@ import logging import select from typing import Optional, List, Any -import serial # type: ignore[import] +import serial # type: ignore[import-untyped] from . import usb_config, usb_monitor, tcp_conn diff --git a/usb-bridge/ot3usb/serial_thread.py b/usb-bridge/ot3usb/serial_thread.py index 09aff9c2e51..67cf74816af 100644 --- a/usb-bridge/ot3usb/serial_thread.py +++ b/usb-bridge/ot3usb/serial_thread.py @@ -1,7 +1,7 @@ """Worker thread to write serial data.""" from typing import Tuple from typing_extensions import TypeAlias -import serial # type: ignore[import] +import serial # type: ignore[import-untyped] import threading from queue import Queue import time diff --git a/usb-bridge/ot3usb/usb_config.py b/usb-bridge/ot3usb/usb_config.py index 0ea109ecff5..6cc6031f632 100644 --- a/usb-bridge/ot3usb/usb_config.py +++ b/usb-bridge/ot3usb/usb_config.py @@ -19,7 +19,7 @@ import logging import os import time -import serial # type: ignore[import] +import serial # type: ignore[import-untyped] import typing LOG = logging.getLogger(__name__) diff --git a/usb-bridge/ot3usb/usb_monitor.py b/usb-bridge/ot3usb/usb_monitor.py index ae548951628..0a991e1e76e 100644 --- a/usb-bridge/ot3usb/usb_monitor.py +++ b/usb-bridge/ot3usb/usb_monitor.py @@ -23,7 +23,7 @@ reading new data. """ -import pyudev # type: ignore[import] +import pyudev # type: ignore[import-untyped] import logging import os diff --git a/usb-bridge/tests/test_listener.py b/usb-bridge/tests/test_listener.py index 09575baf85d..4dca5661618 100644 --- a/usb-bridge/tests/test_listener.py +++ b/usb-bridge/tests/test_listener.py @@ -4,7 +4,7 @@ import mock import select -import serial # type: ignore[import] +import serial # type: ignore[import-untyped] from queue import Queue from ot3usb import usb_config, tcp_conn, usb_monitor, listener diff --git a/usb-bridge/tests/test_tcp_conn.py b/usb-bridge/tests/test_tcp_conn.py index 8a7bbf7bfda..fa92e2b3a7e 100644 --- a/usb-bridge/tests/test_tcp_conn.py +++ b/usb-bridge/tests/test_tcp_conn.py @@ -3,6 +3,7 @@ import pytest import mock import socket +from typing import cast from ot3usb import default_config from ot3usb.tcp_conn import TCPConnection @@ -71,7 +72,7 @@ def test_connect( assert subject.connected() # Now test error case - mock_sock = mock.MagicMock(socket.socket) + mock_sock = cast(mock.MagicMock, socket.socket) mock_sock.side_effect = Exception("Error!") monkeypatch.setattr("socket.socket", mock_sock) diff --git a/usb-bridge/tests/test_usb_monitor.py b/usb-bridge/tests/test_usb_monitor.py index 88901649ac7..db85e01efb5 100644 --- a/usb-bridge/tests/test_usb_monitor.py +++ b/usb-bridge/tests/test_usb_monitor.py @@ -4,7 +4,7 @@ import mock from pathlib import Path import os -import pyudev # type: ignore[import] +import pyudev # type: ignore[import-untyped] from ot3usb import usb_monitor TEST_PHY_NAME = "usbphy123" From 674c32aabcdad59bff35223395e525fe6dd799d1 Mon Sep 17 00:00:00 2001 From: Max Marrone Date: Wed, 7 Feb 2024 17:18:54 -0500 Subject: [PATCH 07/10] fix(robot-server): Fix protocols being stored in the wrong directory (#14442) --- .../fastapi_dependencies.py | 36 +++++++++++++-- .../robot_server/persistence/__init__.py | 2 + .../persistence/_fastapi_dependencies.py | 26 ++++++++++- .../service/legacy/routers/settings.py | 46 +++++++++++++------ .../http_api/persistence/test_reset.py | 8 +--- .../http_api/protocols/test_persistence.py | 4 +- .../test_deck_configuration.tavern.yaml | 4 ++ .../service/legacy/routers/test_settings.py | 23 ++++++---- 8 files changed, 111 insertions(+), 38 deletions(-) diff --git a/robot-server/robot_server/deck_configuration/fastapi_dependencies.py b/robot-server/robot_server/deck_configuration/fastapi_dependencies.py index ecf7dd0037e..16f87840b90 100644 --- a/robot-server/robot_server/deck_configuration/fastapi_dependencies.py +++ b/robot-server/robot_server/deck_configuration/fastapi_dependencies.py @@ -2,6 +2,7 @@ from pathlib import Path +from typing import Optional import fastapi @@ -14,7 +15,10 @@ from robot_server.deck_configuration.store import DeckConfigurationStore from robot_server.hardware import get_deck_type -from robot_server.persistence import get_active_persistence_directory +from robot_server.persistence import ( + get_active_persistence_directory, + get_active_persistence_directory_failsafe, +) # This needs to be kept in sync with opentrons.execute, which reads this file. @@ -30,9 +34,33 @@ async def get_deck_configuration_store( persistence_directory: Path = fastapi.Depends(get_active_persistence_directory), ) -> DeckConfigurationStore: """Return the server's singleton `DeckConfigurationStore`.""" - # It's important that this dependency doesn't do anything that might fail, like reading - # files. This is a dependency of the POST /settings/reset endpoint, which should always - # be available. + deck_configuration_store = _accessor.get_from(app_state) + if deck_configuration_store is None: + path = persistence_directory / _DECK_CONFIGURATION_FILE_NAME + # If this initialization becomes async, we will need to protect it with a lock, + # to protect against the bug described in https://github.com/Opentrons/opentrons/pull/11927. + deck_configuration_store = DeckConfigurationStore(deck_type, path) + _accessor.set_on(app_state, deck_configuration_store) + return deck_configuration_store + + +# TODO(mm, 2024-02-07): Resolve the duplication between these two implementations. +async def get_deck_configuration_store_failsafe( + app_state: AppState = fastapi.Depends(get_app_state), + deck_type: DeckType = fastapi.Depends(get_deck_type), + persistence_directory: Optional[Path] = fastapi.Depends( + get_active_persistence_directory_failsafe + ), +) -> Optional[DeckConfigurationStore]: + """Return the server's singleton `DeckConfigurationStore`. + + This is like `get_deck_configuration_store()`, except this returns `None` if the + store has failed to initialize or is not yet ready, instead of raising an exception + or blocking. This is important because this is a dependency of the + `POST /settings/reset` endpoint, which should always be available. + """ + if persistence_directory is None: + return None deck_configuration_store = _accessor.get_from(app_state) if deck_configuration_store is None: path = persistence_directory / _DECK_CONFIGURATION_FILE_NAME diff --git a/robot-server/robot_server/persistence/__init__.py b/robot-server/robot_server/persistence/__init__.py index 12c11b5ed93..604c331f1c5 100644 --- a/robot-server/robot_server/persistence/__init__.py +++ b/robot-server/robot_server/persistence/__init__.py @@ -7,6 +7,7 @@ clean_up_persistence, get_sql_engine, get_active_persistence_directory, + get_active_persistence_directory_failsafe, get_persistence_resetter, ) from ._persistence_directory import PersistenceResetter @@ -35,6 +36,7 @@ # dependencies and types for use by FastAPI endpoint functions "get_sql_engine", "get_active_persistence_directory", + "get_active_persistence_directory_failsafe", "PersistenceResetter", "get_persistence_resetter", ] diff --git a/robot-server/robot_server/persistence/_fastapi_dependencies.py b/robot-server/robot_server/persistence/_fastapi_dependencies.py index 66b6633d9d1..7a2e32a1575 100644 --- a/robot-server/robot_server/persistence/_fastapi_dependencies.py +++ b/robot-server/robot_server/persistence/_fastapi_dependencies.py @@ -220,7 +220,9 @@ async def get_active_persistence_directory( If this is called before that initialization completes, this will raise an appropriate HTTP-facing error to indicate that the server is busy. """ - initialize_task = _root_persistence_directory_init_task_accessor.get_from(app_state) + initialize_task = _active_persistence_directory_init_task_accessor.get_from( + app_state + ) assert ( initialize_task is not None ), "Forgot to start persistence directory initialization as part of server startup?" @@ -244,6 +246,28 @@ async def get_active_persistence_directory( ) from exception +async def get_active_persistence_directory_failsafe( + app_state: AppState = Depends(get_app_state), +) -> Optional[Path]: + """Return the path to the server's persistence directory. + + This is the same as `get_active_persistence_directory()`, except this will return + `None` if the active persistence directory has failed to initialize or is not yet + ready, instead of raising an exception or blocking. + """ + initialize_task = _active_persistence_directory_init_task_accessor.get_from( + app_state + ) + assert ( + initialize_task is not None + ), "Forgot to start persistence directory initialization as part of server startup?" + + try: + return initialize_task.result() + except Exception: + return None + + async def _get_persistence_directory_root( app_state: AppState = Depends(get_app_state), ) -> Path: diff --git a/robot-server/robot_server/service/legacy/routers/settings.py b/robot-server/robot_server/service/legacy/routers/settings.py index d8681d51ece..b16bb28c085 100644 --- a/robot-server/robot_server/service/legacy/routers/settings.py +++ b/robot-server/robot_server/service/legacy/routers/settings.py @@ -1,6 +1,6 @@ from dataclasses import asdict import logging -from typing import Dict, cast, Union, Any +from typing import cast, Any, Dict, List, Optional, Union from starlette import status from fastapi import APIRouter, Depends @@ -25,7 +25,7 @@ get_opentrons_path, ) from robot_server.deck_configuration.fastapi_dependencies import ( - get_deck_configuration_store, + get_deck_configuration_store_failsafe, ) from robot_server.deck_configuration.store import DeckConfigurationStore @@ -206,13 +206,14 @@ async def get_settings_reset_options( description="Perform a factory reset of some robot data", responses={ status.HTTP_403_FORBIDDEN: {"model": LegacyErrorResponse}, + status.HTTP_503_SERVICE_UNAVAILABLE: {"model": LegacyErrorResponse}, }, ) async def post_settings_reset_options( factory_reset_commands: Dict[reset_util.ResetOptionId, bool], persistence_resetter: PersistenceResetter = Depends(get_persistence_resetter), - deck_configuration_store: DeckConfigurationStore = Depends( - get_deck_configuration_store + deck_configuration_store: Optional[DeckConfigurationStore] = Depends( + get_deck_configuration_store_failsafe ), robot_type: RobotTypeEnum = Depends(get_robot_type_enum), ) -> V1BasicResponse: @@ -230,6 +231,9 @@ async def post_settings_reset_options( ).as_error(status.HTTP_403_FORBIDDEN) options = set(k for k, v in factory_reset_commands.items() if v) + + failed_commands: List[reset_util.ResetOptionId] = [] + reset_util.reset(options, robot_type) if factory_reset_commands.get(reset_util.ResetOptionId.runs_history, False): @@ -239,16 +243,30 @@ async def post_settings_reset_options( await reset_odd.mark_odd_for_reset_next_boot() if factory_reset_commands.get(reset_util.ResetOptionId.deck_configuration, False): - await deck_configuration_store.delete() - - # TODO (tz, 5-24-22): The order of a set is undefined because set's aren't ordered. - # The message returned to the client will be printed in the wrong order. - message = ( - "Options '{}' were reset".format(", ".join(o.name for o in options)) - if options - else "Nothing to do" - ) - return V1BasicResponse(message=message) + if deck_configuration_store: + await deck_configuration_store.delete() + else: + failed_commands.append(reset_util.ResetOptionId.deck_configuration) + + if failed_commands: + raise LegacyErrorResponse( + message=f"Some options could not be reset: {failed_commands}", + errorCode=ErrorCodes.GENERAL_ERROR.value.code, + ).as_error( + # 503 because this condition can happen if someone tries to reset something + # before our persistence layer has fully initialized. It will start working + # after initialization finishes. + status.HTTP_503_SERVICE_UNAVAILABLE + ) + else: + # TODO (tz, 5-24-22): The order of a set is undefined because set's aren't ordered. + # The message returned to the client will be printed in the wrong order. + message = ( + "Options '{}' were reset".format(", ".join(o.name for o in options)) + if options + else "Nothing to do" + ) + return V1BasicResponse(message=message) @router.get( diff --git a/robot-server/tests/integration/http_api/persistence/test_reset.py b/robot-server/tests/integration/http_api/persistence/test_reset.py index 2106b3d8acf..1eba97c5e46 100644 --- a/robot-server/tests/integration/http_api/persistence/test_reset.py +++ b/robot-server/tests/integration/http_api/persistence/test_reset.py @@ -1,5 +1,4 @@ import asyncio -import os import secrets from pathlib import Path from shutil import copytree @@ -41,8 +40,8 @@ async def _assert_reset_was_successful( all_files_and_directories = set(persistence_directory.glob("**/*")) expected_files_and_directories = { persistence_directory / "robot_server.db", - persistence_directory / "protocols", persistence_directory / "3", + persistence_directory / "3" / "protocols", persistence_directory / "3" / "robot_server.db", } assert all_files_and_directories == expected_files_and_directories @@ -109,11 +108,6 @@ async def test_upload_protocols_and_reset_persistence_dir() -> None: assert len(result.json()["data"]) == 2 - # TODO(mm, 2022-09-08): This can erroneously pass if something other than - # our software creates a file in this directory, like if macOS creates - # .DS_Store. - assert os.listdir(f"{server.persistence_directory}/protocols/") - # Restart to enact the reset. server.stop() assert await robot_client.wait_until_dead(), "Dev Robot did not stop." diff --git a/robot-server/tests/integration/http_api/protocols/test_persistence.py b/robot-server/tests/integration/http_api/protocols/test_persistence.py index 2c6c62bf930..d7957188222 100644 --- a/robot-server/tests/integration/http_api/protocols/test_persistence.py +++ b/robot-server/tests/integration/http_api/protocols/test_persistence.py @@ -132,10 +132,10 @@ async def test_protocol_labware_files_persist() -> None: assert restarted_protocol_detail == protocol_detail four_tuberack = Path( - f"{server.persistence_directory}/protocols/{protocol_id}/cpx_4_tuberack_100ul.json" + f"{server.persistence_directory}/3/protocols/{protocol_id}/cpx_4_tuberack_100ul.json" ) six_tuberack = Path( - f"{server.persistence_directory}/protocols/{protocol_id}/cpx_6_tuberack_100ul.json" + f"{server.persistence_directory}/3/protocols/{protocol_id}/cpx_6_tuberack_100ul.json" ) assert four_tuberack.is_file() assert six_tuberack.is_file() diff --git a/robot-server/tests/integration/http_api/test_deck_configuration.tavern.yaml b/robot-server/tests/integration/http_api/test_deck_configuration.tavern.yaml index 8cc01fdcd24..7ade14b4f8e 100644 --- a/robot-server/tests/integration/http_api/test_deck_configuration.tavern.yaml +++ b/robot-server/tests/integration/http_api/test_deck_configuration.tavern.yaml @@ -155,6 +155,10 @@ stages: deckConfiguration: true response: json: !anydict + # Retry on failure because if this request comes in before the server's persistence + # layer has fully initialized, it will return 503. + max_retries: 5 + delay_after: 0.5 - name: Get the deck configuration after the reset and make sure it's immediately gone back to the default request: diff --git a/robot-server/tests/service/legacy/routers/test_settings.py b/robot-server/tests/service/legacy/routers/test_settings.py index 80825e3e736..58bcfefffe0 100644 --- a/robot-server/tests/service/legacy/routers/test_settings.py +++ b/robot-server/tests/service/legacy/routers/test_settings.py @@ -1,7 +1,7 @@ import logging from mock import patch, call, MagicMock from dataclasses import make_dataclass -from typing import Generator +from typing import Generator, Optional from pathlib import Path import pytest @@ -20,7 +20,7 @@ from robot_server import app from robot_server.deck_configuration.fastapi_dependencies import ( - get_deck_configuration_store, + get_deck_configuration_store_failsafe, ) from robot_server.deck_configuration.store import DeckConfigurationStore from robot_server.persistence import PersistenceResetter, get_persistence_resetter @@ -510,19 +510,19 @@ async def mock_get_persistence_resetter() -> PersistenceResetter: @pytest.fixture -def mock_deck_configuration_store( +def mock_deck_configuration_store_failsafe( decoy: Decoy, -) -> Generator[DeckConfigurationStore, None, None]: +) -> Generator[Optional[DeckConfigurationStore], None, None]: mock_deck_configuration_store = decoy.mock(cls=DeckConfigurationStore) - async def mock_get_deck_configuration_store() -> DeckConfigurationStore: + async def mock_get_deck_configuration_store_failsafe() -> DeckConfigurationStore: return mock_deck_configuration_store app.dependency_overrides[ - get_deck_configuration_store - ] = mock_get_deck_configuration_store + get_deck_configuration_store_failsafe + ] = mock_get_deck_configuration_store_failsafe yield mock_deck_configuration_store - del app.dependency_overrides[get_deck_configuration_store] + del app.dependency_overrides[get_deck_configuration_store_failsafe] @pytest.mark.parametrize( @@ -578,7 +578,7 @@ def test_reset_success( api_client, mock_reset, mock_persistence_resetter: PersistenceResetter, - mock_deck_configuration_store: DeckConfigurationStore, + mock_deck_configuration_store_failsafe: Optional[DeckConfigurationStore], body, called_with, ): @@ -588,7 +588,10 @@ def test_reset_success( def test_reset_invalid_option( - api_client, mock_reset, mock_persistence_resetter, mock_deck_configuration_store + api_client, + mock_reset, + mock_persistence_resetter, + mock_deck_configuration_store_failsafe, ): resp = api_client.post("/settings/reset", json={"aksgjajhadjasl": False}) assert resp.status_code == 422 From 2eb52a76fc1cd12d30ed1e47eae33c423637997e Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Wed, 7 Feb 2024 17:37:46 -0500 Subject: [PATCH 08/10] fix(api): raise errors from modules disconnecting (#14443) When a module gets disconnected, the hardware controller cleans up the module instance, which stops the poller. What it doesn't do is cancel anything that was waiting on the next poll, or in fact prevent new things from waiting on the now-stopped poller. That means that if a module disconnects - During a module method waiting for the next poll, that module method hangs (well, awaits) forever - During a module method right _before_ waiting for the next poll, that module method would start waiting and continue waiting forever This PR forwards cancellations into the registered poll waiters when the poller task is cancelled, and prevents the registration of new poll waiters on a cancelled poll task. --- api/src/opentrons/hardware_control/poller.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/src/opentrons/hardware_control/poller.py b/api/src/opentrons/hardware_control/poller.py index 76dd40157a1..27224bebaef 100644 --- a/api/src/opentrons/hardware_control/poller.py +++ b/api/src/opentrons/hardware_control/poller.py @@ -3,6 +3,7 @@ import logging from abc import ABC, abstractmethod from typing import AsyncGenerator, List, Optional +from opentrons_shared_data.errors.exceptions import ModuleCommunicationError log = logging.getLogger(__name__) @@ -48,6 +49,8 @@ async def stop(self) -> None: async with self._use_read_lock(): task.cancel() await asyncio.gather(task, return_exceptions=True) + for waiter in self._poll_waiters: + waiter.cancel(msg="Module was removed") async def wait_next_poll(self) -> None: """Wait for the next poll to complete. @@ -56,6 +59,9 @@ async def wait_next_poll(self) -> None: the next complete read. If a read raises an exception, it will be passed through to `wait_next_poll`. """ + if not self._poll_forever_task or self._poll_forever_task.done(): + raise ModuleCommunicationError(message="Module was removed") + poll_future = asyncio.get_running_loop().create_future() self._poll_waiters.append(poll_future) await poll_future From b8a60d6dd47c0481cb0f1288c689ab9494a2123e Mon Sep 17 00:00:00 2001 From: koji Date: Thu, 8 Feb 2024 07:42:27 +0900 Subject: [PATCH 09/10] fix(app): fix odd protocol setup background color (#14438) * fix(app): fix odd protocol setup background color fix odd protocol setup background color Close RAUT-961 --- app/src/pages/ProtocolSetup/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/pages/ProtocolSetup/index.tsx b/app/src/pages/ProtocolSetup/index.tsx index 98198d1a395..46011492e54 100644 --- a/app/src/pages/ProtocolSetup/index.tsx +++ b/app/src/pages/ProtocolSetup/index.tsx @@ -124,7 +124,7 @@ export function ProtocolSetupStep({ const backgroundColorByStepStatus = { ready: COLORS.green35, 'not ready': COLORS.yellow35, - general: COLORS.blue35, + general: COLORS.grey35, } const { makeSnackbar } = useToaster() @@ -164,7 +164,7 @@ export function ProtocolSetupStep({ Date: Wed, 7 Feb 2024 17:47:02 -0500 Subject: [PATCH 10/10] fix(app): open external links in browser (#14447) external links were opening in the electron browser window instead of an external browser window closes RQA-2309 --- app-shell/src/ui.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app-shell/src/ui.ts b/app-shell/src/ui.ts index c60118bc0cd..6734136fc6e 100644 --- a/app-shell/src/ui.ts +++ b/app-shell/src/ui.ts @@ -57,14 +57,10 @@ export function createUi(): BrowserWindow { mainWindow.loadURL(url, { extraHeaders: 'pragma: no-cache\n' }) // open new windows ( { - if (disposition === 'new-window' && url === 'about:blank') { - // eslint-disable-next-line no-void - void shell.openExternal(url) - return { action: 'deny' } - } else { - return { action: 'allow' } - } + mainWindow.webContents.setWindowOpenHandler(({ url }) => { + // eslint-disable-next-line no-void + void shell.openExternal(url) + return { action: 'deny' } }) return mainWindow