Skip to content

Commit a56e919

Browse files
refactor: Rename Pydantic v1 methods to their v2 counterparts (#17123)
1 parent 60398ea commit a56e919

File tree

148 files changed

+659
-586
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+659
-586
lines changed

api/pytest.ini

+8-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@ markers =
66
addopts = --color=yes --strict-markers
77
asyncio_mode = auto
88

9-
# TODO this should be looked into being removed upon updating the Decoy library. The purpose of this warning is to
10-
# catch missing attributes, but it raises for any property referenced in a test which accounts for about ~250 warnings
11-
# which aren't serving any useful purpose and obscure other warnings.
129
filterwarnings =
10+
# TODO this should be looked into being removed upon updating the Decoy library. The purpose of this warning is to
11+
# catch missing attributes, but it raises for any property referenced in a test which accounts for about ~250 warnings
12+
# which aren't serving any useful purpose and obscure other warnings.
1313
ignore::decoy.warnings.MissingSpecAttributeWarning
14+
# Pydantic's shims for its legacy v1 methods (e.g. `BaseModel.construct()`)
15+
# are not type-checked properly. Forbid them, so we're forced to use their newer
16+
# v2 replacements which are type-checked (e.g. ``BaseModel.model_construct()`)
17+
error::pydantic.PydanticDeprecatedSince20
18+

api/src/opentrons/calibration_storage/deck_configuration.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ def serialize_deck_configuration(
2424
cutout_fixture_placements: List[CutoutFixturePlacement], last_modified: datetime
2525
) -> bytes:
2626
"""Serialize a deck configuration for storing on the filesystem."""
27-
data = _DeckConfigurationModel.construct(
27+
data = _DeckConfigurationModel.model_construct(
2828
cutoutFixtures=[
29-
_CutoutFixturePlacementModel.construct(
29+
_CutoutFixturePlacementModel.model_construct(
3030
cutoutId=e.cutout_id,
3131
cutoutFixtureId=e.cutout_fixture_id,
3232
opentronsModuleSerialNumber=e.opentrons_module_serial_number,

api/src/opentrons/calibration_storage/file_operators.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def save_to_file(
103103
directory_path.mkdir(parents=True, exist_ok=True)
104104
file_path = directory_path / f"{file_name}.json"
105105
json_data = (
106-
data.json()
106+
data.model_dump_json()
107107
if isinstance(data, pydantic.BaseModel)
108108
else json.dumps(data, cls=encoder)
109109
)
@@ -112,7 +112,7 @@ def save_to_file(
112112

113113
def serialize_pydantic_model(data: pydantic.BaseModel) -> bytes:
114114
"""Safely serialize data from a Pydantic model into a form suitable for storing on disk."""
115-
return data.json(by_alias=True).encode("utf-8")
115+
return data.model_dump_json(by_alias=True).encode("utf-8")
116116

117117

118118
_ModelT = typing.TypeVar("_ModelT", bound=pydantic.BaseModel)

api/src/opentrons/calibration_storage/ot2/tip_length.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def _convert_tip_length_model_to_dict(
3131
# add encoders when converting to a dict.
3232
dict_of_tip_lengths = {}
3333
for key, item in to_dict.items():
34-
dict_of_tip_lengths[key] = json.loads(item.json())
34+
dict_of_tip_lengths[key] = json.loads(item.model_dump_json())
3535
return dict_of_tip_lengths
3636

3737

@@ -176,12 +176,14 @@ def delete_tip_length_calibration(
176176
io.save_to_file(tip_length_dir, pipette_id, dict_of_tip_lengths)
177177
else:
178178
io.delete_file(tip_length_dir / f"{pipette_id}.json")
179-
elif tiprack_hash and any(tiprack_hash in v.dict() for v in tip_lengths.values()):
179+
elif tiprack_hash and any(
180+
tiprack_hash in v.model_dump() for v in tip_lengths.values()
181+
):
180182
# NOTE this is for backwards compatibilty only
181183
# TODO delete this check once the tip_length DELETE router
182184
# no longer depends on a tiprack hash
183185
for k, v in tip_lengths.items():
184-
if tiprack_hash in v.dict():
186+
if tiprack_hash in v.model_dump():
185187
tip_lengths.pop(k)
186188
if tip_lengths:
187189
dict_of_tip_lengths = _convert_tip_length_model_to_dict(tip_lengths)

api/src/opentrons/execute.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,9 @@ def _create_live_context_pe(
560560
# Non-async would use call_soon_threadsafe(), which makes the waiting harder.
561561
async def add_all_extra_labware() -> None:
562562
for labware_definition_dict in extra_labware.values():
563-
labware_definition = LabwareDefinition.parse_obj(labware_definition_dict)
563+
labware_definition = LabwareDefinition.model_validate(
564+
labware_definition_dict
565+
)
564566
pe.add_labware_definition(labware_definition)
565567

566568
# Add extra_labware to ProtocolEngine, being careful not to modify ProtocolEngine from this

api/src/opentrons/hardware_control/emulation/module_server/client.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ async def read(self) -> Message:
6666
"""Read a message from the module server."""
6767
try:
6868
b = await self._reader.readuntil(MessageDelimiter)
69-
m: Message = Message.parse_raw(b)
69+
m: Message = Message.model_validate_json(b)
7070
return m
7171
except LimitOverrunError as e:
7272
raise ModuleServerClientError(str(e))

api/src/opentrons/hardware_control/emulation/module_server/server.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ def on_server_connected(
5353
self._connections[identifier] = connection
5454
for c in self._clients:
5555
c.write(
56-
Message(status="connected", connections=[connection]).json().encode()
56+
Message(status="connected", connections=[connection])
57+
.model_dump_json()
58+
.encode()
5759
)
5860
c.write(b"\n")
5961

@@ -72,7 +74,7 @@ def on_server_disconnected(self, identifier: str) -> None:
7274
for c in self._clients:
7375
c.write(
7476
Message(status="disconnected", connections=[connection])
75-
.json()
77+
.model_dump_json()
7678
.encode()
7779
)
7880
c.write(MessageDelimiter)
@@ -95,7 +97,7 @@ async def _handle_connection(
9597
# A client connected. Send a dump of all connected modules.
9698
m = Message(status="dump", connections=list(self._connections.values()))
9799

98-
writer.write(m.json().encode())
100+
writer.write(m.model_dump_json().encode())
99101
writer.write(MessageDelimiter)
100102

101103
self._clients.add(writer)

api/src/opentrons/hardware_control/instruments/ot2/instrument_calibration.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ def load_tip_length_for_pipette(
123123
) -> TipLengthCalibration:
124124
if isinstance(tiprack, LabwareDefinition):
125125
tiprack = typing.cast(
126-
"TypeDictLabwareDef", tiprack.dict(exclude_none=True, exclude_unset=True)
126+
"TypeDictLabwareDef",
127+
tiprack.model_dump(exclude_none=True, exclude_unset=True),
127128
)
128129

129130
tip_length_data = calibration_storage.load_tip_length_calibration(

api/src/opentrons/hardware_control/instruments/ot2/pipette.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def __init__(
9696
use_old_aspiration_functions: bool = False,
9797
) -> None:
9898
self._config = config
99-
self._config_as_dict = config.dict()
99+
self._config_as_dict = config.model_dump()
100100
self._pipette_offset = pipette_offset_cal
101101
self._pipette_type = self._config.pipette_type
102102
self._pipette_version = self._config.version
@@ -273,15 +273,15 @@ def update_config_item(
273273
self._config, elements, liquid_class
274274
)
275275
# Update the cached dict representation
276-
self._config_as_dict = self._config.dict()
276+
self._config_as_dict = self._config.model_dump()
277277

278278
def reload_configurations(self) -> None:
279279
self._config = load_pipette_data.load_definition(
280280
self._pipette_model.pipette_type,
281281
self._pipette_model.pipette_channels,
282282
self._pipette_model.pipette_version,
283283
)
284-
self._config_as_dict = self._config.dict()
284+
self._config_as_dict = self._config.model_dump()
285285

286286
def reset_state(self) -> None:
287287
self._current_volume = 0.0
@@ -656,8 +656,8 @@ def _reload_and_check_skip(
656656
# Same config, good enough
657657
return attached_instr, True
658658
else:
659-
newdict = new_config.dict()
660-
olddict = attached_instr.config.dict()
659+
newdict = new_config.model_dump()
660+
olddict = attached_instr.config.model_dump()
661661
changed: Set[str] = set()
662662
for k in newdict.keys():
663663
if newdict[k] != olddict[k]:

api/src/opentrons/hardware_control/instruments/ot3/gripper.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,8 @@ def _reload_gripper(
318318
# Same config, good enough
319319
return attached_instr, True
320320
else:
321-
newdict = new_config.dict()
322-
olddict = attached_instr.config.dict()
321+
newdict = new_config.model_dump()
322+
olddict = attached_instr.config.model_dump()
323323
changed: Set[str] = set()
324324
for k in newdict.keys():
325325
if newdict[k] != olddict[k]:

api/src/opentrons/hardware_control/instruments/ot3/pipette.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def __init__(
7979
use_old_aspiration_functions: bool = False,
8080
) -> None:
8181
self._config = config
82-
self._config_as_dict = config.dict()
82+
self._config_as_dict = config.model_dump()
8383
self._plunger_motor_current = config.plunger_motor_configurations
8484
self._pick_up_configurations = config.pick_up_tip_configurations
8585
self._plunger_homing_configurations = config.plunger_homing_configurations
@@ -251,7 +251,7 @@ def reload_configurations(self) -> None:
251251
self._pipette_model.pipette_channels,
252252
self._pipette_model.pipette_version,
253253
)
254-
self._config_as_dict = self._config.dict()
254+
self._config_as_dict = self._config.model_dump()
255255

256256
def reset_state(self) -> None:
257257
self._current_volume = 0.0
@@ -770,8 +770,8 @@ def _reload_and_check_skip(
770770
# Same config, good enough
771771
return attached_instr, True
772772
else:
773-
newdict = new_config.dict()
774-
olddict = attached_instr.config.dict()
773+
newdict = new_config.model_dump()
774+
olddict = attached_instr.config.model_dump()
775775
changed: Set[str] = set()
776776
for k in newdict.keys():
777777
if newdict[k] != olddict[k]:

api/src/opentrons/hardware_control/ot3_calibration.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ def load_attitude_matrix(to_default: bool = True) -> DeckCalibration:
968968
return DeckCalibration(
969969
attitude=apply_machine_transform(calibration_data.attitude),
970970
source=calibration_data.source,
971-
status=types.CalibrationStatus(**calibration_data.status.dict()),
971+
status=types.CalibrationStatus(**calibration_data.status.model_dump()),
972972
belt_attitude=calibration_data.attitude,
973973
last_modified=calibration_data.lastModified,
974974
pipette_calibrated_with=calibration_data.pipetteCalibratedWith,

api/src/opentrons/hardware_control/robot_calibration.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def load_attitude_matrix() -> DeckCalibration:
154154
return DeckCalibration(
155155
attitude=calibration_data.attitude,
156156
source=calibration_data.source,
157-
status=types.CalibrationStatus(**calibration_data.status.dict()),
157+
status=types.CalibrationStatus(**calibration_data.status.model_dump()),
158158
last_modified=calibration_data.last_modified,
159159
pipette_calibrated_with=calibration_data.pipette_calibrated_with,
160160
tiprack=calibration_data.tiprack,

api/src/opentrons/protocol_api/core/engine/labware.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,14 @@ def get_name(self) -> str:
9292

9393
def get_definition(self) -> LabwareDefinitionDict:
9494
"""Get the labware's definition as a plain dictionary."""
95-
return cast(LabwareDefinitionDict, self._definition.dict(exclude_none=True))
95+
return cast(
96+
LabwareDefinitionDict, self._definition.model_dump(exclude_none=True)
97+
)
9698

9799
def get_parameters(self) -> LabwareParametersDict:
98100
return cast(
99101
LabwareParametersDict,
100-
self._definition.parameters.dict(exclude_none=True),
102+
self._definition.parameters.model_dump(exclude_none=True),
101103
)
102104

103105
def get_quirks(self) -> List[str]:
@@ -118,7 +120,7 @@ def set_calibration(self, delta: Point) -> None:
118120
details={"kind": "labware-not-in-slot"},
119121
)
120122

121-
request = LabwareOffsetCreate.construct(
123+
request = LabwareOffsetCreate.model_construct(
122124
definitionUri=self.get_uri(),
123125
location=offset_location,
124126
vector=LabwareOffsetVector(x=delta.x, y=delta.y, z=delta.z),

api/src/opentrons/protocol_api/core/engine/protocol.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ def add_labware_definition(
193193
) -> LabwareLoadParams:
194194
"""Add a labware definition to the set of loadable definitions."""
195195
uri = self._engine_client.add_labware_definition(
196-
LabwareDefinition.parse_obj(definition)
196+
LabwareDefinition.model_validate(definition)
197197
)
198198
return LabwareLoadParams.from_uri(uri)
199199

api/src/opentrons/protocol_engine/commands/absorbance_reader/read.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ async def execute( # noqa: C901
124124
)
125125
asbsorbance_result[wavelength] = converted_values
126126
transform_results.append(
127-
ReadData.construct(wavelength=wavelength, data=converted_values)
127+
ReadData.model_construct(
128+
wavelength=wavelength, data=converted_values
129+
)
128130
)
129131
# Handle the virtual module case for data creation (all zeroes)
130132
elif self._state_view.config.use_virtual_modules:
@@ -138,7 +140,9 @@ async def execute( # noqa: C901
138140
)
139141
asbsorbance_result[wavelength] = converted_values
140142
transform_results.append(
141-
ReadData.construct(wavelength=wavelength, data=converted_values)
143+
ReadData.model_construct(
144+
wavelength=wavelength, data=converted_values
145+
)
142146
)
143147
else:
144148
raise CannotPerformModuleAction(
@@ -153,7 +157,7 @@ async def execute( # noqa: C901
153157
file_ids: list[str] = []
154158
if params.fileName is not None:
155159
# Create the Plate Reader Transform
156-
plate_read_result = PlateReaderData.construct(
160+
plate_read_result = PlateReaderData.model_construct(
157161
read_results=transform_results,
158162
reference_wavelength=abs_reader_substate.reference_wavelength,
159163
start_time=start_time,

api/src/opentrons/protocol_engine/commands/calibration/calibrate_gripper.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ async def execute(
125125
calibration_data = result
126126

127127
return SuccessData(
128-
public=CalibrateGripperResult.construct(
129-
jawOffset=Vec3f.construct(
128+
public=CalibrateGripperResult.model_construct(
129+
jawOffset=Vec3f.model_construct(
130130
x=probe_offset.x, y=probe_offset.y, z=probe_offset.z
131131
),
132132
savedCalibration=calibration_data,

api/src/opentrons/protocol_engine/commands/calibration/calibrate_pipette.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ async def execute(
6565
await ot3_api.save_instrument_offset(mount=ot3_mount, delta=pipette_offset)
6666

6767
return SuccessData(
68-
public=CalibratePipetteResult.construct(
69-
pipetteOffset=InstrumentOffsetVector.construct(
68+
public=CalibratePipetteResult.model_construct(
69+
pipetteOffset=InstrumentOffsetVector.model_construct(
7070
x=pipette_offset.x, y=pipette_offset.y, z=pipette_offset.z
7171
)
7272
),

api/src/opentrons/protocol_engine/commands/configure_nozzle_layout.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ async def execute(
6161
self, params: ConfigureNozzleLayoutParams
6262
) -> SuccessData[ConfigureNozzleLayoutResult]:
6363
"""Check that requested pipette can support the requested nozzle layout."""
64-
primary_nozzle = params.configurationParams.dict().get("primaryNozzle")
65-
front_right_nozzle = params.configurationParams.dict().get("frontRightNozzle")
66-
back_left_nozzle = params.configurationParams.dict().get("backLeftNozzle")
64+
primary_nozzle = params.configurationParams.model_dump().get("primaryNozzle")
65+
front_right_nozzle = params.configurationParams.model_dump().get(
66+
"frontRightNozzle"
67+
)
68+
back_left_nozzle = params.configurationParams.model_dump().get("backLeftNozzle")
6769
nozzle_params = await self._tip_handler.available_for_nozzle_layout(
6870
pipette_id=params.pipetteId,
6971
style=params.configurationParams.style,

api/src/opentrons/protocol_engine/commands/custom.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class CustomImplementation(
4444
async def execute(self, params: CustomParams) -> SuccessData[CustomResult]:
4545
"""A custom command does nothing when executed directly."""
4646
return SuccessData(
47-
public=CustomResult.construct(),
47+
public=CustomResult.model_construct(),
4848
)
4949

5050

api/src/opentrons/protocol_engine/commands/movement_common.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ async def move_to_well(
182182
state_update=StateUpdate().clear_all_pipette_locations(),
183183
)
184184
else:
185-
deck_point = DeckPoint.construct(x=position.x, y=position.y, z=position.z)
185+
deck_point = DeckPoint.model_construct(x=position.x, y=position.y, z=position.z)
186186
return SuccessData(
187187
public=DestinationPositionResult(
188188
position=deck_point,
@@ -222,7 +222,7 @@ async def move_relative(
222222
state_update=StateUpdate().clear_all_pipette_locations(),
223223
)
224224
else:
225-
deck_point = DeckPoint.construct(x=position.x, y=position.y, z=position.z)
225+
deck_point = DeckPoint.model_construct(x=position.x, y=position.y, z=position.z)
226226
return SuccessData(
227227
public=DestinationPositionResult(
228228
position=deck_point,
@@ -277,7 +277,7 @@ async def move_to_addressable_area(
277277
.set_addressable_area_used(addressable_area_name=addressable_area_name),
278278
)
279279
else:
280-
deck_point = DeckPoint.construct(x=x, y=y, z=z)
280+
deck_point = DeckPoint.model_construct(x=x, y=y, z=z)
281281
return SuccessData(
282282
public=DestinationPositionResult(position=deck_point),
283283
state_update=StateUpdate()
@@ -324,7 +324,7 @@ async def move_to_coordinates(
324324
state_update=StateUpdate().clear_all_pipette_locations(),
325325
)
326326
else:
327-
deck_point = DeckPoint.construct(x=x, y=y, z=z)
327+
deck_point = DeckPoint.model_construct(x=x, y=y, z=z)
328328

329329
return SuccessData(
330330
public=DestinationPositionResult(position=DeckPoint(x=x, y=y, z=z)),

api/src/opentrons/protocol_engine/commands/touch_tip.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ async def execute(
154154
waypoints=touch_waypoints,
155155
speed=touch_speed,
156156
)
157-
final_deck_point = DeckPoint.construct(
157+
final_deck_point = DeckPoint.model_construct(
158158
x=final_point.x, y=final_point.y, z=final_point.z
159159
)
160160
state_update = center_result.state_update.set_pipette_location(

api/src/opentrons/protocol_engine/errors/error_occurrence.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def from_failed(
2929
wrappedErrors = [
3030
cls.from_failed(id, createdAt, err) for err in error.wrapping
3131
]
32-
return cls.construct(
32+
return cls.model_construct(
3333
id=id,
3434
createdAt=createdAt,
3535
errorType=type(error).__name__,

0 commit comments

Comments
 (0)