Skip to content

Commit

Permalink
fix(hugr-core)!: bump serialisation version with no upgrade path (#1352)
Browse files Browse the repository at this point in the history
Since we are breaking serialisation I edited most test cases to use v3.
The single test case which I deleted was testing that we were able to l
deserialise from an older version, so is now redundant. This should have
been done when removing `CustomTypeArg`.

BREAKING CHANGE: All Hugrs serialised with earlier versions will fail to
deserialise

---------

Co-authored-by: Agustín Borgna <[email protected]>
Co-authored-by: Seyon Sivarajah <[email protected]>
  • Loading branch information
3 people authored Jul 26, 2024
1 parent 73070c4 commit 657cbb0
Show file tree
Hide file tree
Showing 23 changed files with 22 additions and 11,037 deletions.
14 changes: 9 additions & 5 deletions hugr-core/src/hugr/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ enum Versioned<SerHugr = SerHugrLatest> {
V0,

V1(serde_json::Value),
V2(SerHugr),
V2(serde_json::Value),
Live(SerHugr),

#[serde(skip_serializing)]
#[serde(other)]
Expand All @@ -48,24 +49,27 @@ enum Versioned<SerHugr = SerHugrLatest> {

impl<T> Versioned<T> {
pub fn new_latest(t: T) -> Self {
Self::V2(t)
Self::Live(t)
}
}

impl<T: DeserializeOwned> Versioned<T> {
fn upgrade(mut self) -> Result<T, UpgradeError> {
fn upgrade(self) -> Result<T, UpgradeError> {
// go is polymorphic in D. When we are upgrading to the latest version
// D is T. When we are upgrading to a version which is not the latest D
// is serde_json::Value.
#[allow(unused)]
fn go<D: serde::de::DeserializeOwned>(v: serde_json::Value) -> Result<D, UpgradeError> {
serde_json::from_value(v).map_err(Into::into)
}
loop {
match self {
Self::V0 => Err(UpgradeError::KnownVersionUnsupported("0".into()))?,
// the upgrade lines remain unchanged when adding a new constructor
Self::V1(json) => self = Self::V2(upgrade::v1_to_v2(json).and_then(go)?),
Self::V2(ser_hugr) => return Ok(ser_hugr),
// Self::V1(json) => self = Self::V2(upgrade::v1_to_v2(json).and_then(go)?),
Self::V1(_) => Err(UpgradeError::KnownVersionUnsupported("1".into()))?,
Self::V2(_) => Err(UpgradeError::KnownVersionUnsupported("2".into()))?,
Self::Live(ser_hugr) => return Ok(ser_hugr),
Versioned::Unsupported => Err(UpgradeError::UnknownVersionUnsupported)?,
}
}
Expand Down
13 changes: 1 addition & 12 deletions hugr-core/src/hugr/serialize/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ macro_rules! include_schema {
static ref $name: NamedSchema =
NamedSchema::new("$name", {
let schema_val: serde_json::Value = serde_json::from_str(include_str!(
concat!("../../../../specification/schema/", $path, "_v2.json")
concat!("../../../../specification/schema/", $path, "_live.json")
))
.unwrap();
JSONSchema::options()
Expand Down Expand Up @@ -517,17 +517,6 @@ fn roundtrip_optype(#[case] optype: impl Into<OpType> + std::fmt::Debug) {
});
}

#[test]
#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri
/// issue 1270
fn input_extensions_deser() {
// load a file serialised with `input_extensions` fields on all ops
let _: Hugr = serde_json::from_reader(std::io::BufReader::new(
std::fs::File::open(crate::test_file!("issue-1270.json")).unwrap(),
))
.unwrap();
}

mod proptest {
use super::check_testing_roundtrip;
use super::{NodeSer, SimpleOpDef};
Expand Down
21 changes: 0 additions & 21 deletions hugr-core/src/hugr/serialize/upgrade.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use serde::de::Error;
use thiserror::Error;

#[derive(Debug, Error)]
Expand All @@ -13,26 +12,6 @@ pub enum UpgradeError {
UnknownVersionUnsupported,
}

pub fn v1_to_v2(mut input: serde_json::Value) -> Result<serde_json::Value, UpgradeError> {
let input_obj = input
.as_object_mut()
.ok_or(serde_json::Error::custom("Value is not an object"))?;
let nodes = input_obj
.get_mut("nodes")
.ok_or(serde_json::Error::custom("No nodes field"))?
.as_array_mut()
.ok_or(serde_json::Error::custom("nodes is not an array"))?;
for node in nodes.iter_mut() {
let node_obj = node
.as_object_mut()
.ok_or(serde_json::Error::custom("node is not an object"))?;
if let Some(name) = node_obj.remove("op_name") {
node_obj.insert("name".to_owned(), name);
}
}
Ok(input)
}

#[cfg(all(test, not(miri)))]
// see serialize::test.
mod test;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v1",
"version": "live",
"nodes": [
{
"parent": 0,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v1",
"version": "live",
"nodes": [
{
"parent": 0,
Expand Down Expand Up @@ -58,7 +58,7 @@
"parent": 0,
"op": "CustomOp",
"extension": "logic",
"op_name": "And",
"name": "And",
"description": "logical 'and'",
"args": [
{
Expand Down
2 changes: 1 addition & 1 deletion hugr-py/src/hugr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@

def get_serialisation_version() -> str:
"""Return the current version of the serialization schema."""
return "v2"
return "live"
1 change: 0 additions & 1 deletion hugr-py/src/hugr/hugr.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,6 @@ def _serialize_link(
return (src.port.node.idx, s), (dst.port.node.idx, d)

return SerialHugr(
version="v1",
# non contiguous indices will be erased
nodes=[node.to_serial(Node(idx)) for idx, node in enumerate(node_it)],
edges=[_serialize_link(link) for link in self._links.items()],
Expand Down
6 changes: 3 additions & 3 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion resources/test/hugr-0.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v1",
"version": "v3",
"nodes":
[
{
Expand Down
2 changes: 1 addition & 1 deletion resources/test/hugr-1.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v1",
"version": "live",
"nodes":
[
{
Expand Down
2 changes: 1 addition & 1 deletion resources/test/hugr-2.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v1",
"version": "live",
"nodes":
[
{
Expand Down
2 changes: 1 addition & 1 deletion resources/test/hugr-3.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v1",
"version": "live",
"nodes":
[
{
Expand Down
2 changes: 1 addition & 1 deletion resources/test/issue-1189.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v1",
"version": "live",
"nodes": [
{
"parent": 0,
Expand Down
Loading

0 comments on commit 657cbb0

Please sign in to comment.