From b80a871120c1c2babba61c4cb5fdcb985e1ea431 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin Date: Wed, 28 Feb 2024 21:54:26 -0500 Subject: [PATCH 1/3] Add to_dict method to all classes that can be converted to dict and to_list to AnyVector. Useful to pass to json.dumps. Signed-off-by: Jean-Christophe Morin --- .../opentimelineio/core/_core_utils.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/py-opentimelineio/opentimelineio/core/_core_utils.py b/src/py-opentimelineio/opentimelineio/core/_core_utils.py index d58791a67b..548a33fac9 100644 --- a/src/py-opentimelineio/opentimelineio/core/_core_utils.py +++ b/src/py-opentimelineio/opentimelineio/core/_core_utils.py @@ -4,6 +4,7 @@ import types import collections.abc import copy +import json from .. import ( _otio, @@ -14,6 +15,11 @@ AnyVector, PyAny ) +from .. _opentime import ( + RationalTime, + TimeRange, + TimeTransform +) SUPPORTED_VALUE_TYPES = ( @@ -388,3 +394,57 @@ def __deepcopy__(self, *args, **kwargs): @add_method(SerializableObject) def __copy__(self, *args, **kwargs): raise ValueError("SerializableObjects may not be shallow copied.") + + +@add_method(AnyDictionary) +def to_dict(self): + """ + Convert to a built-in dict. It will recursively convert all values + to their corresponding python built-in types. + """ + return json.loads(_otio._serialize_json_to_string(_value_to_any(self), {}, 0)) + + +@add_method(AnyVector) +def to_list(self): + """ + Convert to a built-in list. It will recursively convert all values + to their corresponding python built-in types. + """ + return json.loads(_otio._serialize_json_to_string(_value_to_any(self), {}, 0)) + + +@add_method(SerializableObject) +def to_dict(self): + """ + Convert to a built-in dict. It will recursively convert all values + to their corresponding python built-in types. + """ + return json.loads(_otio._serialize_json_to_string(_value_to_any(self), {}, 0)) + + +@add_method(RationalTime) +def to_dict(self): + """ + Convert to a built-in dict. It will recursively convert all values + to their corresponding python built-in types. + """ + return json.loads(_otio._serialize_json_to_string(_value_to_any(self), {}, 0)) + + +@add_method(TimeRange) +def to_dict(self): + """ + Convert to a built-in dict. It will recursively convert all values + to their corresponding python built-in types. + """ + return json.loads(_otio._serialize_json_to_string(_value_to_any(self), {}, 0)) + + +@add_method(TimeTransform) +def to_dict(self): + """ + Convert to a built-in dict. It will recursively convert all values + to their corresponding python built-in types. + """ + return json.loads(_otio._serialize_json_to_string(_value_to_any(self), {}, 0)) From cf764ee5525c4122b004ddfc02ba7fcf6cc18d6c Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin Date: Fri, 8 Mar 2024 19:43:50 -0500 Subject: [PATCH 2/3] Add tests Signed-off-by: Jean-Christophe Morin --- tests/test_core_utils.py | 52 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/test_core_utils.py b/tests/test_core_utils.py index 3c93330fb4..017830a56f 100644 --- a/tests/test_core_utils.py +++ b/tests/test_core_utils.py @@ -2,10 +2,13 @@ # Copyright Contributors to the OpenTimelineIO project import copy +import json import unittest import opentimelineio._otio import opentimelineio.core._core_utils +import opentimelineio.core +import opentimelineio.opentime class AnyDictionaryTests(unittest.TestCase): @@ -242,3 +245,52 @@ def test_copy(self): deepcopied = copy.deepcopy(v) self.assertIsNot(v, deepcopied) self.assertIsNot(v[2], deepcopied[2]) + + +class ConvertToPython(unittest.TestCase): + def test_SerializableObject(self): + so = opentimelineio.core.SerializableObjectWithMetadata(name="asd") + so.metadata["key1"] = opentimelineio.core.Composition() + + d = so.to_dict() + self.assertTrue(isinstance(d, dict)) + json.dumps(d) + + def test_AnyDictionary(self): + ad = opentimelineio._otio.AnyDictionary() + ad["my key"] = opentimelineio.core.Composable() + + d = ad.to_dict() + self.assertTrue(isinstance(d, dict)) + json.dumps(d) + + def test_AnyVector(self): + av = opentimelineio._otio.AnyVector() + av.append(1) + av.append(opentimelineio._otio.AnyDictionary()) + + l = av.to_list() + self.assertTrue(isinstance(l, list)) + self.assertEqual(l, [1, {}]) + json.dumps(l) + + def test_RationalTime(self): + rt = opentimelineio.opentime.RationalTime() + + d = rt.to_dict() + self.assertTrue(isinstance(d, dict)) + json.dumps(d) + + def test_TimeRange(self): + tr = opentimelineio.opentime.TimeRange() + + d = tr.to_dict() + self.assertTrue(isinstance(d, dict)) + json.dumps(d) + + def test_TimeTransform(self): + tt = opentimelineio.opentime.TimeTransform() + + d = tt.to_dict() + self.assertTrue(isinstance(d, dict)) + json.dumps(d) From d19d48708689a872297fe51ef7ee13e9ad28c6e8 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin Date: Fri, 8 Mar 2024 19:49:05 -0500 Subject: [PATCH 3/3] Fix linter warnings Signed-off-by: Jean-Christophe Morin --- .../opentimelineio/core/_core_utils.py | 24 ++++++------ tests/test_core_utils.py | 38 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/py-opentimelineio/opentimelineio/core/_core_utils.py b/src/py-opentimelineio/opentimelineio/core/_core_utils.py index 548a33fac9..2692bfab7f 100644 --- a/src/py-opentimelineio/opentimelineio/core/_core_utils.py +++ b/src/py-opentimelineio/opentimelineio/core/_core_utils.py @@ -396,8 +396,8 @@ def __copy__(self, *args, **kwargs): raise ValueError("SerializableObjects may not be shallow copied.") -@add_method(AnyDictionary) -def to_dict(self): +@add_method(AnyDictionary) # noqa: F811 +def to_dict(self): # noqa: F811 """ Convert to a built-in dict. It will recursively convert all values to their corresponding python built-in types. @@ -405,8 +405,8 @@ def to_dict(self): return json.loads(_otio._serialize_json_to_string(_value_to_any(self), {}, 0)) -@add_method(AnyVector) -def to_list(self): +@add_method(AnyVector) # noqa: F811 +def to_list(self): # noqa: F811 """ Convert to a built-in list. It will recursively convert all values to their corresponding python built-in types. @@ -414,8 +414,8 @@ def to_list(self): return json.loads(_otio._serialize_json_to_string(_value_to_any(self), {}, 0)) -@add_method(SerializableObject) -def to_dict(self): +@add_method(SerializableObject) # noqa: F811 +def to_dict(self): # noqa: F811 """ Convert to a built-in dict. It will recursively convert all values to their corresponding python built-in types. @@ -423,8 +423,8 @@ def to_dict(self): return json.loads(_otio._serialize_json_to_string(_value_to_any(self), {}, 0)) -@add_method(RationalTime) -def to_dict(self): +@add_method(RationalTime) # noqa: F811 +def to_dict(self): # noqa: F811 """ Convert to a built-in dict. It will recursively convert all values to their corresponding python built-in types. @@ -432,8 +432,8 @@ def to_dict(self): return json.loads(_otio._serialize_json_to_string(_value_to_any(self), {}, 0)) -@add_method(TimeRange) -def to_dict(self): +@add_method(TimeRange) # noqa: F811 +def to_dict(self): # noqa: F811 """ Convert to a built-in dict. It will recursively convert all values to their corresponding python built-in types. @@ -441,8 +441,8 @@ def to_dict(self): return json.loads(_otio._serialize_json_to_string(_value_to_any(self), {}, 0)) -@add_method(TimeTransform) -def to_dict(self): +@add_method(TimeTransform) # noqa: F811 +def to_dict(self): # noqa: F811 """ Convert to a built-in dict. It will recursively convert all values to their corresponding python built-in types. diff --git a/tests/test_core_utils.py b/tests/test_core_utils.py index 017830a56f..18bfc3bd6a 100644 --- a/tests/test_core_utils.py +++ b/tests/test_core_utils.py @@ -252,45 +252,45 @@ def test_SerializableObject(self): so = opentimelineio.core.SerializableObjectWithMetadata(name="asd") so.metadata["key1"] = opentimelineio.core.Composition() - d = so.to_dict() - self.assertTrue(isinstance(d, dict)) - json.dumps(d) + converted = so.to_dict() + self.assertTrue(isinstance(converted, dict)) + json.dumps(converted) def test_AnyDictionary(self): ad = opentimelineio._otio.AnyDictionary() ad["my key"] = opentimelineio.core.Composable() - d = ad.to_dict() - self.assertTrue(isinstance(d, dict)) - json.dumps(d) + converted = ad.to_dict() + self.assertTrue(isinstance(converted, dict)) + json.dumps(converted) def test_AnyVector(self): av = opentimelineio._otio.AnyVector() av.append(1) av.append(opentimelineio._otio.AnyDictionary()) - l = av.to_list() - self.assertTrue(isinstance(l, list)) - self.assertEqual(l, [1, {}]) - json.dumps(l) + converted = av.to_list() + self.assertTrue(isinstance(converted, list)) + self.assertEqual(converted, [1, {}]) + json.dumps(converted) def test_RationalTime(self): rt = opentimelineio.opentime.RationalTime() - d = rt.to_dict() - self.assertTrue(isinstance(d, dict)) - json.dumps(d) + converted = rt.to_dict() + self.assertTrue(isinstance(converted, dict)) + json.dumps(converted) def test_TimeRange(self): tr = opentimelineio.opentime.TimeRange() - d = tr.to_dict() - self.assertTrue(isinstance(d, dict)) - json.dumps(d) + converted = tr.to_dict() + self.assertTrue(isinstance(converted, dict)) + json.dumps(converted) def test_TimeTransform(self): tt = opentimelineio.opentime.TimeTransform() - d = tt.to_dict() - self.assertTrue(isinstance(d, dict)) - json.dumps(d) + converted = tt.to_dict() + self.assertTrue(isinstance(converted, dict)) + json.dumps(converted)