Show More
@@ -17,7 +17,7 b' from nose import SkipTest' | |||
|
17 | 17 | |
|
18 | 18 | from IPython.utils.traitlets import ( |
|
19 | 19 | HasTraits, MetaHasTraits, TraitType, Any, Bool, CBytes, Dict, |
|
20 | Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError, | |
|
20 | Int, Long, Integer, Float, Complex, Bytes, Unicode, Color, TraitError, | |
|
21 | 21 | Union, Undefined, Type, This, Instance, TCPAddress, List, Tuple, |
|
22 | 22 | ObjectName, DottedObjectName, CRegExp, link, directional_link, |
|
23 | 23 | EventfulList, EventfulDict, ForwardDeclaredType, ForwardDeclaredInstance, |
@@ -940,6 +940,16 b' class TestDottedObjectName(TraitTestBase):' | |||
|
940 | 940 | _good_values.append(u"t.ΓΎ") |
|
941 | 941 | |
|
942 | 942 | |
|
943 | class ColorTrait(HasTraits): | |
|
944 | value = Color("black") | |
|
945 | ||
|
946 | class TestColor(TraitTestBase): | |
|
947 | obj = ColorTrait() | |
|
948 | ||
|
949 | _good_values = ["blue", "#AA0", "#FFFFFF"] | |
|
950 | _bad_values = ["vanilla", "blues"] | |
|
951 | ||
|
952 | ||
|
943 | 953 | class TCPAddressTrait(HasTraits): |
|
944 | 954 | |
|
945 | 955 | value = TCPAddress() |
@@ -1277,19 +1277,14 b' class CUnicode(Unicode):' | |||
|
1277 | 1277 | self.error(obj, value) |
|
1278 | 1278 | |
|
1279 | 1279 | |
|
1280 |
class |
|
|
1281 | """A string holding a valid object name in this version of Python. | |
|
1282 | ||
|
1283 | This does not check that the name exists in any scope.""" | |
|
1284 | info_text = "a valid object identifier in Python" | |
|
1280 | class _CoercedString(TraitType): | |
|
1285 | 1281 | |
|
1286 | 1282 | if py3compat.PY3: |
|
1287 | 1283 | # Python 3: |
|
1288 | coerce_str = staticmethod(lambda _,s: s) | |
|
1289 | ||
|
1284 | _coerce_str = staticmethod(lambda _,s: s) | |
|
1290 | 1285 | else: |
|
1291 | 1286 | # Python 2: |
|
1292 | def coerce_str(self, obj, value): | |
|
1287 | def _coerce_str(self, obj, value): | |
|
1293 | 1288 | "In Python 2, coerce ascii-only unicode to str" |
|
1294 | 1289 | if isinstance(value, unicode): |
|
1295 | 1290 | try: |
@@ -1298,23 +1293,49 b' class ObjectName(TraitType):' | |||
|
1298 | 1293 | self.error(obj, value) |
|
1299 | 1294 | return value |
|
1300 | 1295 | |
|
1296 | ||
|
1297 | class ObjectName(_CoercedString): | |
|
1298 | """A string holding a valid object name in this version of Python. | |
|
1299 | ||
|
1300 | This does not check that the name exists in any scope.""" | |
|
1301 | ||
|
1302 | info_text = "a valid object identifier in Python" | |
|
1303 | ||
|
1301 | 1304 | def validate(self, obj, value): |
|
1302 | value = self.coerce_str(obj, value) | |
|
1305 | value = self._coerce_str(obj, value) | |
|
1303 | 1306 | |
|
1304 | 1307 | if isinstance(value, string_types) and py3compat.isidentifier(value): |
|
1305 | 1308 | return value |
|
1306 | 1309 | self.error(obj, value) |
|
1307 | 1310 | |
|
1311 | ||
|
1308 | 1312 | class DottedObjectName(ObjectName): |
|
1309 | 1313 | """A string holding a valid dotted object name in Python, such as A.b3._c""" |
|
1314 | ||
|
1310 | 1315 | def validate(self, obj, value): |
|
1311 | value = self.coerce_str(obj, value) | |
|
1316 | value = self._coerce_str(obj, value) | |
|
1312 | 1317 | |
|
1313 | 1318 | if isinstance(value, string_types) and py3compat.isidentifier(value, dotted=True): |
|
1314 | 1319 | return value |
|
1315 | 1320 | self.error(obj, value) |
|
1316 | 1321 | |
|
1317 | 1322 | |
|
1323 | _color_names = ['aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'honeydew', 'hotpink', 'indianred ', 'indigo ', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'rebeccapurple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen'] | |
|
1324 | _color_re = re.compile(r'#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$') | |
|
1325 | ||
|
1326 | ||
|
1327 | class Color(_CoercedString): | |
|
1328 | """A string holding a valid HTML color such as 'blue', '#060482', '#A80'""" | |
|
1329 | ||
|
1330 | info_text = 'a valid HTML color' | |
|
1331 | ||
|
1332 | def validate(self, obj, value): | |
|
1333 | value = self._coerce_str(obj, value) | |
|
1334 | if value.lower() in _color_names or _color_re.match(value): | |
|
1335 | return value | |
|
1336 | self.error(obj, value) | |
|
1337 | ||
|
1338 | ||
|
1318 | 1339 | class Bool(TraitType): |
|
1319 | 1340 | """A boolean (True, False) trait.""" |
|
1320 | 1341 |
General Comments 0
You need to be logged in to leave comments.
Login now