@@ -720,6 +720,105 @@ def __eq__(self, other):
720720 and self .value == other .value )
721721
722722
723+ class BooleanAndTwoCharactersField (SingleLineField ):
724+ """
725+ Field with either a boolean value or character(s) value (at most 2
726+ characters). Validated value is False, True, None or character value.
727+ """
728+
729+ def default_value (self ):
730+ return None
731+
732+ true_flags = ('yes' , 'y' , 'true' , 'x' )
733+ false_flags = ('no' , 'n' , 'false' )
734+ flag_values = true_flags + false_flags
735+
736+ def _validate (self , * args , ** kwargs ):
737+ """
738+ Check that flag are valid with either boolean value or character value.
739+ Default flag to False. Return a list of errors.
740+ """
741+ errors = super (BooleanAndTwoCharactersField ,
742+ self )._validate (* args , ** kwargs )
743+ self .about_file_path = kwargs .get ('about_file_path' )
744+ flag = self .get_value (self .original_value )
745+ if flag is False :
746+ name = self .name
747+ val = self .original_value
748+ about_file_path = self .about_file_path
749+ flag_values = self .flag_values
750+ msg = (u'Path: %(about_file_path)s - Field %(name)s: Invalid value: %(val)r is not '
751+ u'one of: %(flag_values)s and it is not a 1 or 2 character value.' % locals ())
752+ errors .append (Error (ERROR , msg ))
753+ self .value = None
754+ elif flag is None :
755+ name = self .name
756+ msg = (u'Field %(name)s: field is present but empty. ' % locals ())
757+ errors .append (Error (INFO , msg ))
758+ self .value = None
759+ else :
760+ if flag == u'yes' or flag is True :
761+ self .value = True
762+ elif flag == u'no' :
763+ self .value = False
764+ else :
765+ self .value = flag
766+ return errors
767+
768+ def get_value (self , value ):
769+ """
770+ Return a normalized existing value if found in the list of
771+ possible values or None if empty or False if not found or original value
772+ if it is not a boolean value
773+ """
774+ if value is None or value == '' :
775+ return None
776+
777+ if isinstance (value , bool ):
778+ return value
779+ else :
780+ if isinstance (value , str ):
781+ value = value .strip ()
782+ if not value :
783+ return None
784+
785+ value = value .lower ()
786+ if value in self .flag_values or len (value ) <= 2 :
787+ if value in self .true_flags :
788+ return u'yes'
789+ elif value in self .false_flags :
790+ return u'no'
791+ else :
792+ return value
793+ else :
794+ return False
795+ else :
796+ return False
797+
798+ @property
799+ def has_content (self ):
800+ """
801+ Return true if it has content regardless of what value, False otherwise
802+ """
803+ if self .original_value :
804+ return True
805+ return False
806+
807+ def _serialized_value (self ):
808+ # default normalized values for serialization
809+ if self .value :
810+ if isinstance (self .value , bool ):
811+ return u'yes'
812+ else :
813+ return self .value
814+ elif self .value is False :
815+ return u'no'
816+ else :
817+ # self.value is None
818+ # TODO: should we serialize to No for None???
819+ return u''
820+
821+
723822def validate_fields (fields , about_file_path , running_inventory , base_dir ,
724823 reference_dir = None ):
725824 """
@@ -810,7 +909,7 @@ def set_standard_fields(self):
810909 ('notice_url' , UrlField ()),
811910
812911 ('redistribute' , BooleanField ()),
813- ('attribute' , BooleanField ()),
912+ ('attribute' , BooleanAndTwoCharactersField ()),
814913 ('track_changes' , BooleanField ()),
815914 ('modified' , BooleanField ()),
816915 ('internal_use_only' , BooleanField ()),
0 commit comments