aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/pyexiv2.py27
-rw-r--r--unittest/exif.py38
-rw-r--r--unittest/rational.py4
3 files changed, 68 insertions, 1 deletions
diff --git a/src/pyexiv2.py b/src/pyexiv2.py
index 4f23757..9102011 100644
--- a/src/pyexiv2.py
+++ b/src/pyexiv2.py
@@ -283,6 +283,7 @@ def StringToTime(string):
return localTime
+
class Rational(object):
"""
@@ -485,6 +486,16 @@ class ExifTag(MetadataTag):
except ValueError:
raise ExifValueError(value, xtype)
+ elif xtype in ('Rational', 'SRational'):
+ try:
+ r = Rational.from_string(value)
+ except (ValueError, ZeroDivisionError):
+ raise ExifValueError(value, xtype)
+ else:
+ if xtype == 'Rational' and r.numerator < 0:
+ raise ExifValueError(value, xtype)
+ return r
+
elif xtype == 'Undefined':
try:
return unicode(fvalue, 'utf-8')
@@ -543,6 +554,22 @@ class ExifTag(MetadataTag):
else:
raise ExifValueError(value, xtype)
+ elif xtype == 'Rational':
+ if type(value) is Rational and value.numerator >= 0:
+ return str(value)
+ else:
+ raise ExifValueError(value, xtype)
+
+ elif xtype == 'SRational':
+ if type(value) is Rational:
+ return str(value)
+ else:
+ raise ExifValueError(value, xtype)
+
+ elif xtype == 'Undefined':
+ # TODO
+ raise NotImplementedError('EXIF conversion for type [%s]' % xtype)
+
# TODO: other types
raise ExifValueError(value, xtype)
diff --git a/unittest/exif.py b/unittest/exif.py
index 86eab63..0f7df8f 100644
--- a/unittest/exif.py
+++ b/unittest/exif.py
@@ -25,7 +25,7 @@
# ******************************************************************************
import unittest
-from pyexiv2 import ExifTag, ExifValueError
+from pyexiv2 import ExifTag, ExifValueError, Rational
import datetime
@@ -129,6 +129,42 @@ class TestExifTag(unittest.TestCase):
self.failUnlessRaises(ExifValueError, ExifTag._convert_to_string, 'invalid', xtype)
self.failUnlessRaises(ExifValueError, ExifTag._convert_to_string, 3.14, xtype)
+ def test_convert_to_python_rational(self):
+ xtype = 'Rational'
+ # Valid values
+ self.assertEqual(ExifTag._convert_to_python('5/3', xtype, None), Rational(5, 3))
+ # Invalid values
+ self.failUnlessRaises(ExifValueError, ExifTag._convert_to_python, 'invalid', xtype, None)
+ self.failUnlessRaises(ExifValueError, ExifTag._convert_to_python, '-5/3', xtype, None)
+ self.failUnlessRaises(ExifValueError, ExifTag._convert_to_python, '5 / 3', xtype, None)
+ self.failUnlessRaises(ExifValueError, ExifTag._convert_to_python, '5/-3', xtype, None)
+
+ def test_convert_to_string_rational(self):
+ xtype = 'Rational'
+ # Valid values
+ self.assertEqual(ExifTag._convert_to_string(Rational(5, 3), xtype), '5/3')
+ # Invalid values
+ self.failUnlessRaises(ExifValueError, ExifTag._convert_to_string, 'invalid', xtype)
+ self.failUnlessRaises(ExifValueError, ExifTag._convert_to_string, Rational(-5, 3), xtype)
+
+ def test_convert_to_python_srational(self):
+ xtype = 'SRational'
+ # Valid values
+ self.assertEqual(ExifTag._convert_to_python('5/3', xtype, None), Rational(5, 3))
+ self.assertEqual(ExifTag._convert_to_python('-5/3', xtype, None), Rational(-5, 3))
+ # Invalid values
+ self.failUnlessRaises(ExifValueError, ExifTag._convert_to_python, 'invalid', xtype, None)
+ self.failUnlessRaises(ExifValueError, ExifTag._convert_to_python, '5 / 3', xtype, None)
+ self.failUnlessRaises(ExifValueError, ExifTag._convert_to_python, '5/-3', xtype, None)
+
+ def test_convert_to_string_srational(self):
+ xtype = 'SRational'
+ # Valid values
+ self.assertEqual(ExifTag._convert_to_string(Rational(5, 3), xtype), '5/3')
+ self.assertEqual(ExifTag._convert_to_string(Rational(-5, 3), xtype), '-5/3')
+ # Invalid values
+ self.failUnlessRaises(ExifValueError, ExifTag._convert_to_string, 'invalid', xtype)
+
def test_convert_to_python_undefined(self):
xtype = 'Undefined'
# Valid values
diff --git a/unittest/rational.py b/unittest/rational.py
index f475846..81edfb9 100644
--- a/unittest/rational.py
+++ b/unittest/rational.py
@@ -44,6 +44,10 @@ class TestRational(unittest.TestCase):
self.assertRaises(ValueError, Rational.from_string, '3/-5')
self.assertRaises(ValueError, Rational.from_string, 'invalid')
+ def test_to_string(self):
+ self.assertEqual(str(Rational(3, 5)), '3/5')
+ self.assertEqual(str(Rational(-3, 5)), '-3/5')
+
def test_equality(self):
r1 = Rational(2, 1)
r2 = Rational(2, 1)