-
Notifications
You must be signed in to change notification settings - Fork 294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow to construct AnyVector and AnyDictionary with values from Python #1574
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
import unittest | ||
|
||
import opentimelineio._otio | ||
import opentimelineio.opentime | ||
import opentimelineio.core._core_utils | ||
|
||
|
||
|
@@ -61,6 +62,42 @@ def test_raise_on_mutation_during_iter(self): | |
for key in d: | ||
del d['b'] | ||
|
||
def test_construct_with_values(self): | ||
d1 = opentimelineio.core._core_utils.AnyDictionary( | ||
{'key1': 1234, 'key_2': {'asdasdasd': 5.6}} | ||
) | ||
v = opentimelineio.core._core_utils.AnyVector() | ||
v.append(1) | ||
v.append('inside any vector') | ||
|
||
so = opentimelineio._otio.SerializableObject() | ||
d2 = opentimelineio.core._core_utils.AnyDictionary( | ||
{ | ||
'string': 'myvalue', | ||
'int': -999999999999, | ||
'list': [1, 2.5, 'asd'], | ||
'dict': {'map1': [345]}, | ||
'AnyVector': v, | ||
'AnyDictionary': d1, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. related to the question about copies, can you edit d1 in place and have d2["AnyDictionary"] change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Items removed or added in d1 in place won't be added/removed in d2, but values are shared. As far as I see, this is an existing behavior. For example, this passes: def test_construct_with_values(self):
# Contruct with values
d1 = opentimelineio.core._core_utils.AnyDictionary(
{'key1': 1234, 'key_2': {'asdasdasd': 5.6}}
)
# Construct without values and only add a value after instantiation.
d3 = opentimelineio.core._core_utils.AnyDictionary()
d3['key4'] = 'value4'
# Create an SO and add it to d1 and d3.
so = opentimelineio._otio.SerializableObjectWithMetadata('initial name')
d1['so'] = so
d3['so'] = so
d2 = opentimelineio.core._core_utils.AnyDictionary(
{
'd1': d1,
'd3': d3,
'so': so
}
)
self.assertEqual(d2['d1'], d1)
self.assertEqual(d2['d3'], d3)
# Edit d1 in place
d1['key3'] = 'value3'
d1['so'].name = 'new name set on d1["so"]'
# Confirm that d2['d1'] is not updated
self.assertEqual(d2['d1'], {'key1': 1234, 'key_2': {'asdasdasd': 5.6}, 'so': so})
self.assertEqual(d1, {'key1': 1234, 'key_2': {'asdasdasd': 5.6}, 'key3': 'value3', 'so': so})
# But values that were already there are shared.
# We previously updated the name of so by doing d1['so'].name = '...'
# and d2['so'] got updated.
self.assertEqual(d2['so'].name, 'new name set on d1["so"]')
# Same behavior here.
d3['key5'] = 'value5'
d3['so'].name = 'new name set on d3["so"]'
self.assertEqual(d2['d3'], {'key4': 'value4', 'so': so})
self.assertEqual(d3, {'key4': 'value4', 'key5': 'value5', 'so': so})
self.assertEqual(d2['so'].name, 'new name set on d3["so"]') There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But just to be sure, I'll do some A/B testing with the main branch. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same result on the main branch (with slight modification in the code example to not construct with values): def test_construct_with_values(self):
d1 = opentimelineio.core._core_utils.AnyDictionary()
d1['key1'] = 1234
d1['key_2'] = {'asdasdasd': 5.6}
# Construct without values and only add a value after instantiation.
d3 = opentimelineio.core._core_utils.AnyDictionary()
d3['key4'] = 'value4'
# Create an SO and add it to d1 and d3.
so = opentimelineio._otio.SerializableObjectWithMetadata('initial name')
d1['so'] = so
d3['so'] = so
d2 = opentimelineio.core._core_utils.AnyDictionary()
d2['d1'] = d1
d2['d3'] = d3
d2['so'] = so
self.assertEqual(d2['d1'], d1)
self.assertEqual(d2['d3'], d3)
# Edit d1 in place
d1['key3'] = 'value3'
d1['so'].name = 'new name set on d1["so"]'
# Confirm that d2['d1'] is not updated
self.assertEqual(d2['d1'], {'key1': 1234, 'key_2': {'asdasdasd': 5.6}, 'so': so})
self.assertEqual(d1, {'key1': 1234, 'key_2': {'asdasdasd': 5.6}, 'key3': 'value3', 'so': so})
# But values that were already there are shared.
# We previously updated the name of so by doing d1['so'].name = '...'
# and d2['so'] got updated.
self.assertEqual(d2['so'].name, 'new name set on d1["so"]')
# Same behavior here.
d3['key5'] = 'value5'
d3['so'].name = 'new name set on d3["so"]'
self.assertEqual(d2['d3'], {'key4': 'value4', 'so': so})
self.assertEqual(d3, {'key4': 'value4', 'key5': 'value5', 'so': so})
self.assertEqual(d2['so'].name, 'new name set on d3["so"]') |
||
'RationalTime': opentimelineio.opentime.RationalTime( | ||
value=10.0, | ||
rate=5.0 | ||
), | ||
'TimeRange': opentimelineio.opentime.TimeRange( | ||
opentimelineio.opentime.RationalTime(value=1.0), | ||
opentimelineio.opentime.RationalTime(value=100.0) | ||
), | ||
'TimeTransform': opentimelineio.opentime.TimeTransform( | ||
offset=opentimelineio.opentime.RationalTime(value=55.0), | ||
scale=999 | ||
), | ||
'SerializableObject': so | ||
} | ||
) | ||
self.assertEqual(d2['string'], 'myvalue') | ||
self.assertEqual(d2['SerializableObject'], so) | ||
self.assertEqual(d2['AnyDictionary'], d1) | ||
|
||
def test_raises_if_ref_destroyed(self): | ||
d1 = opentimelineio.core._core_utils.AnyDictionary() | ||
opentimelineio._otio._testing.test_AnyDictionary_destroy(d1) | ||
|
@@ -196,6 +233,41 @@ def test_main(self): | |
# Appending copies data, completely removing references to it. | ||
self.assertIsNot(v5[0], tmplist) | ||
|
||
def test_construct_with_values(self): | ||
d = opentimelineio.core._core_utils.AnyDictionary() | ||
d['key_1'] = 1234 | ||
d['key_2'] = {'asdasdasd': 5.6} | ||
|
||
v1 = opentimelineio.core._core_utils.AnyVector([1, 'inside any vector']) | ||
|
||
so = opentimelineio._otio.SerializableObject() | ||
v2 = opentimelineio.core._core_utils.AnyVector( | ||
[ | ||
'myvalue', | ||
-999999999999, | ||
[1, 2.5, 'asd'], | ||
{'map1': [345]}, | ||
v1, | ||
d, | ||
opentimelineio.opentime.RationalTime( | ||
value=10.0, | ||
rate=5.0 | ||
), | ||
opentimelineio.opentime.TimeRange( | ||
opentimelineio.opentime.RationalTime(value=1.0), | ||
opentimelineio.opentime.RationalTime(value=100.0) | ||
), | ||
opentimelineio.opentime.TimeTransform( | ||
offset=opentimelineio.opentime.RationalTime(value=55.0), | ||
scale=999 | ||
), | ||
so | ||
] | ||
) | ||
self.assertEqual(v2[0], 'myvalue') | ||
self.assertEqual(v2[-1], so) | ||
self.assertEqual(v2[5], d) | ||
|
||
def test_raises_if_ref_destroyed(self): | ||
v1 = opentimelineio.core._core_utils.AnyVector() | ||
opentimelineio._otio._testing.test_AnyVector_destroy(v1) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this copying the data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If by data you mean everything (like a deep copy in Python), no. If you mean the top level list/vector, yes. See https://github.com/AcademySoftwareFoundation/OpenTimelineIO/pull/1574/files#r1165693980.
What should be the behavior?