Skip to content

Commit

Permalink
Addressed python3 support. resolves #19 (#32)
Browse files Browse the repository at this point in the history
* Addressed python3 support. resolves #19

* Added unitests for comparison of TimeRange and TimeTransform and fixed inequality checks

* Added python3.5 to README and converted from io import StringIO to import io
  • Loading branch information
reinecke authored and ssteinbach committed Nov 10, 2016
1 parent 4ee8aa1 commit b56138a
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 9 deletions.
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
test:
python2.7 -m unittest discover tests

test3.5:
python3.5 -m unittest discover tests

# run all the unit tests, stopping at the first failure
test_first_fail:
python2.7 -m unittest discover tests --failfast
Expand All @@ -10,6 +13,10 @@ test_first_fail:
fast_test:
env OTIO_FAST_TEST=1 python2.7 -m unittest discover tests

# skip the timecode test that takes forever
fast_test3.5:
env OTIO_FAST_TEST=1 python3.5 -m unittest discover tests

# remove pyc files
clean:
rm */*.pyc */*/*.pyc
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Even though the project is python, we provide a makefile with some utility targe
Developing
----------

Currently the code base is written against python2.7. Before committing please run your changes through pep8/autopep8.
Currently the code base is written against python2.7 and python3.5. Before committing please run your changes through pep8/autopep8.

Contact
-------
Expand Down
6 changes: 3 additions & 3 deletions opentimelineio/adapters/cmx_3600.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def __init__(self, comments):
self._parse(comment)

def _parse(self, comment):
for comment_id, comment_type in self.comment_id_map.iteritems():
for comment_id, comment_type in self.comment_id_map.items():
regex = self._regex_template.format(id=comment_id)
if re.match(regex, comment):
self.handled[comment_type] = comment.split(':')[1].strip()
Expand All @@ -284,8 +284,8 @@ def read_from_string(input_str):
def write_to_string(input_otio):
# TODO: We should have convenience functions in Timeline for this?
# also only works for a single video track at the moment
video_tracks = filter(lambda t: t.kind == "Video", input_otio.tracks)
audio_tracks = filter(lambda t: t.kind == "Audio", input_otio.tracks)
video_tracks = list(filter(lambda t: t.kind == "Video", input_otio.tracks))
audio_tracks = list(filter(lambda t: t.kind == "Audio", input_otio.tracks))

if len(video_tracks) != 1:
raise otio.exceptions.NotSupportedError(
Expand Down
5 changes: 2 additions & 3 deletions opentimelineio/adapters/pretty_print_string.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"""
Adapter that prints to string.
"""

import StringIO
import io

import opentimelineio as otio

Expand Down Expand Up @@ -81,6 +80,6 @@ def from_base_object(base_object, indent=0):
)
)

result = StringIO.StringIO()
result = io.StringIO()
result.write('\n'.join(lines))
return result.getvalue()
35 changes: 33 additions & 2 deletions opentimelineio/opentime.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,39 @@ def __sub__(self, other):
value = (self.value_rescaled_to(scale) - other.value)
return RationalTime(value=value, rate=scale)

def __cmp__(self, other):
def _comparable_floats(self, other):
"""
returns a tuple of two floats, (self, other), which are suitable
for comparison.
If other is not of a type that can be compared, TypeError is raised
"""
if not isinstance(other, RationalTime):
raise TypeError(
"RationalTime can only be compared to other objects of type "
"RationalTime, not {}".format(type(other))
)
return cmp(
return (
float(self.value) / self.rate,
float(other.value) / other.rate
)

def __gt__(self, other):
f_self, f_other = self._comparable_floats(other)
return f_self > f_other

def __lt__(self, other):
f_self, f_other = self._comparable_floats(other)
return f_self < f_other

def __le__(self, other):
f_self, f_other = self._comparable_floats(other)
return f_self <= f_other

def __ge__(self, other):
f_self, f_other = self._comparable_floats(other)
return f_self >= f_other

def __repr__(self):
return (
"otio.opentime.RationalTime(value={value},"
Expand All @@ -101,6 +123,9 @@ def __eq__(self, other):
except AttributeError:
return False

def __ne__(self, other):
return not (self == other)

def __hash__(self):
return hash((self.value, self.rate))

Expand Down Expand Up @@ -169,6 +194,9 @@ def __eq__(self, other):
except AttributeError:
return False

def __ne__(self, other):
return not (self == other)

def __hash__(self):
return hash((self.offset, self.scale, self.rate))

Expand Down Expand Up @@ -340,6 +368,9 @@ def __eq__(self, rhs):
except AttributeError:
return False

def __ne__(self, rhs):
return not (self == rhs)

def __repr__(self):
return (
"otio.opentime.TimeRange(start_time={}, duration={})".format(
Expand Down
52 changes: 52 additions & 0 deletions tests/test_opentime.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,37 @@ def test_equality(self):
self.assertTrue(t1 is not t2)
self.assertEqual(t1, t2)

def test_inequality(self):
t1 = otio.opentime.RationalTime(30.2)
self.assertEqual(t1, t1)
t2 = otio.opentime.RationalTime(33.2)
self.assertTrue(t1 is not t2)
self.assertNotEqual(t1, t2)
t3 = otio.opentime.RationalTime(30.2)
self.assertTrue(t1 is not t3)
self.assertFalse(t1 != t3)

def test_comparison(self):
t1 = otio.opentime.RationalTime(15.2)
t2 = otio.opentime.RationalTime(15.6)
self.assertTrue(t1 < t2)
self.assertTrue(t1 <= t2)
self.assertFalse(t1 > t2)
self.assertFalse(t1 >= t2)

# Ensure the equality case of the comparisons works correctly
t3 = otio.opentime.RationalTime(30.4, 2)
self.assertTrue(t1 <= t3)
self.assertTrue(t1 >= t3)
self.assertTrue(t3 <= t1)
self.assertTrue(t3 >= t1)

# test implicit base conversion
t2 = otio.opentime.RationalTime(15.6, 48)
self.assertTrue(t1 > t2)
self.assertTrue(t1 >= t2)
self.assertFalse(t1 < t2)
self.assertFalse(t1 <= t2)

def test_base_conversion(self):

Expand Down Expand Up @@ -297,6 +320,19 @@ def test_hash(self):
txform2 = otio.opentime.TimeTransform(offset=tstart, scale=2, rate=10)
self.assertNotEqual(hash(txform), hash(txform2))

def test_comparison(self):
tstart = otio.opentime.RationalTime(12, 25)
txform = otio.opentime.TimeTransform(offset=tstart, scale=2)
tstart = otio.opentime.RationalTime(12, 25)
txform2 = otio.opentime.TimeTransform(offset=tstart, scale=2)
self.assertEqual(txform, txform2)
self.assertFalse(txform != txform2)

tstart = otio.opentime.RationalTime(23, 25)
txform3 = otio.opentime.TimeTransform(offset=tstart, scale=2)
self.assertNotEqual(txform, txform3)
self.assertFalse(txform == txform3)


class TestTimeRange(unittest.TestCase):

Expand Down Expand Up @@ -348,6 +384,22 @@ def test_repr(self):
"duration=otio.opentime.RationalTime(value=6, rate=24))"
)

def test_compare(self):
start_time1 = otio.opentime.RationalTime(18, 24)
duration1 = otio.opentime.RationalTime(7, 24)
tr1 = otio.opentime.TimeRange(start_time1, duration1)
start_time2 = otio.opentime.RationalTime(18, 24)
duration2 = otio.opentime.RationalTime(14, 48)
tr2 = otio.opentime.TimeRange(start_time2, duration2)
self.assertEqual(tr1, tr2)
self.assertFalse(tr1 != tr2)

start_time3 = otio.opentime.RationalTime(20, 24)
duration3 = otio.opentime.RationalTime(3, 24)
tr3 = otio.opentime.TimeRange(start_time3, duration3)
self.assertNotEqual(tr1, tr3)
self.assertFalse(tr1 == tr3)

def test_clamped(self):
test_point_min = otio.opentime.RationalTime(-2, 24)
test_point_max = otio.opentime.RationalTime(6, 24)
Expand Down

0 comments on commit b56138a

Please sign in to comment.