Show More
@@ -16,7 +16,7 b' import nose.tools as nt' | |||||
16 | from nose import SkipTest |
|
16 | from nose import SkipTest | |
17 |
|
17 | |||
18 | from IPython.utils.traitlets import ( |
|
18 | from IPython.utils.traitlets import ( | |
19 |
HasTraits, MetaHasTraits, TraitType, |
|
19 | HasTraits, MetaHasTraits, TraitType, Any, CBytes, Dict, | |
20 | Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError, |
|
20 | Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError, | |
21 | Undefined, Type, This, Instance, TCPAddress, List, Tuple, |
|
21 | Undefined, Type, This, Instance, TCPAddress, List, Tuple, | |
22 | ObjectName, DottedObjectName, CRegExp, link |
|
22 | ObjectName, DottedObjectName, CRegExp, link | |
@@ -73,7 +73,7 b' class TestTraitType(TestCase):' | |||||
73 | self.assertEqual(a.tt, -1) |
|
73 | self.assertEqual(a.tt, -1) | |
74 |
|
74 | |||
75 | def test_default_validate(self): |
|
75 | def test_default_validate(self): | |
76 |
class MyIntTT( |
|
76 | class MyIntTT(TraitType): | |
77 | def validate(self, obj, value): |
|
77 | def validate(self, obj, value): | |
78 | if isinstance(value, int): |
|
78 | if isinstance(value, int): | |
79 | return value |
|
79 | return value | |
@@ -354,29 +354,29 b' class TestHasTraitsNotify(TestCase):' | |||||
354 |
|
354 | |||
355 | class A(HasTraits): |
|
355 | class A(HasTraits): | |
356 | listen_to = ['a'] |
|
356 | listen_to = ['a'] | |
357 |
|
357 | |||
358 | a = Int(0) |
|
358 | a = Int(0) | |
359 | b = 0 |
|
359 | b = 0 | |
360 |
|
360 | |||
361 | def __init__(self, **kwargs): |
|
361 | def __init__(self, **kwargs): | |
362 | super(A, self).__init__(**kwargs) |
|
362 | super(A, self).__init__(**kwargs) | |
363 | self.on_trait_change(self.listener1, ['a']) |
|
363 | self.on_trait_change(self.listener1, ['a']) | |
364 |
|
364 | |||
365 | def listener1(self, name, old, new): |
|
365 | def listener1(self, name, old, new): | |
366 | self.b += 1 |
|
366 | self.b += 1 | |
367 |
|
367 | |||
368 | class B(A): |
|
368 | class B(A): | |
369 |
|
369 | |||
370 | c = 0 |
|
370 | c = 0 | |
371 | d = 0 |
|
371 | d = 0 | |
372 |
|
372 | |||
373 | def __init__(self, **kwargs): |
|
373 | def __init__(self, **kwargs): | |
374 | super(B, self).__init__(**kwargs) |
|
374 | super(B, self).__init__(**kwargs) | |
375 | self.on_trait_change(self.listener2) |
|
375 | self.on_trait_change(self.listener2) | |
376 |
|
376 | |||
377 | def listener2(self, name, old, new): |
|
377 | def listener2(self, name, old, new): | |
378 | self.c += 1 |
|
378 | self.c += 1 | |
379 |
|
379 | |||
380 | def _a_changed(self, name, old, new): |
|
380 | def _a_changed(self, name, old, new): | |
381 | self.d += 1 |
|
381 | self.d += 1 | |
382 |
|
382 | |||
@@ -442,7 +442,7 b' class TestHasTraits(TestCase):' | |||||
442 | def __init__(self, i): |
|
442 | def __init__(self, i): | |
443 | super(A, self).__init__() |
|
443 | super(A, self).__init__() | |
444 | self.i = i |
|
444 | self.i = i | |
445 |
|
445 | |||
446 | a = A(5) |
|
446 | a = A(5) | |
447 | self.assertEqual(a.i, 5) |
|
447 | self.assertEqual(a.i, 5) | |
448 | # should raise TypeError if no positional arg given |
|
448 | # should raise TypeError if no positional arg given | |
@@ -677,19 +677,19 b' class TraitTestBase(TestCase):' | |||||
677 | if (hasattr(self, '_bad_values') and hasattr(self, '_good_values') and |
|
677 | if (hasattr(self, '_bad_values') and hasattr(self, '_good_values') and | |
678 | None in self._bad_values): |
|
678 | None in self._bad_values): | |
679 | trait=self.obj.traits()['value'] |
|
679 | trait=self.obj.traits()['value'] | |
680 | if isinstance(trait, AllowNone) and not trait._allow_none: |
|
680 | try: | |
681 |
tr |
|
681 | trait.allow_none = True | |
682 | trait._allow_none = True |
|
682 | self._bad_values.remove(None) | |
683 | self._bad_values.remove(None) |
|
683 | #skip coerce. Allow None casts None to None. | |
684 | #skip coerce. Allow None casts None to None. |
|
684 | self.assign(None) | |
685 |
|
|
685 | self.assertEqual(self.obj.value,None) | |
686 |
|
|
686 | self.test_good_values() | |
687 |
|
|
687 | self.test_bad_values() | |
688 | self.test_bad_values() |
|
688 | finally: | |
689 |
|
|
689 | #tear down | |
690 |
|
|
690 | trait.allow_none = False | |
691 | trait._allow_none = False |
|
691 | self._bad_values.append(None) | |
692 | self._bad_values.append(None) |
|
692 | print "bad values %s" % self | |
693 |
|
693 | |||
694 |
|
694 | |||
695 | def tearDown(self): |
|
695 | def tearDown(self): | |
@@ -894,7 +894,7 b' class TestList(TraitTestBase):' | |||||
894 | _default_value = [] |
|
894 | _default_value = [] | |
895 | _good_values = [[], [1], list(range(10)), (1,2)] |
|
895 | _good_values = [[], [1], list(range(10)), (1,2)] | |
896 | _bad_values = [10, [1,'a'], 'a'] |
|
896 | _bad_values = [10, [1,'a'], 'a'] | |
897 |
|
897 | |||
898 | def coerce(self, value): |
|
898 | def coerce(self, value): | |
899 | if value is not None: |
|
899 | if value is not None: | |
900 | value = list(value) |
|
900 | value = list(value) | |
@@ -1073,7 +1073,7 b' class TestLink(TestCase):' | |||||
1073 | count = Int() |
|
1073 | count = Int() | |
1074 | a = A(value=9) |
|
1074 | a = A(value=9) | |
1075 | b = B(count=8) |
|
1075 | b = B(count=8) | |
1076 |
|
1076 | |||
1077 | # Register callbacks that count. |
|
1077 | # Register callbacks that count. | |
1078 | callback_count = [] |
|
1078 | callback_count = [] | |
1079 | def a_callback(name, old, new): |
|
1079 | def a_callback(name, old, new): | |
@@ -1124,4 +1124,4 b' def test_pickle_hastraits():' | |||||
1124 | c2 = pickle.loads(p) |
|
1124 | c2 = pickle.loads(p) | |
1125 | nt.assert_equal(c2.i, c.i) |
|
1125 | nt.assert_equal(c2.i, c.i) | |
1126 | nt.assert_equal(c2.j, c.j) |
|
1126 | nt.assert_equal(c2.j, c.j) | |
1127 |
|
|
1127 | No newline at end of file |
@@ -220,7 +220,7 b' class link(object):' | |||||
220 | for obj,attr in self.objects.keys(): |
|
220 | for obj,attr in self.objects.keys(): | |
221 | if obj is not sending_obj or attr != sending_attr: |
|
221 | if obj is not sending_obj or attr != sending_attr: | |
222 | setattr(obj, attr, new) |
|
222 | setattr(obj, attr, new) | |
223 |
|
223 | |||
224 | def unlink(self): |
|
224 | def unlink(self): | |
225 | for key, callback in self.objects.items(): |
|
225 | for key, callback in self.objects.items(): | |
226 | (obj,attr) = key |
|
226 | (obj,attr) = key | |
@@ -252,13 +252,16 b' class TraitType(object):' | |||||
252 |
|
252 | |||
253 | metadata = {} |
|
253 | metadata = {} | |
254 | default_value = Undefined |
|
254 | default_value = Undefined | |
|
255 | allow_none = False | |||
255 | info_text = 'any value' |
|
256 | info_text = 'any value' | |
256 |
|
257 | |||
257 | def __init__(self, default_value=NoDefaultSpecified, **metadata): |
|
258 | def __init__(self, default_value=NoDefaultSpecified, allow_none=None, **metadata): | |
258 | """Create a TraitType. |
|
259 | """Create a TraitType. | |
259 | """ |
|
260 | """ | |
260 | if default_value is not NoDefaultSpecified: |
|
261 | if default_value is not NoDefaultSpecified: | |
261 | self.default_value = default_value |
|
262 | self.default_value = default_value | |
|
263 | if allow_none is not None: | |||
|
264 | self.allow_none = allow_none | |||
262 |
|
265 | |||
263 | if len(metadata) > 0: |
|
266 | if len(metadata) > 0: | |
264 | if len(self.metadata) > 0: |
|
267 | if len(self.metadata) > 0: | |
@@ -371,6 +374,8 b' class TraitType(object):' | |||||
371 | obj._notify_trait(self.name, old_value, new_value) |
|
374 | obj._notify_trait(self.name, old_value, new_value) | |
372 |
|
375 | |||
373 | def _validate(self, obj, value): |
|
376 | def _validate(self, obj, value): | |
|
377 | if value is None and self.allow_none: | |||
|
378 | return value | |||
374 | if hasattr(self, 'validate'): |
|
379 | if hasattr(self, 'validate'): | |
375 | return self.validate(obj, value) |
|
380 | return self.validate(obj, value) | |
376 | elif hasattr(self, 'is_valid_for'): |
|
381 | elif hasattr(self, 'is_valid_for'): | |
@@ -677,29 +682,16 b' class HasTraits(py3compat.with_metaclass(MetaHasTraits, object)):' | |||||
677 | else: |
|
682 | else: | |
678 | return trait.get_metadata(key) |
|
683 | return trait.get_metadata(key) | |
679 |
|
684 | |||
680 | class AllowNone(TraitType): |
|
|||
681 | """A trait that can be set to allow None values. It does not provide |
|
|||
682 | validation.""" |
|
|||
683 | def __init__(self, default_value=NoDefaultSpecified, allow_none = False, **metadata): |
|
|||
684 | self._allow_none = allow_none |
|
|||
685 | super(AllowNone, self).__init__(default_value, **metadata) |
|
|||
686 |
|
||||
687 | def _none_ok(self, value): |
|
|||
688 | """The validate method can return the None value.""" |
|
|||
689 | return value is None and self._allow_none |
|
|||
690 |
|
||||
691 |
|
||||
692 | #----------------------------------------------------------------------------- |
|
685 | #----------------------------------------------------------------------------- | |
693 | # Actual TraitTypes implementations/subclasses |
|
686 | # Actual TraitTypes implementations/subclasses | |
694 | #----------------------------------------------------------------------------- |
|
687 | #----------------------------------------------------------------------------- | |
695 |
|
688 | |||
696 |
|
||||
697 | #----------------------------------------------------------------------------- |
|
689 | #----------------------------------------------------------------------------- | |
698 | # TraitTypes subclasses for handling classes and instances of classes |
|
690 | # TraitTypes subclasses for handling classes and instances of classes | |
699 | #----------------------------------------------------------------------------- |
|
691 | #----------------------------------------------------------------------------- | |
700 |
|
692 | |||
701 |
|
693 | |||
702 |
class ClassBasedTraitType( |
|
694 | class ClassBasedTraitType(TraitType): | |
703 | """A trait with error reporting for Type, Instance and This.""" |
|
695 | """A trait with error reporting for Type, Instance and This.""" | |
704 |
|
696 | |||
705 | def error(self, obj, value): |
|
697 | def error(self, obj, value): | |
@@ -767,8 +759,7 b' class Type(ClassBasedTraitType):' | |||||
767 | if issubclass(value, self.klass): |
|
759 | if issubclass(value, self.klass): | |
768 | return value |
|
760 | return value | |
769 | except: |
|
761 | except: | |
770 | if self._none_ok(value): |
|
762 | pass | |
771 | return value |
|
|||
772 |
|
763 | |||
773 | self.error(obj, value) |
|
764 | self.error(obj, value) | |
774 |
|
765 | |||
@@ -779,7 +770,7 b' class Type(ClassBasedTraitType):' | |||||
779 | else: |
|
770 | else: | |
780 | klass = self.klass.__name__ |
|
771 | klass = self.klass.__name__ | |
781 | result = 'a subclass of ' + klass |
|
772 | result = 'a subclass of ' + klass | |
782 |
if self. |
|
773 | if self.allow_none: | |
783 | return result + ' or None' |
|
774 | return result + ' or None' | |
784 | return result |
|
775 | return result | |
785 |
|
776 | |||
@@ -869,11 +860,6 b' class Instance(ClassBasedTraitType):' | |||||
869 | super(Instance, self).__init__(default_value, allow_none, **metadata) |
|
860 | super(Instance, self).__init__(default_value, allow_none, **metadata) | |
870 |
|
861 | |||
871 | def validate(self, obj, value): |
|
862 | def validate(self, obj, value): | |
872 | if value is None: |
|
|||
873 | if self._allow_none: |
|
|||
874 | return value |
|
|||
875 | self.error(obj, value) |
|
|||
876 |
|
||||
877 | if isinstance(value, self.klass): |
|
863 | if isinstance(value, self.klass): | |
878 | return value |
|
864 | return value | |
879 | else: |
|
865 | else: | |
@@ -885,7 +871,7 b' class Instance(ClassBasedTraitType):' | |||||
885 | else: |
|
871 | else: | |
886 | klass = self.klass.__name__ |
|
872 | klass = self.klass.__name__ | |
887 | result = class_of(klass) |
|
873 | result = class_of(klass) | |
888 |
if self. |
|
874 | if self.allow_none: | |
889 | return result + ' or None' |
|
875 | return result + ' or None' | |
890 |
|
876 | |||
891 | return result |
|
877 | return result | |
@@ -945,14 +931,14 b' class Any(TraitType):' | |||||
945 | info_text = 'any value' |
|
931 | info_text = 'any value' | |
946 |
|
932 | |||
947 |
|
933 | |||
948 |
class Int( |
|
934 | class Int(TraitType): | |
949 | """An int trait.""" |
|
935 | """An int trait.""" | |
950 |
|
936 | |||
951 | default_value = 0 |
|
937 | default_value = 0 | |
952 | info_text = 'an int' |
|
938 | info_text = 'an int' | |
953 |
|
939 | |||
954 | def validate(self, obj, value): |
|
940 | def validate(self, obj, value): | |
955 |
if isinstance(value, int) |
|
941 | if isinstance(value, int): | |
956 | return value |
|
942 | return value | |
957 | self.error(obj, value) |
|
943 | self.error(obj, value) | |
958 |
|
944 | |||
@@ -963,22 +949,20 b' class CInt(Int):' | |||||
963 | try: |
|
949 | try: | |
964 | return int(value) |
|
950 | return int(value) | |
965 | except: |
|
951 | except: | |
966 | if self._none_ok(value): |
|
|||
967 | return value |
|
|||
968 | self.error(obj, value) |
|
952 | self.error(obj, value) | |
969 |
|
953 | |||
970 | if py3compat.PY3: |
|
954 | if py3compat.PY3: | |
971 | Long, CLong = Int, CInt |
|
955 | Long, CLong = Int, CInt | |
972 | Integer = Int |
|
956 | Integer = Int | |
973 | else: |
|
957 | else: | |
974 |
class Long( |
|
958 | class Long(TraitType): | |
975 | """A long integer trait.""" |
|
959 | """A long integer trait.""" | |
976 |
|
960 | |||
977 | default_value = 0 |
|
961 | default_value = 0 | |
978 | info_text = 'a long' |
|
962 | info_text = 'a long' | |
979 |
|
963 | |||
980 | def validate(self, obj, value): |
|
964 | def validate(self, obj, value): | |
981 |
if isinstance(value, long) |
|
965 | if isinstance(value, long): | |
982 | return value |
|
966 | return value | |
983 | if isinstance(value, int): |
|
967 | if isinstance(value, int): | |
984 | return long(value) |
|
968 | return long(value) | |
@@ -992,11 +976,9 b' else:' | |||||
992 | try: |
|
976 | try: | |
993 | return long(value) |
|
977 | return long(value) | |
994 | except: |
|
978 | except: | |
995 | if self._none_ok(value): |
|
|||
996 | return value |
|
|||
997 | self.error(obj, value) |
|
979 | self.error(obj, value) | |
998 |
|
980 | |||
999 |
class Integer( |
|
981 | class Integer(TraitType): | |
1000 | """An integer trait. |
|
982 | """An integer trait. | |
1001 |
|
983 | |||
1002 | Longs that are unnecessary (<= sys.maxint) are cast to ints.""" |
|
984 | Longs that are unnecessary (<= sys.maxint) are cast to ints.""" | |
@@ -1005,7 +987,7 b' else:' | |||||
1005 | info_text = 'an integer' |
|
987 | info_text = 'an integer' | |
1006 |
|
988 | |||
1007 | def validate(self, obj, value): |
|
989 | def validate(self, obj, value): | |
1008 |
if isinstance(value, int) |
|
990 | if isinstance(value, int): | |
1009 | return value |
|
991 | return value | |
1010 | if isinstance(value, long): |
|
992 | if isinstance(value, long): | |
1011 | # downcast longs that fit in int: |
|
993 | # downcast longs that fit in int: | |
@@ -1019,14 +1001,14 b' else:' | |||||
1019 | self.error(obj, value) |
|
1001 | self.error(obj, value) | |
1020 |
|
1002 | |||
1021 |
|
1003 | |||
1022 |
class Float( |
|
1004 | class Float(TraitType): | |
1023 | """A float trait.""" |
|
1005 | """A float trait.""" | |
1024 |
|
1006 | |||
1025 | default_value = 0.0 |
|
1007 | default_value = 0.0 | |
1026 | info_text = 'a float' |
|
1008 | info_text = 'a float' | |
1027 |
|
1009 | |||
1028 | def validate(self, obj, value): |
|
1010 | def validate(self, obj, value): | |
1029 |
if isinstance(value, float |
|
1011 | if isinstance(value, float): | |
1030 | return value |
|
1012 | return value | |
1031 | if isinstance(value, int): |
|
1013 | if isinstance(value, int): | |
1032 | return float(value) |
|
1014 | return float(value) | |
@@ -1040,18 +1022,16 b' class CFloat(Float):' | |||||
1040 | try: |
|
1022 | try: | |
1041 | return float(value) |
|
1023 | return float(value) | |
1042 | except: |
|
1024 | except: | |
1043 | if self._none_ok(value): |
|
|||
1044 | return value |
|
|||
1045 | self.error(obj, value) |
|
1025 | self.error(obj, value) | |
1046 |
|
1026 | |||
1047 |
class Complex( |
|
1027 | class Complex(TraitType): | |
1048 | """A trait for complex numbers.""" |
|
1028 | """A trait for complex numbers.""" | |
1049 |
|
1029 | |||
1050 | default_value = 0.0 + 0.0j |
|
1030 | default_value = 0.0 + 0.0j | |
1051 | info_text = 'a complex number' |
|
1031 | info_text = 'a complex number' | |
1052 |
|
1032 | |||
1053 | def validate(self, obj, value): |
|
1033 | def validate(self, obj, value): | |
1054 |
if isinstance(value, complex) |
|
1034 | if isinstance(value, complex): | |
1055 | return value |
|
1035 | return value | |
1056 | if isinstance(value, (float, int)): |
|
1036 | if isinstance(value, (float, int)): | |
1057 | return complex(value) |
|
1037 | return complex(value) | |
@@ -1065,21 +1045,19 b' class CComplex(Complex):' | |||||
1065 | try: |
|
1045 | try: | |
1066 | return complex(value) |
|
1046 | return complex(value) | |
1067 | except: |
|
1047 | except: | |
1068 | if self._noe_ok(value): |
|
|||
1069 | return value |
|
|||
1070 | self.error(obj, value) |
|
1048 | self.error(obj, value) | |
1071 |
|
1049 | |||
1072 | # We should always be explicit about whether we're using bytes or unicode, both |
|
1050 | # We should always be explicit about whether we're using bytes or unicode, both | |
1073 | # for Python 3 conversion and for reliable unicode behaviour on Python 2. So |
|
1051 | # for Python 3 conversion and for reliable unicode behaviour on Python 2. So | |
1074 | # we don't have a Str type. |
|
1052 | # we don't have a Str type. | |
1075 |
class Bytes( |
|
1053 | class Bytes(TraitType): | |
1076 | """A trait for byte strings.""" |
|
1054 | """A trait for byte strings.""" | |
1077 |
|
1055 | |||
1078 | default_value = b'' |
|
1056 | default_value = b'' | |
1079 | info_text = 'a bytes object' |
|
1057 | info_text = 'a bytes object' | |
1080 |
|
1058 | |||
1081 | def validate(self, obj, value): |
|
1059 | def validate(self, obj, value): | |
1082 |
if isinstance(value, bytes) |
|
1060 | if isinstance(value, bytes): | |
1083 | return value |
|
1061 | return value | |
1084 | self.error(obj, value) |
|
1062 | self.error(obj, value) | |
1085 |
|
1063 | |||
@@ -1091,19 +1069,17 b' class CBytes(Bytes):' | |||||
1091 | try: |
|
1069 | try: | |
1092 | return bytes(value) |
|
1070 | return bytes(value) | |
1093 | except: |
|
1071 | except: | |
1094 | if self._none_ok(value): |
|
|||
1095 | return value |
|
|||
1096 | self.error(obj, value) |
|
1072 | self.error(obj, value) | |
1097 |
|
1073 | |||
1098 |
|
1074 | |||
1099 |
class Unicode( |
|
1075 | class Unicode(TraitType): | |
1100 | """A trait for unicode strings.""" |
|
1076 | """A trait for unicode strings.""" | |
1101 |
|
1077 | |||
1102 | default_value = u'' |
|
1078 | default_value = u'' | |
1103 | info_text = 'a unicode string' |
|
1079 | info_text = 'a unicode string' | |
1104 |
|
1080 | |||
1105 | def validate(self, obj, value): |
|
1081 | def validate(self, obj, value): | |
1106 |
if isinstance(value, py3compat.unicode_type) |
|
1082 | if isinstance(value, py3compat.unicode_type): | |
1107 | return value |
|
1083 | return value | |
1108 | if isinstance(value, bytes): |
|
1084 | if isinstance(value, bytes): | |
1109 | try: |
|
1085 | try: | |
@@ -1121,12 +1097,10 b' class CUnicode(Unicode):' | |||||
1121 | try: |
|
1097 | try: | |
1122 | return py3compat.unicode_type(value) |
|
1098 | return py3compat.unicode_type(value) | |
1123 | except: |
|
1099 | except: | |
1124 | if self._allow_none(value): |
|
|||
1125 | return value |
|
|||
1126 | self.error(obj, value) |
|
1100 | self.error(obj, value) | |
1127 |
|
1101 | |||
1128 |
|
1102 | |||
1129 |
class ObjectName( |
|
1103 | class ObjectName(TraitType): | |
1130 | """A string holding a valid object name in this version of Python. |
|
1104 | """A string holding a valid object name in this version of Python. | |
1131 |
|
1105 | |||
1132 | This does not check that the name exists in any scope.""" |
|
1106 | This does not check that the name exists in any scope.""" | |
@@ -1148,8 +1122,6 b' class ObjectName(AllowNone):' | |||||
1148 | return value |
|
1122 | return value | |
1149 |
|
1123 | |||
1150 | def validate(self, obj, value): |
|
1124 | def validate(self, obj, value): | |
1151 | if self._none_ok(value): |
|
|||
1152 | return value |
|
|||
1153 | value = self.coerce_str(obj, value) |
|
1125 | value = self.coerce_str(obj, value) | |
1154 |
|
1126 | |||
1155 | if isinstance(value, str) and py3compat.isidentifier(value): |
|
1127 | if isinstance(value, str) and py3compat.isidentifier(value): | |
@@ -1159,8 +1131,6 b' class ObjectName(AllowNone):' | |||||
1159 | class DottedObjectName(ObjectName): |
|
1131 | class DottedObjectName(ObjectName): | |
1160 | """A string holding a valid dotted object name in Python, such as A.b3._c""" |
|
1132 | """A string holding a valid dotted object name in Python, such as A.b3._c""" | |
1161 | def validate(self, obj, value): |
|
1133 | def validate(self, obj, value): | |
1162 | if self._none_ok(value): |
|
|||
1163 | return value |
|
|||
1164 | value = self.coerce_str(obj, value) |
|
1134 | value = self.coerce_str(obj, value) | |
1165 |
|
1135 | |||
1166 | if isinstance(value, str) and py3compat.isidentifier(value, dotted=True): |
|
1136 | if isinstance(value, str) and py3compat.isidentifier(value, dotted=True): | |
@@ -1168,14 +1138,14 b' class DottedObjectName(ObjectName):' | |||||
1168 | self.error(obj, value) |
|
1138 | self.error(obj, value) | |
1169 |
|
1139 | |||
1170 |
|
1140 | |||
1171 |
class Bool( |
|
1141 | class Bool(TraitType): | |
1172 | """A boolean (True, False) trait.""" |
|
1142 | """A boolean (True, False) trait.""" | |
1173 |
|
1143 | |||
1174 | default_value = False |
|
1144 | default_value = False | |
1175 | info_text = 'a boolean' |
|
1145 | info_text = 'a boolean' | |
1176 |
|
1146 | |||
1177 | def validate(self, obj, value): |
|
1147 | def validate(self, obj, value): | |
1178 |
if isinstance(value, bool) |
|
1148 | if isinstance(value, bool): | |
1179 | return value |
|
1149 | return value | |
1180 | self.error(obj, value) |
|
1150 | self.error(obj, value) | |
1181 |
|
1151 | |||
@@ -1195,14 +1165,9 b' class Enum(TraitType):' | |||||
1195 |
|
1165 | |||
1196 | def __init__(self, values, default_value=None, allow_none=True, **metadata): |
|
1166 | def __init__(self, values, default_value=None, allow_none=True, **metadata): | |
1197 | self.values = values |
|
1167 | self.values = values | |
1198 | self._allow_none = allow_none |
|
1168 | super(Enum, self).__init__(default_value, allow_none, **metadata) | |
1199 | super(Enum, self).__init__(default_value, **metadata) |
|
|||
1200 |
|
1169 | |||
1201 | def validate(self, obj, value): |
|
1170 | def validate(self, obj, value): | |
1202 | if value is None: |
|
|||
1203 | if self._allow_none: |
|
|||
1204 | return value |
|
|||
1205 |
|
||||
1206 | if value in self.values: |
|
1171 | if value in self.values: | |
1207 | return value |
|
1172 | return value | |
1208 | self.error(obj, value) |
|
1173 | self.error(obj, value) | |
@@ -1210,7 +1175,7 b' class Enum(TraitType):' | |||||
1210 | def info(self): |
|
1175 | def info(self): | |
1211 | """ Returns a description of the trait.""" |
|
1176 | """ Returns a description of the trait.""" | |
1212 | result = 'any of ' + repr(self.values) |
|
1177 | result = 'any of ' + repr(self.values) | |
1213 |
if self. |
|
1178 | if self.allow_none: | |
1214 | return result + ' or None' |
|
1179 | return result + ' or None' | |
1215 | return result |
|
1180 | return result | |
1216 |
|
1181 | |||
@@ -1218,10 +1183,6 b' class CaselessStrEnum(Enum):' | |||||
1218 | """An enum of strings that are caseless in validate.""" |
|
1183 | """An enum of strings that are caseless in validate.""" | |
1219 |
|
1184 | |||
1220 | def validate(self, obj, value): |
|
1185 | def validate(self, obj, value): | |
1221 | if value is None: |
|
|||
1222 | if self._allow_none: |
|
|||
1223 | return value |
|
|||
1224 |
|
||||
1225 | if not isinstance(value, py3compat.string_types): |
|
1186 | if not isinstance(value, py3compat.string_types): | |
1226 | self.error(obj, value) |
|
1187 | self.error(obj, value) | |
1227 |
|
1188 | |||
@@ -1384,7 +1345,7 b' class List(Container):' | |||||
1384 | self.length_error(obj, value) |
|
1345 | self.length_error(obj, value) | |
1385 |
|
1346 | |||
1386 | return super(List, self).validate_elements(obj, value) |
|
1347 | return super(List, self).validate_elements(obj, value) | |
1387 |
|
1348 | |||
1388 | def validate(self, obj, value): |
|
1349 | def validate(self, obj, value): | |
1389 | value = super(List, self).validate(obj, value) |
|
1350 | value = super(List, self).validate(obj, value) | |
1390 | if value is None: |
|
1351 | if value is None: | |
@@ -1393,7 +1354,7 b' class List(Container):' | |||||
1393 | value = self.validate_elements(obj, value) |
|
1354 | value = self.validate_elements(obj, value) | |
1394 |
|
1355 | |||
1395 | return value |
|
1356 | return value | |
1396 |
|
1357 | |||
1397 |
|
1358 | |||
1398 |
|
1359 | |||
1399 | class Set(List): |
|
1360 | class Set(List): | |
@@ -1513,7 +1474,7 b' class Dict(Instance):' | |||||
1513 | super(Dict,self).__init__(klass=dict, args=args, |
|
1474 | super(Dict,self).__init__(klass=dict, args=args, | |
1514 | allow_none=allow_none, **metadata) |
|
1475 | allow_none=allow_none, **metadata) | |
1515 |
|
1476 | |||
1516 |
class TCPAddress( |
|
1477 | class TCPAddress(TraitType): | |
1517 | """A trait for an (ip, port) tuple. |
|
1478 | """A trait for an (ip, port) tuple. | |
1518 |
|
1479 | |||
1519 | This allows for both IPv4 IP addresses as well as hostnames. |
|
1480 | This allows for both IPv4 IP addresses as well as hostnames. | |
@@ -1529,11 +1490,9 b' class TCPAddress(AllowNone):' | |||||
1529 | port = value[1] |
|
1490 | port = value[1] | |
1530 | if port >= 0 and port <= 65535: |
|
1491 | if port >= 0 and port <= 65535: | |
1531 | return value |
|
1492 | return value | |
1532 | if self._none_ok(value): |
|
|||
1533 | return value |
|
|||
1534 | self.error(obj, value) |
|
1493 | self.error(obj, value) | |
1535 |
|
1494 | |||
1536 |
class CRegExp( |
|
1495 | class CRegExp(TraitType): | |
1537 | """A casting compiled regular expression trait. |
|
1496 | """A casting compiled regular expression trait. | |
1538 |
|
1497 | |||
1539 | Accepts both strings and compiled regular expressions. The resulting |
|
1498 | Accepts both strings and compiled regular expressions. The resulting | |
@@ -1545,6 +1504,4 b' class CRegExp(AllowNone):' | |||||
1545 | try: |
|
1504 | try: | |
1546 | return re.compile(value) |
|
1505 | return re.compile(value) | |
1547 | except: |
|
1506 | except: | |
1548 | if self._none_ok(value): |
|
|||
1549 | return value |
|
|||
1550 | self.error(obj, value) |
|
1507 | self.error(obj, value) |
General Comments 0
You need to be logged in to leave comments.
Login now