aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Tilloy <olivier@tilloy.net>2010-12-26 21:09:29 +0100
committerOlivier Tilloy <olivier@tilloy.net>2010-12-26 21:09:29 +0100
commit71116952f8a4714228155c755b55e588e17d5e6b (patch)
tree1b20734e849b77da34fdef024efb214b4576f73e
parent27f94886b6c043609366dd2f5604566d1264852d (diff)
parent3ece0524d87364f9edb40b70b95d8c39937572b9 (diff)
downloadpyexiv2-71116952f8a4714228155c755b55e588e17d5e6b.tar.gz
Use fractions.Fraction when available in the standard library (Python ≥ 2.6),
or fallback on the custom Rational class in a transparent manner.
-rw-r--r--src/pyexiv2/exif.py18
-rw-r--r--src/pyexiv2/utils.py54
-rw-r--r--src/pyexiv2/xmp.py10
-rw-r--r--test/ReadMetadataTestCase.py61
-rwxr-xr-xtest/TestsRunner.py3
-rw-r--r--test/exif.py21
-rw-r--r--test/metadata.py4
-rw-r--r--test/pickling.py8
-rw-r--r--test/utils.py50
-rw-r--r--test/xmp.py13
10 files changed, 158 insertions, 84 deletions
diff --git a/src/pyexiv2/exif.py b/src/pyexiv2/exif.py
index 4f3fe03..b0c6374 100644
--- a/src/pyexiv2/exif.py
+++ b/src/pyexiv2/exif.py
@@ -30,7 +30,7 @@ EXIF specific code.
import libexiv2python
-from pyexiv2.utils import Rational, Fraction, \
+from pyexiv2.utils import is_fraction, make_fraction, fraction_to_string, \
NotifyingList, ListenerInterface, \
undefined_to_string, string_to_undefined
@@ -72,7 +72,8 @@ class ExifTag(ListenerInterface):
- Comment: string
- Long, SLong: [list of] long
- Short, SShort: [list of] int
- - Rational, SRational: [list of] :class:`pyexiv2.utils.Rational`
+ - Rational, SRational: [list of] :class:`fractions.Fraction` if available
+ (Python ≥ 2.6) or :class:`pyexiv2.utils.Rational`
- Undefined: string
"""
@@ -316,7 +317,7 @@ class ExifTag(ListenerInterface):
elif self.type in ('Rational', 'SRational'):
try:
- r = Rational.from_string(value)
+ r = make_fraction(value)
except (ValueError, ZeroDivisionError):
raise ExifValueError(value, self.type)
else:
@@ -424,17 +425,14 @@ class ExifTag(ListenerInterface):
raise ExifValueError(value, self.type)
elif self.type == 'Rational':
- if (isinstance(value, Rational) or \
- (Fraction is not None and isinstance(value, Fraction))) \
- and value.numerator >= 0:
- return str(value)
+ if is_fraction(value) and value.numerator >= 0:
+ return fraction_to_string(value)
else:
raise ExifValueError(value, self.type)
elif self.type == 'SRational':
- if isinstance(value, Rational) or \
- (Fraction is not None and isinstance(value, Fraction)):
- return str(value)
+ if is_fraction(value):
+ return fraction_to_string(value)
else:
raise ExifValueError(value, self.type)
diff --git a/src/pyexiv2/utils.py b/src/pyexiv2/utils.py
index 5b0a3d5..4fcebf9 100644
--- a/src/pyexiv2/utils.py
+++ b/src/pyexiv2/utils.py
@@ -31,11 +31,10 @@ Utilitary classes and functions.
import datetime
import re
-# Support for fractions.Fraction as a replacement for the Rational class is not
-# implemented yet as we have to support versions of Python < 2.6
-# (see https://launchpad.net/bugs/514415).
-# However, it doesn’t hurt to accept Fraction objects as values when the module
-# is available (see https://launchpad.net/bugs/683232).
+# pyexiv2 uses fractions.Fraction when available (Python ≥ 2.6), or falls back
+# on the custom Rational class. This should be transparent to the application
+# developer as both classes have a similar API.
+# This module contains convenience functions to ease manipulation of fractions.
try:
from fractions import Fraction
except ImportError:
@@ -250,6 +249,51 @@ class Rational(object):
return '%d/%d' % (self._numerator, self._denominator)
+def is_fraction(obj):
+ """
+ Test whether the object is a valid fraction.
+ """
+ if Fraction is not None and isinstance(obj, Fraction):
+ return True
+ elif isinstance(obj, Rational):
+ return True
+ else:
+ return False
+
+
+def make_fraction(*args):
+ """
+ Make a fraction.
+
+ The type of the returned object depends on the availability of the
+ fractions module in the standard library (Python ≥ 2.6).
+ """
+ if Fraction is not None:
+ return Fraction(*args)
+ else:
+ if len(args) == 1:
+ return Rational.from_string(*args)
+ else:
+ return Rational(*args)
+
+
+def fraction_to_string(fraction):
+ """
+ Return a string representation of a fraction, suitable to pass to libexiv2.
+
+ The returned string is always in the form '[numerator]/[denominator]'.
+
+ :raise TypeError: if the argument is not a valid fraction
+ """
+ if Fraction is not None and isinstance(fraction, Fraction):
+ # fractions.Fraction.__str__ returns '0' for a null numerator.
+ return '%s/%s' % (fraction.numerator, fraction.denominator)
+ elif isinstance(fraction, Rational):
+ return str(fraction)
+ else:
+ raise TypeError('Not a fraction')
+
+
class ListenerInterface(object):
"""
diff --git a/src/pyexiv2/xmp.py b/src/pyexiv2/xmp.py
index ab2edeb..469af98 100644
--- a/src/pyexiv2/xmp.py
+++ b/src/pyexiv2/xmp.py
@@ -30,7 +30,7 @@ XMP specific code.
import libexiv2python
-from pyexiv2.utils import FixedOffset, Rational, Fraction, GPSCoordinate
+from pyexiv2.utils import FixedOffset, is_fraction, make_fraction, GPSCoordinate
import datetime
import re
@@ -74,7 +74,8 @@ class XmpTag(object):
- Integer: int
- Locale: *[not implemented yet]*
- MIMEType: 2-tuple of strings
- - Rational: :class:`pyexiv2.utils.Rational`
+ - Rational: :class:`fractions.Fraction` if available (Python ≥ 2.6) or
+ :class:`pyexiv2.utils.Rational`
- Real: *[not implemented yet]*
- AgentName, ProperName, Text: unicode string
- Thumbnail: *[not implemented yet]*
@@ -338,7 +339,7 @@ class XmpTag(object):
elif type == 'Rational':
try:
- return Rational.from_string(value)
+ return make_fraction(value)
except (ValueError, ZeroDivisionError):
raise XmpValueError(value, type)
@@ -435,8 +436,7 @@ class XmpTag(object):
raise XmpValueError(value, type)
elif type == 'Rational':
- if isinstance(value, Rational) or \
- (Fraction is not None and isinstance(value, Fraction)):
+ if is_fraction(value):
return str(value)
else:
raise XmpValueError(value, type)
diff --git a/test/ReadMetadataTestCase.py b/test/ReadMetadataTestCase.py
index 40f0843..3bf8e09 100644
--- a/test/ReadMetadataTestCase.py
+++ b/test/ReadMetadataTestCase.py
@@ -25,12 +25,19 @@
#
# ******************************************************************************
+import pyexiv2
+from pyexiv2.utils import is_fraction, make_fraction
+
import unittest
-import testutils
import os.path
-import pyexiv2
import datetime
+import testutils
+
+
+FRACTION = 'fraction'
+
+
class ReadMetadataTestCase(unittest.TestCase):
"""
@@ -38,7 +45,10 @@ class ReadMetadataTestCase(unittest.TestCase):
"""
def check_type_and_value(self, tag, etype, evalue):
- self.assert_(isinstance(tag.value, etype))
+ if etype == FRACTION:
+ self.assert_(is_fraction(tag.value))
+ else:
+ self.assert_(isinstance(tag.value, etype))
self.assertEqual(tag.value, evalue)
def check_type_and_values(self, tag, etype, evalues):
@@ -68,8 +78,8 @@ class ReadMetadataTestCase(unittest.TestCase):
# Exhaustive tests on the values of EXIF metadata
exifTags = [('Exif.Image.ImageDescription', str, 'Well it is a smiley that happens to be green'),
- ('Exif.Image.XResolution', pyexiv2.Rational, pyexiv2.Rational(72, 1)),
- ('Exif.Image.YResolution', pyexiv2.Rational, pyexiv2.Rational(72, 1)),
+ ('Exif.Image.XResolution', FRACTION, make_fraction(72, 1)),
+ ('Exif.Image.YResolution', FRACTION, make_fraction(72, 1)),
('Exif.Image.ResolutionUnit', int, 2),
('Exif.Image.Software', str, 'ImageReady'),
('Exif.Image.DateTime', datetime.datetime, datetime.datetime(2004, 7, 13, 21, 23, 44)),
@@ -115,36 +125,22 @@ class ReadMetadataTestCase(unittest.TestCase):
('Xmp.dc.source', unicode, u'FreeFoto.com'),
('Xmp.dc.subject', list, [u'Communications']),
('Xmp.dc.title', dict, {u'x-default': u'Communications'}),
- ('Xmp.exif.ApertureValue',
- pyexiv2.utils.Rational,
- pyexiv2.utils.Rational(8, 1)),
- ('Xmp.exif.BrightnessValue',
- pyexiv2.utils.Rational,
- pyexiv2.utils.Rational(333, 1280)),
+ ('Xmp.exif.ApertureValue', FRACTION, make_fraction(8, 1)),
+ ('Xmp.exif.BrightnessValue', FRACTION, make_fraction(333, 1280)),
('Xmp.exif.ColorSpace', int, 1),
('Xmp.exif.DateTimeOriginal',
datetime.datetime,
datetime.datetime(2002, 7, 13, 15, 58, 28, tzinfo=pyexiv2.utils.FixedOffset())),
('Xmp.exif.ExifVersion', unicode, u'0200'),
- ('Xmp.exif.ExposureBiasValue',
- pyexiv2.utils.Rational,
- pyexiv2.utils.Rational(-13, 20)),
+ ('Xmp.exif.ExposureBiasValue', FRACTION, make_fraction(-13, 20)),
('Xmp.exif.ExposureProgram', int, 4),
- ('Xmp.exif.FNumber',
- pyexiv2.utils.Rational,
- pyexiv2.utils.Rational(3, 5)),
+ ('Xmp.exif.FNumber', FRACTION, make_fraction(3, 5)),
('Xmp.exif.FileSource', int, 0),
('Xmp.exif.FlashpixVersion', unicode, u'0100'),
- ('Xmp.exif.FocalLength',
- pyexiv2.utils.Rational,
- pyexiv2.utils.Rational(0, 1)),
+ ('Xmp.exif.FocalLength', FRACTION, make_fraction(0, 1)),
('Xmp.exif.FocalPlaneResolutionUnit', int, 2),
- ('Xmp.exif.FocalPlaneXResolution',
- pyexiv2.utils.Rational,
- pyexiv2.utils.Rational(3085, 256)),
- ('Xmp.exif.FocalPlaneYResolution',
- pyexiv2.utils.Rational,
- pyexiv2.utils.Rational(3085, 256)),
+ ('Xmp.exif.FocalPlaneXResolution', FRACTION, make_fraction(3085, 256)),
+ ('Xmp.exif.FocalPlaneYResolution', FRACTION, make_fraction(3085, 256)),
('Xmp.exif.GPSLatitude',
pyexiv2.utils.GPSCoordinate,
pyexiv2.utils.GPSCoordinate.from_string('54,59.380000N')),
@@ -162,9 +158,7 @@ class ReadMetadataTestCase(unittest.TestCase):
('Xmp.exif.PixelYDimension', int, 1600),
('Xmp.exif.SceneType', int, 0),
('Xmp.exif.SensingMethod', int, 2),
- ('Xmp.exif.ShutterSpeedValue',
- pyexiv2.utils.Rational,
- pyexiv2.utils.Rational(30827, 3245)),
+ ('Xmp.exif.ShutterSpeedValue', FRACTION, make_fraction(30827, 3245)),
('Xmp.pdf.Keywords', unicode, u'Communications'),
('Xmp.photoshop.AuthorsPosition', unicode, u'Photographer'),
('Xmp.photoshop.CaptionWriter', unicode, u'Ian Britton'),
@@ -191,13 +185,9 @@ class ReadMetadataTestCase(unittest.TestCase):
('Xmp.tiff.Orientation', int, 1),
('Xmp.tiff.ResolutionUnit', int, 2),
('Xmp.tiff.Software', unicode, u'Adobe Photoshop 7.0'),
- ('Xmp.tiff.XResolution',
- pyexiv2.utils.Rational,
- pyexiv2.utils.Rational(300, 1)),
+ ('Xmp.tiff.XResolution', FRACTION, make_fraction(300, 1)),
('Xmp.tiff.YCbCrPositioning', int, 2),
- ('Xmp.tiff.YResolution',
- pyexiv2.utils.Rational,
- pyexiv2.utils.Rational(300, 1)),
+ ('Xmp.tiff.YResolution', FRACTION, make_fraction(300, 1)),
('Xmp.xmp.CreateDate',
datetime.datetime,
datetime.datetime(2002, 7, 13, 15, 58, 28, tzinfo=pyexiv2.utils.FixedOffset())),
@@ -215,3 +205,4 @@ class ReadMetadataTestCase(unittest.TestCase):
self.assertEqual(image.xmp_keys, [tag[0] for tag in xmpTags])
for key, ktype, value in xmpTags:
self.check_type_and_value(image[key], ktype, value)
+
diff --git a/test/TestsRunner.py b/test/TestsRunner.py
index 198bb27..ba5162c 100755
--- a/test/TestsRunner.py
+++ b/test/TestsRunner.py
@@ -38,7 +38,7 @@ from xmp import TestXmpTag, TestXmpNamespaces
from metadata import TestImageMetadata
from buffer import TestBuffer
from encoding import TestEncodings
-from utils import TestConversions
+from utils import TestConversions, TestFractions
from usercomment import TestUserCommentReadWrite, TestUserCommentAdd
from pickling import TestPicklingTags
@@ -58,6 +58,7 @@ def run_unit_tests():
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestBuffer))
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestEncodings))
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestConversions))
+ suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestFractions))
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestUserCommentReadWrite))
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestUserCommentAdd))
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestPicklingTags))
diff --git a/test/exif.py b/test/exif.py
index 1f929b7..38e19b7 100644
--- a/test/exif.py
+++ b/test/exif.py
@@ -27,7 +27,7 @@
import unittest
from pyexiv2.exif import ExifTag, ExifValueError
-from pyexiv2.utils import Rational, Fraction
+from pyexiv2.utils import make_fraction
import datetime
@@ -260,7 +260,7 @@ class TestExifTag(unittest.TestCase):
# Valid values
tag = ExifTag('Exif.Image.XResolution')
self.assertEqual(tag.type, 'Rational')
- self.assertEqual(tag._convert_to_python('5/3'), Rational(5, 3))
+ self.assertEqual(tag._convert_to_python('5/3'), make_fraction(5, 3))
# Invalid values
self.failUnlessRaises(ExifValueError, tag._convert_to_python, 'invalid')
@@ -272,21 +272,19 @@ class TestExifTag(unittest.TestCase):
# Valid values
tag = ExifTag('Exif.Image.XResolution')
self.assertEqual(tag.type, 'Rational')
- self.assertEqual(tag._convert_to_string(Rational(5, 3)), '5/3')
- if Fraction is not None:
- self.assertEqual(tag._convert_to_string(Fraction('1.6')), '8/5')
+ self.assertEqual(tag._convert_to_string(make_fraction(5, 3)), '5/3')
# Invalid values
self.failUnlessRaises(ExifValueError, tag._convert_to_string, 'invalid')
self.failUnlessRaises(ExifValueError,
- tag._convert_to_string, Rational(-5, 3))
+ tag._convert_to_string, make_fraction(-5, 3))
def test_convert_to_python_srational(self):
# Valid values
tag = ExifTag('Exif.Image.BaselineExposure')
self.assertEqual(tag.type, 'SRational')
- self.assertEqual(tag._convert_to_python('5/3'), Rational(5, 3))
- self.assertEqual(tag._convert_to_python('-5/3'), Rational(-5, 3))
+ self.assertEqual(tag._convert_to_python('5/3'), make_fraction(5, 3))
+ self.assertEqual(tag._convert_to_python('-5/3'), make_fraction(-5, 3))
# Invalid values
self.failUnlessRaises(ExifValueError, tag._convert_to_python, 'invalid')
@@ -297,11 +295,8 @@ class TestExifTag(unittest.TestCase):
# Valid values
tag = ExifTag('Exif.Image.BaselineExposure')
self.assertEqual(tag.type, 'SRational')
- self.assertEqual(tag._convert_to_string(Rational(5, 3)), '5/3')
- self.assertEqual(tag._convert_to_string(Rational(-5, 3)), '-5/3')
- if Fraction is not None:
- self.assertEqual(tag._convert_to_string(Fraction('1.6')), '8/5')
- self.assertEqual(tag._convert_to_string(Fraction('-1.6')), '-8/5')
+ self.assertEqual(tag._convert_to_string(make_fraction(5, 3)), '5/3')
+ self.assertEqual(tag._convert_to_string(make_fraction(-5, 3)), '-5/3')
# Invalid values
self.failUnlessRaises(ExifValueError, tag._convert_to_string, 'invalid')
diff --git a/test/metadata.py b/test/metadata.py
index bc4d1ff..177ec9d 100644
--- a/test/metadata.py
+++ b/test/metadata.py
@@ -28,7 +28,7 @@ from pyexiv2.metadata import ImageMetadata
from pyexiv2.exif import ExifTag
from pyexiv2.iptc import IptcTag
from pyexiv2.xmp import XmpTag
-from pyexiv2.utils import FixedOffset, Rational
+from pyexiv2.utils import FixedOffset, make_fraction
import datetime
import os
@@ -501,7 +501,7 @@ class TestImageMetadata(unittest.TestCase):
self.metadata.read()
# Set new tags
key = 'Exif.Photo.ExposureBiasValue'
- tag = ExifTag(key, Rational(0, 3))
+ tag = ExifTag(key, make_fraction(0, 3))
self.metadata[key] = tag
self.failUnless(key in self.metadata._tags['exif'])
self.failUnlessEqual(self.metadata._tags['exif'][key], tag)
diff --git a/test/pickling.py b/test/pickling.py
index d98c146..8d0101b 100644
--- a/test/pickling.py
+++ b/test/pickling.py
@@ -27,7 +27,7 @@
from pyexiv2.exif import ExifTag
from pyexiv2.iptc import IptcTag
from pyexiv2.xmp import XmpTag
-from pyexiv2.utils import Rational, FixedOffset
+from pyexiv2.utils import make_fraction, FixedOffset
import unittest
import pickle
@@ -49,8 +49,8 @@ class TestPicklingTags(unittest.TestCase):
tags.append(ExifTag('Exif.Image.TimeZoneOffset', 7))
tags.append(ExifTag('Exif.Image.ImageWidth', 7492))
tags.append(ExifTag('Exif.OlympusCs.ManometerReading', 29))
- tags.append(ExifTag('Exif.Image.XResolution', Rational(7, 3)))
- tags.append(ExifTag('Exif.Image.BaselineExposure', Rational(-7, 3)))
+ tags.append(ExifTag('Exif.Image.XResolution', make_fraction(7, 3)))
+ tags.append(ExifTag('Exif.Image.BaselineExposure', make_fraction(-7, 3)))
tags.append(ExifTag('Exif.Photo.ExifVersion', '0100'))
for tag in tags:
s = pickle.dumps(tag)
@@ -102,7 +102,7 @@ class TestPicklingTags(unittest.TestCase):
tags.append(XmpTag('Xmp.dc.source', 'bleh'))
tags.append(XmpTag('Xmp.xmpMM.DocumentID', 'http://example.com'))
tags.append(XmpTag('Xmp.xmp.BaseURL', 'http://example.com'))
- tags.append(XmpTag('Xmp.xmpDM.videoPixelAspectRatio', Rational(5, 3)))
+ tags.append(XmpTag('Xmp.xmpDM.videoPixelAspectRatio', make_fraction(5, 3)))
for tag in tags:
s = pickle.dumps(tag)
t = pickle.loads(s)
diff --git a/test/utils.py b/test/utils.py
index 2f0d19b..11b1766 100644
--- a/test/utils.py
+++ b/test/utils.py
@@ -26,7 +26,9 @@
import unittest
-from pyexiv2.utils import undefined_to_string, string_to_undefined
+from pyexiv2.utils import undefined_to_string, string_to_undefined, \
+ Rational, Fraction, \
+ is_fraction, make_fraction, fraction_to_string
class TestConversions(unittest.TestCase):
@@ -48,3 +50,49 @@ class TestConversions(unittest.TestCase):
value = "48 50 50 49"
self.assertEqual(string_to_undefined(undefined_to_string(value)), value)
+
+class TestFractions(unittest.TestCase):
+
+ def test_is_fraction(self):
+ if Fraction is not None:
+ self.failUnless(is_fraction(Fraction()))
+ self.failUnless(is_fraction(Fraction(3, 5)))
+ self.failUnless(is_fraction(Fraction(Fraction(4, 5))))
+ self.failUnless(is_fraction(Fraction('3/2')))
+ self.failUnless(is_fraction(Fraction('-4/5')))
+ self.failUnless(is_fraction(Rational(3, 5)))
+ self.failUnless(is_fraction(Rational(-4, 5)))
+ self.failUnless(is_fraction(Rational.from_string("3/5")))
+ self.failUnless(is_fraction(Rational.from_string("-4/5")))
+
+ self.failIf(is_fraction(3 / 5))
+ self.failIf(is_fraction('3/5'))
+ self.failIf(is_fraction('2.7'))
+ self.failIf(is_fraction(2.7))
+ self.failIf(is_fraction('notafraction'))
+ self.failIf(is_fraction(None))
+
+ def test_make_fraction(self):
+ if Fraction is not None:
+ self.assertEqual(make_fraction(3, 5), Fraction(3, 5))
+ self.assertEqual(make_fraction(-3, 5), Fraction(-3, 5))
+ self.assertEqual(make_fraction('3/2'), Fraction(3, 2))
+ self.assertEqual(make_fraction('-3/4'), Fraction(-3, 4))
+ else:
+ self.assertEqual(make_fraction(3, 5), Rational(3, 5))
+ self.assertEqual(make_fraction(-3, 5), Rational(-3, 5))
+ self.assertEqual(make_fraction('3/2'), Rational(3, 2))
+ self.assertEqual(make_fraction('-3/4'), Rational(-3, 4))
+
+ self.assertRaises(ZeroDivisionError, make_fraction, 3, 0)
+ self.assertRaises(ZeroDivisionError, make_fraction, '3/0')
+ self.assertRaises(TypeError, make_fraction, 5, 3, 2)
+ self.assertRaises(TypeError, make_fraction, None)
+
+ def test_fraction_to_string(self):
+ self.assertEqual(fraction_to_string(make_fraction(3, 5)), '3/5')
+ self.assertEqual(fraction_to_string(make_fraction(-3, 5)), '-3/5')
+ self.assertEqual(fraction_to_string(make_fraction(0, 1)), '0/1')
+ self.assertRaises(TypeError, fraction_to_string, None)
+ self.assertRaises(TypeError, fraction_to_string, 'invalid')
+
diff --git a/test/xmp.py b/test/xmp.py
index 3379851..f3fa4c3 100644
--- a/test/xmp.py
+++ b/test/xmp.py
@@ -28,7 +28,7 @@ import unittest
from pyexiv2.xmp import XmpTag, XmpValueError, register_namespace, \
unregister_namespace, unregister_namespaces
-from pyexiv2.utils import FixedOffset, Rational, Fraction
+from pyexiv2.utils import FixedOffset, make_fraction
from pyexiv2.metadata import ImageMetadata
import datetime
@@ -288,8 +288,8 @@ class TestXmpTag(unittest.TestCase):
# Valid values
tag = XmpTag('Xmp.xmpDM.videoPixelAspectRatio')
self.assertEqual(tag.type, 'Rational')
- self.assertEqual(tag._convert_to_python('5/3', 'Rational'), Rational(5, 3))
- self.assertEqual(tag._convert_to_python('-5/3', 'Rational'), Rational(-5, 3))
+ self.assertEqual(tag._convert_to_python('5/3', 'Rational'), make_fraction(5, 3))
+ self.assertEqual(tag._convert_to_python('-5/3', 'Rational'), make_fraction(-5, 3))
# Invalid values
self.failUnlessRaises(XmpValueError, tag._convert_to_python, 'invalid', 'Rational')
@@ -300,11 +300,8 @@ class TestXmpTag(unittest.TestCase):
# Valid values
tag = XmpTag('Xmp.xmpDM.videoPixelAspectRatio')
self.assertEqual(tag.type, 'Rational')
- self.assertEqual(tag._convert_to_string(Rational(5, 3), 'Rational'), '5/3')
- self.assertEqual(tag._convert_to_string(Rational(-5, 3), 'Rational'), '-5/3')
- if Fraction is not None:
- self.assertEqual(tag._convert_to_string(Fraction('1.6'), 'Rational'), '8/5')
- self.assertEqual(tag._convert_to_string(Fraction('-1.6'), 'Rational'), '-8/5')
+ self.assertEqual(tag._convert_to_string(make_fraction(5, 3), 'Rational'), '5/3')
+ self.assertEqual(tag._convert_to_string(make_fraction(-5, 3), 'Rational'), '-5/3')
# Invalid values
self.failUnlessRaises(XmpValueError, tag._convert_to_string, 'invalid', 'Rational')