From 816eaa7f29b317442b46407f3cfe120b82fafb96 Mon Sep 17 00:00:00 2001 From: Max Marrone Date: Wed, 6 Sep 2023 11:26:10 -0400 Subject: [PATCH] fix(robot-server): Pin pickle protocol version to v4 (#13466) --- .../robot_server/persistence/_tables.py | 5 ++-- .../persistence/pickle_protocol_version.py | 23 +++++++++++++++++++ .../protocols/completed_analysis_store.py | 5 +++- 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 robot-server/robot_server/persistence/pickle_protocol_version.py diff --git a/robot-server/robot_server/persistence/_tables.py b/robot-server/robot_server/persistence/_tables.py index ab30c512e05..7de9fa60465 100644 --- a/robot-server/robot_server/persistence/_tables.py +++ b/robot-server/robot_server/persistence/_tables.py @@ -2,6 +2,7 @@ import sqlalchemy from . import legacy_pickle +from .pickle_protocol_version import PICKLE_PROTOCOL_VERSION from ._utc_datetime import UTCDateTime _metadata = sqlalchemy.MetaData() @@ -94,13 +95,13 @@ # column added in schema v1 sqlalchemy.Column( "state_summary", - sqlalchemy.PickleType(pickler=legacy_pickle), + sqlalchemy.PickleType(pickler=legacy_pickle, protocol=PICKLE_PROTOCOL_VERSION), nullable=True, ), # column added in schema v1 sqlalchemy.Column( "commands", - sqlalchemy.PickleType(pickler=legacy_pickle), + sqlalchemy.PickleType(pickler=legacy_pickle, protocol=PICKLE_PROTOCOL_VERSION), nullable=True, ), # column added in schema v1 diff --git a/robot-server/robot_server/persistence/pickle_protocol_version.py b/robot-server/robot_server/persistence/pickle_protocol_version.py new file mode 100644 index 00000000000..a4d9702bf07 --- /dev/null +++ b/robot-server/robot_server/persistence/pickle_protocol_version.py @@ -0,0 +1,23 @@ +# noqa: D100 + + +from typing_extensions import Final + + +PICKLE_PROTOCOL_VERSION: Final = 4 +"""The version of Python's pickle protocol that we should use for serializing new objects. + +We set this to v4 because it's the least common denominator between all of our environments. +At the time of writing (2023-09-05): + +* Flex: Python 3.8, pickle protocol v5 by default +* OT-2: Python 3.7, pickle protocol v4 by default +* Typical local dev environments: Python 3.7, pickle protocol v4 by default + +For troubleshooting, we want our dev environments be able to read pickles created by any robot. +""" + + +# TODO(mm, 2023-09-05): Delete this when robot-server stops pickling new objects +# (https://opentrons.atlassian.net/browse/RSS-98), or when we upgrade the Python version +# in our dev environments. diff --git a/robot-server/robot_server/protocols/completed_analysis_store.py b/robot-server/robot_server/protocols/completed_analysis_store.py index 77f4eea682f..29ee571d08c 100644 --- a/robot-server/robot_server/protocols/completed_analysis_store.py +++ b/robot-server/robot_server/protocols/completed_analysis_store.py @@ -11,6 +11,7 @@ from robot_server.persistence import analysis_table, sqlite_rowid from robot_server.persistence import legacy_pickle +from robot_server.persistence.pickle_protocol_version import PICKLE_PROTOCOL_VERSION from .analysis_models import CompletedAnalysis from .analysis_memcache import MemoryCache @@ -289,7 +290,9 @@ async def add(self, completed_analysis_resource: CompletedAnalysisResource) -> N def _serialize_completed_analysis_to_pickle( completed_analysis: CompletedAnalysis, ) -> bytes: - return legacy_pickle.dumps(completed_analysis.dict()) + return legacy_pickle.dumps( + completed_analysis.dict(), protocol=PICKLE_PROTOCOL_VERSION + ) def _serialize_completed_analysis_to_json(completed_analysis: CompletedAnalysis) -> str: