aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Tilloy <olivier@tilloy.net>2011-08-18 08:51:18 +0200
committerOlivier Tilloy <olivier@tilloy.net>2011-08-18 08:51:18 +0200
commit846611ba355fa09e66cee3e0253d7b364c6e7910 (patch)
tree14dfbf0ec7bb8341e8e7efe7b130ec0a1525964e
parent8db919cfb2e31409116026d76a72e82f4f0824c1 (diff)
parent235aec27487a8a247269a444be0198f6b47731cb (diff)
downloadpyexiv2-846611ba355fa09e66cee3e0253d7b364c6e7910.tar.gz
Check the type before setting an XMP tag’s value and raise a TypeError if it doesn’t match.
Allow setting the value of a LangAlt tag to a single string, in which case it is automatically converted to {'x-default': value}.
-rw-r--r--src/pyexiv2/metadata.py14
-rw-r--r--src/pyexiv2/xmp.py6
-rw-r--r--test/metadata.py9
-rw-r--r--test/xmp.py20
4 files changed, 40 insertions, 9 deletions
diff --git a/src/pyexiv2/metadata.py b/src/pyexiv2/metadata.py
index 57c0263..e758bfa 100644
--- a/src/pyexiv2/metadata.py
+++ b/src/pyexiv2/metadata.py
@@ -2,7 +2,7 @@
# ******************************************************************************
#
-# Copyright (C) 2006-2010 Olivier Tilloy <olivier@tilloy.net>
+# Copyright (C) 2006-2011 Olivier Tilloy <olivier@tilloy.net>
#
# This file is part of the pyexiv2 distribution.
#
@@ -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):
diff --git a/src/pyexiv2/xmp.py b/src/pyexiv2/xmp.py
index bed1b66..76e0df2 100644
--- a/src/pyexiv2/xmp.py
+++ b/src/pyexiv2/xmp.py
@@ -218,11 +218,17 @@ 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 isinstance(value, basestring):
+ value = {'x-default': value}
+ 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/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 <olivier@tilloy.net>
+# Copyright (C) 2009-2011 Olivier Tilloy <olivier@tilloy.net>
#
# 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 #
##########################
diff --git a/test/xmp.py b/test/xmp.py
index 7e7522e..6183277 100644
--- a/test/xmp.py
+++ b/test/xmp.py
@@ -2,7 +2,7 @@
# ******************************************************************************
#
-# Copyright (C) 2009-2010 Olivier Tilloy <olivier@tilloy.net>
+# Copyright (C) 2009-2011 Olivier Tilloy <olivier@tilloy.net>
#
# This file is part of the pyexiv2 distribution.
#
@@ -364,6 +364,24 @@ 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.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'])
+
+ 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):