##// END OF EJS Templates
Merge pull request #7726 from SylvainCorlay/trait_dict_validation...
Min RK -
r20769:3263e908 merge
parent child Browse files
Show More
@@ -1079,6 +1079,19 b' def test_dict_assignment():'
1079 nt.assert_equal(d, c.value)
1079 nt.assert_equal(d, c.value)
1080 nt.assert_true(c.value is d)
1080 nt.assert_true(c.value is d)
1081
1081
1082 class ValidatedDictTrait(HasTraits):
1083
1084 value = Dict(Unicode())
1085
1086 class TestInstanceDict(TraitTestBase):
1087
1088 obj = ValidatedDictTrait()
1089
1090 _default_value = {}
1091 _good_values = [{'0': 'foo'}, {'1': 'bar'}]
1092 _bad_values = [{'0': 0}, {'1': 1}]
1093
1094
1082 def test_dict_default_value():
1095 def test_dict_default_value():
1083 """Check that the `{}` default value of the Dict traitlet constructor is
1096 """Check that the `{}` default value of the Dict traitlet constructor is
1084 actually copied."""
1097 actually copied."""
@@ -1645,13 +1645,33 b' class Tuple(Container):'
1645
1645
1646 class Dict(Instance):
1646 class Dict(Instance):
1647 """An instance of a Python dict."""
1647 """An instance of a Python dict."""
1648 _trait = None
1648
1649
1649 def __init__(self, default_value={}, allow_none=False, **metadata):
1650 def __init__(self, trait=None, default_value=NoDefaultSpecified, allow_none=False, **metadata):
1650 """Create a dict trait type from a dict.
1651 """Create a dict trait type from a dict.
1651
1652
1652 The default value is created by doing ``dict(default_value)``,
1653 The default value is created by doing ``dict(default_value)``,
1653 which creates a copy of the ``default_value``.
1654 which creates a copy of the ``default_value``.
1655
1656 trait : TraitType [ optional ]
1657 the type for restricting the contents of the Container. If unspecified,
1658 types are not checked.
1659
1660 default_value : SequenceType [ optional ]
1661 The default value for the Dict. Must be dict, tuple, or None, and
1662 will be cast to a dict if not None. If `trait` is specified, the
1663 `default_value` must conform to the constraints it specifies.
1664
1665 allow_none : bool [ default False ]
1666 Whether to allow the value to be None
1667
1654 """
1668 """
1669 if default_value is NoDefaultSpecified and trait is not None:
1670 if not is_trait(trait):
1671 default_value = trait
1672 trait = None
1673 if default_value is NoDefaultSpecified:
1674 default_value = {}
1655 if default_value is None:
1675 if default_value is None:
1656 args = None
1676 args = None
1657 elif isinstance(default_value, dict):
1677 elif isinstance(default_value, dict):
@@ -1661,9 +1681,48 b' class Dict(Instance):'
1661 else:
1681 else:
1662 raise TypeError('default value of Dict was %s' % default_value)
1682 raise TypeError('default value of Dict was %s' % default_value)
1663
1683
1684 if is_trait(trait):
1685 self._trait = trait() if isinstance(trait, type) else trait
1686 self._trait.name = 'element'
1687 elif trait is not None:
1688 raise TypeError("`trait` must be a Trait or None, got %s"%repr_type(trait))
1689
1664 super(Dict,self).__init__(klass=dict, args=args,
1690 super(Dict,self).__init__(klass=dict, args=args,
1665 allow_none=allow_none, **metadata)
1691 allow_none=allow_none, **metadata)
1666
1692
1693 def element_error(self, obj, element, validator):
1694 e = "Element of the '%s' trait of %s instance must be %s, but a value of %s was specified." \
1695 % (self.name, class_of(obj), validator.info(), repr_type(element))
1696 raise TraitError(e)
1697
1698 def validate(self, obj, value):
1699 value = super(Dict, self).validate(obj, value)
1700 if value is None:
1701 return value
1702 value = self.validate_elements(obj, value)
1703 return value
1704
1705 def validate_elements(self, obj, value):
1706 if self._trait is None or isinstance(self._trait, Any):
1707 return value
1708 validated = {}
1709 for key in value:
1710 v = value[key]
1711 try:
1712 v = self._trait._validate(obj, v)
1713 except TraitError:
1714 self.element_error(obj, v, self._trait)
1715 else:
1716 validated[key] = v
1717 return self.klass(validated)
1718
1719 def instance_init(self, obj):
1720 if isinstance(self._trait, TraitType):
1721 self._trait.this_class = self.this_class
1722 if hasattr(self._trait, '_resolve_classes'):
1723 self._trait._resolve_classes(obj)
1724 super(Dict, self).instance_init(obj)
1725
1667
1726
1668 class EventfulDict(Instance):
1727 class EventfulDict(Instance):
1669 """An instance of an EventfulDict."""
1728 """An instance of an EventfulDict."""
General Comments 0
You need to be logged in to leave comments. Login now