##// END OF EJS Templates
Merge pull request #5353 from Zaharid/nonetraits...
Thomas Kluyver -
r16701:6f9046f4 merge
parent child Browse files
Show More
@@ -673,6 +673,23 b' class TraitTestBase(TestCase):'
673 673 if hasattr(self, '_default_value'):
674 674 self.assertEqual(self._default_value, self.obj.value)
675 675
676 def test_allow_none(self):
677 if (hasattr(self, '_bad_values') and hasattr(self, '_good_values') and
678 None in self._bad_values):
679 trait=self.obj.traits()['value']
680 try:
681 trait.allow_none = True
682 self._bad_values.remove(None)
683 #skip coerce. Allow None casts None to None.
684 self.assign(None)
685 self.assertEqual(self.obj.value,None)
686 self.test_good_values()
687 self.test_bad_values()
688 finally:
689 #tear down
690 trait.allow_none = False
691 self._bad_values.append(None)
692
676 693 def tearDown(self):
677 694 # restore default value after tests, if set
678 695 if hasattr(self, '_default_value'):
@@ -830,7 +847,7 b' class TestObjectName(TraitTestBase):'
830 847 _default_value = "abc"
831 848 _good_values = ["a", "gh", "g9", "g_", "_G", u"a345_"]
832 849 _bad_values = [1, "", u"€", "9g", "!", "#abc", "aj@", "a.b", "a()", "a[0]",
833 object(), object]
850 None, object(), object]
834 851 if sys.version_info[0] < 3:
835 852 _bad_values.append(u"ΓΎ")
836 853 else:
@@ -845,7 +862,7 b' class TestDottedObjectName(TraitTestBase):'
845 862
846 863 _default_value = "a.b"
847 864 _good_values = ["A", "y.t", "y765.__repr__", "os.path.join", u"os.path.join"]
848 _bad_values = [1, u"abc.€", "_.@", ".", ".abc", "abc.", ".abc."]
865 _bad_values = [1, u"abc.€", "_.@", ".", ".abc", "abc.", ".abc.", None]
849 866 if sys.version_info[0] < 3:
850 867 _bad_values.append(u"t.ΓΎ")
851 868 else:
@@ -862,7 +879,7 b' class TestTCPAddress(TraitTestBase):'
862 879
863 880 _default_value = ('127.0.0.1',0)
864 881 _good_values = [('localhost',0),('192.168.0.1',1000),('www.google.com',80)]
865 _bad_values = [(0,0),('localhost',10.0),('localhost',-1)]
882 _bad_values = [(0,0),('localhost',10.0),('localhost',-1), None]
866 883
867 884 class ListTrait(HasTraits):
868 885
@@ -919,14 +936,14 b' class TestLenList(TraitTestBase):'
919 936
920 937 class TupleTrait(HasTraits):
921 938
922 value = Tuple(Int)
939 value = Tuple(Int(allow_none=True))
923 940
924 941 class TestTupleTrait(TraitTestBase):
925 942
926 943 obj = TupleTrait()
927 944
928 945 _default_value = None
929 _good_values = [(1,), None, (0,), [1]]
946 _good_values = [(1,), None, (0,), [1], (None,)]
930 947 _bad_values = [10, (1,2), ('a'), ()]
931 948
932 949 def coerce(self, value):
@@ -252,13 +252,16 b' class TraitType(object):'
252 252
253 253 metadata = {}
254 254 default_value = Undefined
255 allow_none = False
255 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 259 """Create a TraitType.
259 260 """
260 261 if default_value is not NoDefaultSpecified:
261 262 self.default_value = default_value
263 if allow_none is not None:
264 self.allow_none = allow_none
262 265
263 266 if len(metadata) > 0:
264 267 if len(self.metadata) > 0:
@@ -371,6 +374,8 b' class TraitType(object):'
371 374 obj._notify_trait(self.name, old_value, new_value)
372 375
373 376 def _validate(self, obj, value):
377 if value is None and self.allow_none:
378 return value
374 379 if hasattr(self, 'validate'):
375 380 return self.validate(obj, value)
376 381 elif hasattr(self, 'is_valid_for'):
@@ -745,9 +750,8 b' class Type(ClassBasedTraitType):'
745 750 raise TraitError("A Type trait must specify a class.")
746 751
747 752 self.klass = klass
748 self._allow_none = allow_none
749 753
750 super(Type, self).__init__(default_value, **metadata)
754 super(Type, self).__init__(default_value, allow_none=allow_none, **metadata)
751 755
752 756 def validate(self, obj, value):
753 757 """Validates that the value is a valid object instance."""
@@ -755,8 +759,7 b' class Type(ClassBasedTraitType):'
755 759 if issubclass(value, self.klass):
756 760 return value
757 761 except:
758 if (value is None) and (self._allow_none):
759 return value
762 pass
760 763
761 764 self.error(obj, value)
762 765
@@ -767,7 +770,7 b' class Type(ClassBasedTraitType):'
767 770 else:
768 771 klass = self.klass.__name__
769 772 result = 'a subclass of ' + klass
770 if self._allow_none:
773 if self.allow_none:
771 774 return result + ' or None'
772 775 return result
773 776
@@ -831,8 +834,6 b' class Instance(ClassBasedTraitType):'
831 834 not (but not both), None is replace by ``()`` or ``{}``.
832 835 """
833 836
834 self._allow_none = allow_none
835
836 837 if (klass is None) or (not (inspect.isclass(klass) or isinstance(klass, py3compat.string_types))):
837 838 raise TraitError('The klass argument must be a class'
838 839 ' you gave: %r' % klass)
@@ -856,14 +857,9 b' class Instance(ClassBasedTraitType):'
856 857
857 858 default_value = DefaultValueGenerator(*args, **kw)
858 859
859 super(Instance, self).__init__(default_value, **metadata)
860 super(Instance, self).__init__(default_value, allow_none=allow_none, **metadata)
860 861
861 862 def validate(self, obj, value):
862 if value is None:
863 if self._allow_none:
864 return value
865 self.error(obj, value)
866
867 863 if isinstance(value, self.klass):
868 864 return value
869 865 else:
@@ -875,7 +871,7 b' class Instance(ClassBasedTraitType):'
875 871 else:
876 872 klass = self.klass.__name__
877 873 result = class_of(klass)
878 if self._allow_none:
874 if self.allow_none:
879 875 return result + ' or None'
880 876
881 877 return result
@@ -1169,14 +1165,9 b' class Enum(TraitType):'
1169 1165
1170 1166 def __init__(self, values, default_value=None, allow_none=True, **metadata):
1171 1167 self.values = values
1172 self._allow_none = allow_none
1173 super(Enum, self).__init__(default_value, **metadata)
1168 super(Enum, self).__init__(default_value, allow_none=allow_none, **metadata)
1174 1169
1175 1170 def validate(self, obj, value):
1176 if value is None:
1177 if self._allow_none:
1178 return value
1179
1180 1171 if value in self.values:
1181 1172 return value
1182 1173 self.error(obj, value)
@@ -1184,7 +1175,7 b' class Enum(TraitType):'
1184 1175 def info(self):
1185 1176 """ Returns a description of the trait."""
1186 1177 result = 'any of ' + repr(self.values)
1187 if self._allow_none:
1178 if self.allow_none:
1188 1179 return result + ' or None'
1189 1180 return result
1190 1181
@@ -1192,10 +1183,6 b' class CaselessStrEnum(Enum):'
1192 1183 """An enum of strings that are caseless in validate."""
1193 1184
1194 1185 def validate(self, obj, value):
1195 if value is None:
1196 if self._allow_none:
1197 return value
1198
1199 1186 if not isinstance(value, py3compat.string_types):
1200 1187 self.error(obj, value)
1201 1188
@@ -1290,7 +1277,7 b' class Container(Instance):'
1290 1277 return value
1291 1278 for v in value:
1292 1279 try:
1293 v = self._trait.validate(obj, v)
1280 v = self._trait._validate(obj, v)
1294 1281 except TraitError:
1295 1282 self.element_error(obj, v, self._trait)
1296 1283 else:
@@ -1366,8 +1353,6 b' class List(Container):'
1366 1353
1367 1354 def validate(self, obj, value):
1368 1355 value = super(List, self).validate(obj, value)
1369 if value is None:
1370 return value
1371 1356
1372 1357 value = self.validate_elements(obj, value)
1373 1358
@@ -1463,7 +1448,7 b' class Tuple(Container):'
1463 1448 validated = []
1464 1449 for t,v in zip(self._traits, value):
1465 1450 try:
1466 v = t.validate(obj, v)
1451 v = t._validate(obj, v)
1467 1452 except TraitError:
1468 1453 self.element_error(obj, v, t)
1469 1454 else:
General Comments 0
You need to be logged in to leave comments. Login now