← Back to team overview

pyexiv2-developers team mailing list archive

Re: Empty XmpTag.type and Value not set error at write() with empty XmpBag

 

On 2012-01-12, Benjamin Henne <henne@xxxxxxxxxxxxxxxxxxxxx> wrote:
> Hi,
> 
> I maybe have found some pyexiv2 issues now.

Hey Benjamin,

Thanks for your thorough investigation. I answered in the thread on
exiv2's forums. I'm re-posting the answers here, but I suggest that from
now on we keep the conversation in one place only, this will be easier
to follow (let's use the forums, as this keeps Andreas and team in the
loop).
I'm subscribed to the thread on the forum so I won't miss your future
updates.

> 1) XmpTag.type returns '' in a case it should return
>    some other value, namely 'Region' or 'RegionStruct'.
>    Detailed information can be found in
>    * http://dev.exiv2.org/boards/3/topics/1039#message-1065

It appears that Exiv2::XmpProperties::propertyInfo(key) for key =
'Xmp.MP.RegionInfo/MPRI:Regions' returns a null pointer, which is why
the type in pyexiv2 is an empty string.

Could it be that some static information regarding this tag is missing
in libexiv2? Or that the implementation of
XmpProperties::propertyInfo(...) doesn't play well with subkeys?

> 2) If I try to set the value of a XmpBag to [''] for an empty
>    bag containing nothing but structs, I get an "ValueError:
>    Value not set" at write(). I was able to track this to
>    exiv2wrapper.cpp:XmpTag::setArrayValue
> 
>    A (quick) fix (for me) was:
> 
>         // Reset the value
>    --   _datum->setValue(0);
>    ++   _datum->setValue(std::string(""));
>    ++   //  setValue(0) leads to "ValueError: Value not set"
>    ++   //   if array=['']

I reviewed the change you suggest in pyexiv2 and it may fix the issue
for this use case but it won't work in the general case.

The role of `_datum->setValue(0)` in XmpTag::setArrayValue(...) is to
reset the value of the datum, i.e. to empty it if it previously
contained values. Then all values in the list are appended by iterating
over the list and calling _datum->setValue(...) for each value.
Replacing this line of code by `_datum->setValue(std::string(""))` would
lead to appending an empty string (this is a no-op as the string is
checked for emptiness) instead of actually clearing the potentially
existing values.

I've discovered that the issue can be worked around by assigning [' ']
(one whitespace) to md['Xmp.MP.RegionInfo/MPRI:Regions'] instead of
[''], which doesn't work because XmpArrayValue::read(...) checks for the
emptiness of the string before appending the value.
I wonder how this is implemented in exiv2 CLI. I would have thought that
it roughly went through the same code path, but it seems it somehow
works around it to allow appending a truly empty value to the datum.


References