@@ -373,45 +373,83 @@ def clone(self):
373373
374374 return obj
375375
376- def merge (self , other , strict = True ):
376+ def merge_check (self , source , strict = True ):
377377 """
378- Merges the property 'other' into self, if possible. Information
379- will be synchronized. Method will raise a ValueError when the
380- information in this property and the passed property are in
381- conflict.
378+ Checks whether a source Property can be merged with self as destination and
379+ raises a ValueError if the values of source and destination are not compatible.
380+ With parameter *strict=True* a ValueError is also raised, if any of the
381+ attributes unit, definition, uncertainty, reference or value_origin and dtype
382+ differ in source and destination.
382383
383- :param other : an odML Property.
384- :param strict: Bool value to indicate whether types should be implicitly converted
385- even when information may be lost. Default is True, i.e. no conversion,
386- and a ValueError will be raised if types do not match .
384+ :param source : an odML Property.
385+ :param strict: If True, the attributes dtype, unit, uncertainty, definition,
386+ reference and value_origin of source and destination
387+ must be identical .
387388 """
388- assert (isinstance (other , BaseProperty ))
389- if strict and self .dtype != other .dtype :
389+ if not isinstance (source , BaseProperty ):
390+ raise ValueError ("odml.Property.merge: odML Property required." )
391+
392+ # Catch unmerge-able values at this point to avoid
393+ # failing Section tree merges which cannot easily be rolled back.
394+ new_value = self ._convert_value_input (source .value )
395+ if not self ._validate_values (new_value ):
396+ raise ValueError ("odml.Property.merge: passed value(s) cannot "
397+ "be converted to data type '%s'!" % self ._dtype )
398+ if not strict :
399+ return
400+
401+ if (self .dtype is not None and source .dtype is not None and
402+ self .dtype != source .dtype ):
390403 raise ValueError ("odml.Property.merge: src and dest dtypes do not match!" )
391404
392- if self .unit is not None and other .unit is not None and self .unit != other .unit :
393- raise ValueError ("odml.Property.merge: src and dest units (%s, %s) do not match!" % (other .unit , self .unit ))
405+ if self .unit is not None and source .unit is not None and self .unit != source .unit :
406+ raise ValueError ("odml.Property.merge: "
407+ "src and dest units (%s, %s) do not match!" %
408+ (source .unit , self .unit ))
394409
395- if self .definition is not None and other .definition is not None :
410+ if (self .uncertainty is not None and source .uncertainty is not None and
411+ self .uncertainty != source .uncertainty ):
412+ raise ValueError ("odml.Property.merge: "
413+ "src and dest uncertainty both set and do not match!" )
414+
415+ if self .definition is not None and source .definition is not None :
396416 self_def = '' .join (map (str .strip , self .definition .split ())).lower ()
397- other_def = '' .join (map (str .strip , other .definition .split ())).lower ()
417+ other_def = '' .join (map (str .strip , source .definition .split ())).lower ()
398418 if self_def != other_def :
399- raise ValueError ("odml.Property.merge: src and dest definitions do not match!" )
400-
401- if self .uncertainty is not None and other .uncertainty is not None :
402- raise ValueError ("odml.Property.merge: src and dest uncertainty both set and do not match!" )
419+ raise ValueError ("odml.Property.merge: "
420+ "src and dest definitions do not match!" )
403421
404- if self .reference is not None and other .reference is not None :
422+ if self .reference is not None and source .reference is not None :
405423 self_ref = '' .join (map (str .strip , self .reference .lower ().split ()))
406- other_ref = '' .join (map (str .strip , other .reference .lower ().split ()))
424+ other_ref = '' .join (map (str .strip , source .reference .lower ().split ()))
407425 if self_ref != other_ref :
408- raise ValueError ("odml.Property.merge: src and dest references are in conflict!" )
426+ raise ValueError ("odml.Property.merge: "
427+ "src and dest references are in conflict!" )
409428
410- if self .value_origin is not None and other .value_origin is not None :
429+ if self .value_origin is not None and source .value_origin is not None :
411430 self_ori = '' .join (map (str .strip , self .value_origin .lower ().split ()))
412- other_ori = '' .join (map (str .strip , other .value_origin .lower ().split ()))
431+ other_ori = '' .join (map (str .strip , source .value_origin .lower ().split ()))
413432 if self_ori != other_ori :
414- raise ValueError ("odml.Property.merge: src and dest value_origin are in conflict!" )
433+ raise ValueError ("odml.Property.merge: "
434+ "src and dest value_origin are in conflict!" )
435+
436+ def merge (self , other , strict = True ):
437+ """
438+ Merges the Property 'other' into self, if possible. Information
439+ will be synchronized. By default the method will raise a ValueError when the
440+ information in this property and the passed property are in conflict.
441+
442+ :param other: an odML Property.
443+ :param strict: Bool value to indicate whether types should be implicitly converted
444+ even when information may be lost. Default is True, i.e. no conversion,
445+ and a ValueError will be raised if types or other attributes do not match.
446+ If a conflict arises with strict=False, the attribute value of self will
447+ be kept, while the attribute value of other will be lost.
448+ """
449+ if not isinstance (other , BaseProperty ):
450+ raise TypeError ("odml.Property.merge: odml Property required." )
451+
452+ self .merge_check (other , strict )
415453
416454 if self .value_origin is None and other .value_origin is not None :
417455 self .value_origin = other .value_origin
0 commit comments