From fa8a2a497ed8bf62bd53ff6198da62346c50af08 Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Wed, 17 Aug 2011 18:27:35 +0200 Subject: Add a unit test to check that using the dictionary interface with an incorrect tag family raises a KeyError as expected. --- test/metadata.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/metadata.py b/test/metadata.py index 177ec9d..a00d9fa 100644 --- a/test/metadata.py +++ b/test/metadata.py @@ -2,7 +2,7 @@ # ****************************************************************************** # -# Copyright (C) 2009-2010 Olivier Tilloy +# Copyright (C) 2009-2011 Olivier Tilloy # # This file is part of the pyexiv2 distribution. # @@ -564,6 +564,13 @@ class TestImageMetadata(unittest.TestCase): for key in keys: self.metadata[key] = self.metadata[key] + def test_nonexistent_tag_family(self): + self.metadata.read() + key = 'Bleh.Image.DateTime' + self.failUnlessRaises(KeyError, self.metadata.__getitem__, key) + self.failUnlessRaises(KeyError, self.metadata.__setitem__, key, datetime.date.today()) + self.failUnlessRaises(KeyError, self.metadata.__delitem__, key) + ########################## # Test the image comment # ########################## -- cgit From 63969fb0f481b739479993cb3b8c49248a263e8e Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Wed, 17 Aug 2011 18:34:10 +0200 Subject: White-list accepted tag families: 'exif', 'iptc', 'xmp'. Any other family will raise a KeyError. --- src/pyexiv2/metadata.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pyexiv2/metadata.py b/src/pyexiv2/metadata.py index 57c0263..e8ef875 100644 --- a/src/pyexiv2/metadata.py +++ b/src/pyexiv2/metadata.py @@ -205,9 +205,9 @@ class ImageMetadata(MutableMapping): :raise KeyError: if the tag doesn't exist """ family = key.split('.')[0].lower() - try: + if family in ('exif', 'iptc', 'xmp'): return getattr(self, '_get_%s_tag' % family)(key) - except AttributeError: + else: raise KeyError(key) def _set_exif_tag(self, key, tag_or_value): @@ -267,9 +267,9 @@ class ImageMetadata(MutableMapping): :raise KeyError: if the key is invalid """ family = key.split('.')[0].lower() - try: + if family in ('exif', 'iptc', 'xmp'): return getattr(self, '_set_%s_tag' % family)(key, tag_or_value) - except AttributeError: + else: raise KeyError(key) def _delete_exif_tag(self, key): @@ -326,9 +326,9 @@ class ImageMetadata(MutableMapping): :raise KeyError: if the tag with the given key doesn't exist """ family = key.split('.')[0].lower() - try: + if family in ('exif', 'iptc', 'xmp'): return getattr(self, '_delete_%s_tag' % family)(key) - except AttributeError: + else: raise KeyError(key) def __iter__(self): -- cgit From f58166679a8334bd9a75647a6bc4a0c227f7f254 Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Wed, 17 Aug 2011 18:35:49 +0200 Subject: Updated copyright header of the file modified in the previous revision. --- src/pyexiv2/metadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyexiv2/metadata.py b/src/pyexiv2/metadata.py index e8ef875..e758bfa 100644 --- a/src/pyexiv2/metadata.py +++ b/src/pyexiv2/metadata.py @@ -2,7 +2,7 @@ # ****************************************************************************** # -# Copyright (C) 2006-2010 Olivier Tilloy +# Copyright (C) 2006-2011 Olivier Tilloy # # This file is part of the pyexiv2 distribution. # -- cgit From 8f076d1fe72e3ad167bbbd29b076b88d7143ef3a Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Wed, 17 Aug 2011 18:56:52 +0200 Subject: Check the type before setting a tag’s value and raise a TypeError if it doesn’t match. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pyexiv2/xmp.py | 4 ++++ test/xmp.py | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/pyexiv2/xmp.py b/src/pyexiv2/xmp.py index bed1b66..2b3149e 100644 --- a/src/pyexiv2/xmp.py +++ b/src/pyexiv2/xmp.py @@ -218,11 +218,15 @@ class XmpTag(object): stype = stype[17:] self.raw_value = self._convert_to_string(value, stype) elif type in ('XmpAlt', 'XmpBag', 'XmpSeq'): + if not isinstance(value, (list, tuple)): + raise TypeError('Expecting a list of values') stype = self.type[4:] if stype.lower().startswith('closed choice of'): stype = stype[17:] self.raw_value = map(lambda x: self._convert_to_string(x, stype), value) elif type == 'LangAlt': + if not isinstance(value, dict): + raise TypeError('Expecting a dictionary mapping language codes to values') raw_value = {} for k, v in value.iteritems(): try: diff --git a/test/xmp.py b/test/xmp.py index 7e7522e..c0ea11f 100644 --- a/test/xmp.py +++ b/test/xmp.py @@ -2,7 +2,7 @@ # ****************************************************************************** # -# Copyright (C) 2009-2010 Olivier Tilloy +# Copyright (C) 2009-2011 Olivier Tilloy # # This file is part of the pyexiv2 distribution. # @@ -364,6 +364,16 @@ class TestXmpTag(unittest.TestCase): self.failUnlessEqual(tag.type, 'Lang Alt') self.failUnlessRaises(ValueError, tag._set_value, {}) + def test_set_value_incorrect_type(self): + # Expecting a list of values + tag = XmpTag('Xmp.dc.publisher') + self.failUnlessRaises(TypeError, tag._set_value, None) + self.failUnlessRaises(TypeError, tag._set_value, 'bleh') + # Expecting a dictionary mapping language codes to values + tag = XmpTag('Xmp.dc.description') + self.failUnlessRaises(TypeError, tag._set_value, None) + self.failUnlessRaises(TypeError, tag._set_value, 'bleh') + class TestXmpNamespaces(unittest.TestCase): -- cgit From 7457fbcbd52fdb8f0be56b80e4dc889d46faad59 Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Wed, 17 Aug 2011 19:03:45 +0200 Subject: Add some sanity checks. --- test/xmp.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/xmp.py b/test/xmp.py index c0ea11f..294cdc2 100644 --- a/test/xmp.py +++ b/test/xmp.py @@ -367,10 +367,12 @@ class TestXmpTag(unittest.TestCase): def test_set_value_incorrect_type(self): # Expecting a list of values tag = XmpTag('Xmp.dc.publisher') + self.failUnlessEqual(tag.type, 'bag ProperName') self.failUnlessRaises(TypeError, tag._set_value, None) self.failUnlessRaises(TypeError, tag._set_value, 'bleh') # Expecting a dictionary mapping language codes to values tag = XmpTag('Xmp.dc.description') + self.failUnlessEqual(tag.type, 'Lang Alt') self.failUnlessRaises(TypeError, tag._set_value, None) self.failUnlessRaises(TypeError, tag._set_value, 'bleh') -- cgit From 235aec27487a8a247269a444be0198f6b47731cb Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Wed, 17 Aug 2011 19:09:53 +0200 Subject: Be flexible and allow setting the value of a LangAlt tag to a string, in which case it is automatically converted to {'x-default': value}. --- src/pyexiv2/xmp.py | 2 ++ test/xmp.py | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/pyexiv2/xmp.py b/src/pyexiv2/xmp.py index 2b3149e..76e0df2 100644 --- a/src/pyexiv2/xmp.py +++ b/src/pyexiv2/xmp.py @@ -225,6 +225,8 @@ class XmpTag(object): stype = stype[17:] self.raw_value = map(lambda x: self._convert_to_string(x, stype), value) elif type == 'LangAlt': + if isinstance(value, basestring): + value = {'x-default': value} if not isinstance(value, dict): raise TypeError('Expecting a dictionary mapping language codes to values') raw_value = {} diff --git a/test/xmp.py b/test/xmp.py index 294cdc2..6183277 100644 --- a/test/xmp.py +++ b/test/xmp.py @@ -374,7 +374,13 @@ class TestXmpTag(unittest.TestCase): tag = XmpTag('Xmp.dc.description') self.failUnlessEqual(tag.type, 'Lang Alt') self.failUnlessRaises(TypeError, tag._set_value, None) - self.failUnlessRaises(TypeError, tag._set_value, 'bleh') + self.failUnlessRaises(TypeError, tag._set_value, ['bleh']) + + def test_set_value_basestring_for_langalt(self): + tag = XmpTag('Xmp.dc.description') + self.failUnlessEqual(tag.type, 'Lang Alt') + tag.value = 'bleh' + self.failUnlessEqual(tag.value, {'x-default': 'bleh'}) class TestXmpNamespaces(unittest.TestCase): -- cgit