##// END OF EJS Templates
move sentinel out of IPython.utils.signature...
Min RK -
Show More
@@ -0,0 +1,17 b''
1 """Sentinel class for constants with useful reprs"""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 class Sentinel(object):
7
8 def __init__(self, name, module, docstring=None):
9 self.name = name
10 self.module = module
11 if docstring:
12 self.__doc__ = docstring
13
14
15 def __repr__(self):
16 return str(self.module)+'.'+self.name
17
@@ -0,0 +1,17 b''
1 """Sentinel class for constants with useful reprs"""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 class Sentinel(object):
7
8 def __init__(self, name, module, docstring=None):
9 self.name = name
10 self.module = module
11 if docstring:
12 self.__doc__ = docstring
13
14
15 def __repr__(self):
16 return str(self.module)+'.'+self.name
17
@@ -0,0 +1,17 b''
1 """Sentinel class for constants with useful reprs"""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 class Sentinel(object):
7
8 def __init__(self, name, module, docstring=None):
9 self.name = name
10 self.module = module
11 if docstring:
12 self.__doc__ = docstring
13
14
15 def __repr__(self):
16 return str(self.module)+'.'+self.name
17
@@ -1,972 +1,972 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Display formatters.
3 3
4 4 Inheritance diagram:
5 5
6 6 .. inheritance-diagram:: IPython.core.formatters
7 7 :parts: 3
8 8 """
9 9
10 10 # Copyright (c) IPython Development Team.
11 11 # Distributed under the terms of the Modified BSD License.
12 12
13 13 import abc
14 14 import inspect
15 15 import json
16 16 import sys
17 17 import traceback
18 18 import warnings
19 19
20 20 from decorator import decorator
21 21
22 22 from IPython.config.configurable import Configurable
23 23 from IPython.core.getipython import get_ipython
24 from IPython.utils.signatures import Sentinel
24 from IPython.utils.sentinel import Sentinel
25 25 from IPython.lib import pretty
26 26 from IPython.utils.traitlets import (
27 27 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
28 28 ForwardDeclaredInstance,
29 29 )
30 30 from IPython.utils.py3compat import (
31 31 with_metaclass, string_types, unicode_type,
32 32 )
33 33
34 34
35 35 #-----------------------------------------------------------------------------
36 36 # The main DisplayFormatter class
37 37 #-----------------------------------------------------------------------------
38 38
39 39
40 40 def _safe_get_formatter_method(obj, name):
41 41 """Safely get a formatter method
42 42
43 43 - Classes cannot have formatter methods, only instance
44 44 - protect against proxy objects that claim to have everything
45 45 """
46 46 if inspect.isclass(obj):
47 47 # repr methods only make sense on instances, not classes
48 48 return None
49 49 method = pretty._safe_getattr(obj, name, None)
50 50 if callable(method):
51 51 # obj claims to have repr method...
52 52 if callable(pretty._safe_getattr(obj, '_ipython_canary_method_should_not_exist_', None)):
53 53 # ...but don't trust proxy objects that claim to have everything
54 54 return None
55 55 return method
56 56
57 57
58 58 class DisplayFormatter(Configurable):
59 59
60 60 # When set to true only the default plain text formatter will be used.
61 61 plain_text_only = Bool(False, config=True)
62 62 def _plain_text_only_changed(self, name, old, new):
63 63 warnings.warn("""DisplayFormatter.plain_text_only is deprecated.
64 64
65 65 Use DisplayFormatter.active_types = ['text/plain']
66 66 for the same effect.
67 67 """, DeprecationWarning)
68 68 if new:
69 69 self.active_types = ['text/plain']
70 70 else:
71 71 self.active_types = self.format_types
72 72
73 73 active_types = List(Unicode, config=True,
74 74 help="""List of currently active mime-types to display.
75 75 You can use this to set a white-list for formats to display.
76 76
77 77 Most users will not need to change this value.
78 78 """)
79 79 def _active_types_default(self):
80 80 return self.format_types
81 81
82 82 def _active_types_changed(self, name, old, new):
83 83 for key, formatter in self.formatters.items():
84 84 if key in new:
85 85 formatter.enabled = True
86 86 else:
87 87 formatter.enabled = False
88 88
89 89 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
90 90 def _ipython_display_formatter_default(self):
91 91 return IPythonDisplayFormatter(parent=self)
92 92
93 93 # A dict of formatter whose keys are format types (MIME types) and whose
94 94 # values are subclasses of BaseFormatter.
95 95 formatters = Dict()
96 96 def _formatters_default(self):
97 97 """Activate the default formatters."""
98 98 formatter_classes = [
99 99 PlainTextFormatter,
100 100 HTMLFormatter,
101 101 MarkdownFormatter,
102 102 SVGFormatter,
103 103 PNGFormatter,
104 104 PDFFormatter,
105 105 JPEGFormatter,
106 106 LatexFormatter,
107 107 JSONFormatter,
108 108 JavascriptFormatter
109 109 ]
110 110 d = {}
111 111 for cls in formatter_classes:
112 112 f = cls(parent=self)
113 113 d[f.format_type] = f
114 114 return d
115 115
116 116 def format(self, obj, include=None, exclude=None):
117 117 """Return a format data dict for an object.
118 118
119 119 By default all format types will be computed.
120 120
121 121 The following MIME types are currently implemented:
122 122
123 123 * text/plain
124 124 * text/html
125 125 * text/markdown
126 126 * text/latex
127 127 * application/json
128 128 * application/javascript
129 129 * application/pdf
130 130 * image/png
131 131 * image/jpeg
132 132 * image/svg+xml
133 133
134 134 Parameters
135 135 ----------
136 136 obj : object
137 137 The Python object whose format data will be computed.
138 138 include : list or tuple, optional
139 139 A list of format type strings (MIME types) to include in the
140 140 format data dict. If this is set *only* the format types included
141 141 in this list will be computed.
142 142 exclude : list or tuple, optional
143 143 A list of format type string (MIME types) to exclude in the format
144 144 data dict. If this is set all format types will be computed,
145 145 except for those included in this argument.
146 146
147 147 Returns
148 148 -------
149 149 (format_dict, metadata_dict) : tuple of two dicts
150 150
151 151 format_dict is a dictionary of key/value pairs, one of each format that was
152 152 generated for the object. The keys are the format types, which
153 153 will usually be MIME type strings and the values and JSON'able
154 154 data structure containing the raw data for the representation in
155 155 that format.
156 156
157 157 metadata_dict is a dictionary of metadata about each mime-type output.
158 158 Its keys will be a strict subset of the keys in format_dict.
159 159 """
160 160 format_dict = {}
161 161 md_dict = {}
162 162
163 163 if self.ipython_display_formatter(obj):
164 164 # object handled itself, don't proceed
165 165 return {}, {}
166 166
167 167 for format_type, formatter in self.formatters.items():
168 168 if include and format_type not in include:
169 169 continue
170 170 if exclude and format_type in exclude:
171 171 continue
172 172
173 173 md = None
174 174 try:
175 175 data = formatter(obj)
176 176 except:
177 177 # FIXME: log the exception
178 178 raise
179 179
180 180 # formatters can return raw data or (data, metadata)
181 181 if isinstance(data, tuple) and len(data) == 2:
182 182 data, md = data
183 183
184 184 if data is not None:
185 185 format_dict[format_type] = data
186 186 if md is not None:
187 187 md_dict[format_type] = md
188 188
189 189 return format_dict, md_dict
190 190
191 191 @property
192 192 def format_types(self):
193 193 """Return the format types (MIME types) of the active formatters."""
194 194 return list(self.formatters.keys())
195 195
196 196
197 197 #-----------------------------------------------------------------------------
198 198 # Formatters for specific format types (text, html, svg, etc.)
199 199 #-----------------------------------------------------------------------------
200 200
201 201
202 202 def _safe_repr(obj):
203 203 """Try to return a repr of an object
204 204
205 205 always returns a string, at least.
206 206 """
207 207 try:
208 208 return repr(obj)
209 209 except Exception as e:
210 210 return "un-repr-able object (%r)" % e
211 211
212 212
213 213 class FormatterWarning(UserWarning):
214 214 """Warning class for errors in formatters"""
215 215
216 216 @decorator
217 217 def catch_format_error(method, self, *args, **kwargs):
218 218 """show traceback on failed format call"""
219 219 try:
220 220 r = method(self, *args, **kwargs)
221 221 except NotImplementedError:
222 222 # don't warn on NotImplementedErrors
223 223 return None
224 224 except Exception:
225 225 exc_info = sys.exc_info()
226 226 ip = get_ipython()
227 227 if ip is not None:
228 228 ip.showtraceback(exc_info)
229 229 else:
230 230 traceback.print_exception(*exc_info)
231 231 return None
232 232 return self._check_return(r, args[0])
233 233
234 234
235 235 class FormatterABC(with_metaclass(abc.ABCMeta, object)):
236 236 """ Abstract base class for Formatters.
237 237
238 238 A formatter is a callable class that is responsible for computing the
239 239 raw format data for a particular format type (MIME type). For example,
240 240 an HTML formatter would have a format type of `text/html` and would return
241 241 the HTML representation of the object when called.
242 242 """
243 243
244 244 # The format type of the data returned, usually a MIME type.
245 245 format_type = 'text/plain'
246 246
247 247 # Is the formatter enabled...
248 248 enabled = True
249 249
250 250 @abc.abstractmethod
251 251 def __call__(self, obj):
252 252 """Return a JSON'able representation of the object.
253 253
254 254 If the object cannot be formatted by this formatter,
255 255 warn and return None.
256 256 """
257 257 return repr(obj)
258 258
259 259
260 260 def _mod_name_key(typ):
261 261 """Return a (__module__, __name__) tuple for a type.
262 262
263 263 Used as key in Formatter.deferred_printers.
264 264 """
265 265 module = getattr(typ, '__module__', None)
266 266 name = getattr(typ, '__name__', None)
267 267 return (module, name)
268 268
269 269
270 270 def _get_type(obj):
271 271 """Return the type of an instance (old and new-style)"""
272 272 return getattr(obj, '__class__', None) or type(obj)
273 273
274 274
275 275 _raise_key_error = Sentinel('_raise_key_error', __name__,
276 276 """
277 277 Special value to raise a KeyError
278 278
279 279 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
280 280 """)
281 281
282 282
283 283 class BaseFormatter(Configurable):
284 284 """A base formatter class that is configurable.
285 285
286 286 This formatter should usually be used as the base class of all formatters.
287 287 It is a traited :class:`Configurable` class and includes an extensible
288 288 API for users to determine how their objects are formatted. The following
289 289 logic is used to find a function to format an given object.
290 290
291 291 1. The object is introspected to see if it has a method with the name
292 292 :attr:`print_method`. If is does, that object is passed to that method
293 293 for formatting.
294 294 2. If no print method is found, three internal dictionaries are consulted
295 295 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
296 296 and :attr:`deferred_printers`.
297 297
298 298 Users should use these dictionaries to register functions that will be
299 299 used to compute the format data for their objects (if those objects don't
300 300 have the special print methods). The easiest way of using these
301 301 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
302 302 methods.
303 303
304 304 If no function/callable is found to compute the format data, ``None`` is
305 305 returned and this format type is not used.
306 306 """
307 307
308 308 format_type = Unicode('text/plain')
309 309 _return_type = string_types
310 310
311 311 enabled = Bool(True, config=True)
312 312
313 313 print_method = ObjectName('__repr__')
314 314
315 315 # The singleton printers.
316 316 # Maps the IDs of the builtin singleton objects to the format functions.
317 317 singleton_printers = Dict(config=True)
318 318
319 319 # The type-specific printers.
320 320 # Map type objects to the format functions.
321 321 type_printers = Dict(config=True)
322 322
323 323 # The deferred-import type-specific printers.
324 324 # Map (modulename, classname) pairs to the format functions.
325 325 deferred_printers = Dict(config=True)
326 326
327 327 @catch_format_error
328 328 def __call__(self, obj):
329 329 """Compute the format for an object."""
330 330 if self.enabled:
331 331 # lookup registered printer
332 332 try:
333 333 printer = self.lookup(obj)
334 334 except KeyError:
335 335 pass
336 336 else:
337 337 return printer(obj)
338 338 # Finally look for special method names
339 339 method = _safe_get_formatter_method(obj, self.print_method)
340 340 if method is not None:
341 341 return method()
342 342 return None
343 343 else:
344 344 return None
345 345
346 346 def __contains__(self, typ):
347 347 """map in to lookup_by_type"""
348 348 try:
349 349 self.lookup_by_type(typ)
350 350 except KeyError:
351 351 return False
352 352 else:
353 353 return True
354 354
355 355 def _check_return(self, r, obj):
356 356 """Check that a return value is appropriate
357 357
358 358 Return the value if so, None otherwise, warning if invalid.
359 359 """
360 360 if r is None or isinstance(r, self._return_type) or \
361 361 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
362 362 return r
363 363 else:
364 364 warnings.warn(
365 365 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
366 366 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
367 367 FormatterWarning
368 368 )
369 369
370 370 def lookup(self, obj):
371 371 """Look up the formatter for a given instance.
372 372
373 373 Parameters
374 374 ----------
375 375 obj : object instance
376 376
377 377 Returns
378 378 -------
379 379 f : callable
380 380 The registered formatting callable for the type.
381 381
382 382 Raises
383 383 ------
384 384 KeyError if the type has not been registered.
385 385 """
386 386 # look for singleton first
387 387 obj_id = id(obj)
388 388 if obj_id in self.singleton_printers:
389 389 return self.singleton_printers[obj_id]
390 390 # then lookup by type
391 391 return self.lookup_by_type(_get_type(obj))
392 392
393 393 def lookup_by_type(self, typ):
394 394 """Look up the registered formatter for a type.
395 395
396 396 Parameters
397 397 ----------
398 398 typ : type or '__module__.__name__' string for a type
399 399
400 400 Returns
401 401 -------
402 402 f : callable
403 403 The registered formatting callable for the type.
404 404
405 405 Raises
406 406 ------
407 407 KeyError if the type has not been registered.
408 408 """
409 409 if isinstance(typ, string_types):
410 410 typ_key = tuple(typ.rsplit('.',1))
411 411 if typ_key not in self.deferred_printers:
412 412 # We may have it cached in the type map. We will have to
413 413 # iterate over all of the types to check.
414 414 for cls in self.type_printers:
415 415 if _mod_name_key(cls) == typ_key:
416 416 return self.type_printers[cls]
417 417 else:
418 418 return self.deferred_printers[typ_key]
419 419 else:
420 420 for cls in pretty._get_mro(typ):
421 421 if cls in self.type_printers or self._in_deferred_types(cls):
422 422 return self.type_printers[cls]
423 423
424 424 # If we have reached here, the lookup failed.
425 425 raise KeyError("No registered printer for {0!r}".format(typ))
426 426
427 427 def for_type(self, typ, func=None):
428 428 """Add a format function for a given type.
429 429
430 430 Parameters
431 431 -----------
432 432 typ : type or '__module__.__name__' string for a type
433 433 The class of the object that will be formatted using `func`.
434 434 func : callable
435 435 A callable for computing the format data.
436 436 `func` will be called with the object to be formatted,
437 437 and will return the raw data in this formatter's format.
438 438 Subclasses may use a different call signature for the
439 439 `func` argument.
440 440
441 441 If `func` is None or not specified, there will be no change,
442 442 only returning the current value.
443 443
444 444 Returns
445 445 -------
446 446 oldfunc : callable
447 447 The currently registered callable.
448 448 If you are registering a new formatter,
449 449 this will be the previous value (to enable restoring later).
450 450 """
451 451 # if string given, interpret as 'pkg.module.class_name'
452 452 if isinstance(typ, string_types):
453 453 type_module, type_name = typ.rsplit('.', 1)
454 454 return self.for_type_by_name(type_module, type_name, func)
455 455
456 456 try:
457 457 oldfunc = self.lookup_by_type(typ)
458 458 except KeyError:
459 459 oldfunc = None
460 460
461 461 if func is not None:
462 462 self.type_printers[typ] = func
463 463
464 464 return oldfunc
465 465
466 466 def for_type_by_name(self, type_module, type_name, func=None):
467 467 """Add a format function for a type specified by the full dotted
468 468 module and name of the type, rather than the type of the object.
469 469
470 470 Parameters
471 471 ----------
472 472 type_module : str
473 473 The full dotted name of the module the type is defined in, like
474 474 ``numpy``.
475 475 type_name : str
476 476 The name of the type (the class name), like ``dtype``
477 477 func : callable
478 478 A callable for computing the format data.
479 479 `func` will be called with the object to be formatted,
480 480 and will return the raw data in this formatter's format.
481 481 Subclasses may use a different call signature for the
482 482 `func` argument.
483 483
484 484 If `func` is None or unspecified, there will be no change,
485 485 only returning the current value.
486 486
487 487 Returns
488 488 -------
489 489 oldfunc : callable
490 490 The currently registered callable.
491 491 If you are registering a new formatter,
492 492 this will be the previous value (to enable restoring later).
493 493 """
494 494 key = (type_module, type_name)
495 495
496 496 try:
497 497 oldfunc = self.lookup_by_type("%s.%s" % key)
498 498 except KeyError:
499 499 oldfunc = None
500 500
501 501 if func is not None:
502 502 self.deferred_printers[key] = func
503 503 return oldfunc
504 504
505 505 def pop(self, typ, default=_raise_key_error):
506 506 """Pop a formatter for the given type.
507 507
508 508 Parameters
509 509 ----------
510 510 typ : type or '__module__.__name__' string for a type
511 511 default : object
512 512 value to be returned if no formatter is registered for typ.
513 513
514 514 Returns
515 515 -------
516 516 obj : object
517 517 The last registered object for the type.
518 518
519 519 Raises
520 520 ------
521 521 KeyError if the type is not registered and default is not specified.
522 522 """
523 523
524 524 if isinstance(typ, string_types):
525 525 typ_key = tuple(typ.rsplit('.',1))
526 526 if typ_key not in self.deferred_printers:
527 527 # We may have it cached in the type map. We will have to
528 528 # iterate over all of the types to check.
529 529 for cls in self.type_printers:
530 530 if _mod_name_key(cls) == typ_key:
531 531 old = self.type_printers.pop(cls)
532 532 break
533 533 else:
534 534 old = default
535 535 else:
536 536 old = self.deferred_printers.pop(typ_key)
537 537 else:
538 538 if typ in self.type_printers:
539 539 old = self.type_printers.pop(typ)
540 540 else:
541 541 old = self.deferred_printers.pop(_mod_name_key(typ), default)
542 542 if old is _raise_key_error:
543 543 raise KeyError("No registered value for {0!r}".format(typ))
544 544 return old
545 545
546 546 def _in_deferred_types(self, cls):
547 547 """
548 548 Check if the given class is specified in the deferred type registry.
549 549
550 550 Successful matches will be moved to the regular type registry for future use.
551 551 """
552 552 mod = getattr(cls, '__module__', None)
553 553 name = getattr(cls, '__name__', None)
554 554 key = (mod, name)
555 555 if key in self.deferred_printers:
556 556 # Move the printer over to the regular registry.
557 557 printer = self.deferred_printers.pop(key)
558 558 self.type_printers[cls] = printer
559 559 return True
560 560 return False
561 561
562 562
563 563 class PlainTextFormatter(BaseFormatter):
564 564 """The default pretty-printer.
565 565
566 566 This uses :mod:`IPython.lib.pretty` to compute the format data of
567 567 the object. If the object cannot be pretty printed, :func:`repr` is used.
568 568 See the documentation of :mod:`IPython.lib.pretty` for details on
569 569 how to write pretty printers. Here is a simple example::
570 570
571 571 def dtype_pprinter(obj, p, cycle):
572 572 if cycle:
573 573 return p.text('dtype(...)')
574 574 if hasattr(obj, 'fields'):
575 575 if obj.fields is None:
576 576 p.text(repr(obj))
577 577 else:
578 578 p.begin_group(7, 'dtype([')
579 579 for i, field in enumerate(obj.descr):
580 580 if i > 0:
581 581 p.text(',')
582 582 p.breakable()
583 583 p.pretty(field)
584 584 p.end_group(7, '])')
585 585 """
586 586
587 587 # The format type of data returned.
588 588 format_type = Unicode('text/plain')
589 589
590 590 # This subclass ignores this attribute as it always need to return
591 591 # something.
592 592 enabled = Bool(True, config=False)
593 593
594 594 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH, config=True,
595 595 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
596 596
597 597 Set to 0 to disable truncation.
598 598 """
599 599 )
600 600
601 601 # Look for a _repr_pretty_ methods to use for pretty printing.
602 602 print_method = ObjectName('_repr_pretty_')
603 603
604 604 # Whether to pretty-print or not.
605 605 pprint = Bool(True, config=True)
606 606
607 607 # Whether to be verbose or not.
608 608 verbose = Bool(False, config=True)
609 609
610 610 # The maximum width.
611 611 max_width = Integer(79, config=True)
612 612
613 613 # The newline character.
614 614 newline = Unicode('\n', config=True)
615 615
616 616 # format-string for pprinting floats
617 617 float_format = Unicode('%r')
618 618 # setter for float precision, either int or direct format-string
619 619 float_precision = CUnicode('', config=True)
620 620
621 621 def _float_precision_changed(self, name, old, new):
622 622 """float_precision changed, set float_format accordingly.
623 623
624 624 float_precision can be set by int or str.
625 625 This will set float_format, after interpreting input.
626 626 If numpy has been imported, numpy print precision will also be set.
627 627
628 628 integer `n` sets format to '%.nf', otherwise, format set directly.
629 629
630 630 An empty string returns to defaults (repr for float, 8 for numpy).
631 631
632 632 This parameter can be set via the '%precision' magic.
633 633 """
634 634
635 635 if '%' in new:
636 636 # got explicit format string
637 637 fmt = new
638 638 try:
639 639 fmt%3.14159
640 640 except Exception:
641 641 raise ValueError("Precision must be int or format string, not %r"%new)
642 642 elif new:
643 643 # otherwise, should be an int
644 644 try:
645 645 i = int(new)
646 646 assert i >= 0
647 647 except ValueError:
648 648 raise ValueError("Precision must be int or format string, not %r"%new)
649 649 except AssertionError:
650 650 raise ValueError("int precision must be non-negative, not %r"%i)
651 651
652 652 fmt = '%%.%if'%i
653 653 if 'numpy' in sys.modules:
654 654 # set numpy precision if it has been imported
655 655 import numpy
656 656 numpy.set_printoptions(precision=i)
657 657 else:
658 658 # default back to repr
659 659 fmt = '%r'
660 660 if 'numpy' in sys.modules:
661 661 import numpy
662 662 # numpy default is 8
663 663 numpy.set_printoptions(precision=8)
664 664 self.float_format = fmt
665 665
666 666 # Use the default pretty printers from IPython.lib.pretty.
667 667 def _singleton_printers_default(self):
668 668 return pretty._singleton_pprinters.copy()
669 669
670 670 def _type_printers_default(self):
671 671 d = pretty._type_pprinters.copy()
672 672 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
673 673 return d
674 674
675 675 def _deferred_printers_default(self):
676 676 return pretty._deferred_type_pprinters.copy()
677 677
678 678 #### FormatterABC interface ####
679 679
680 680 @catch_format_error
681 681 def __call__(self, obj):
682 682 """Compute the pretty representation of the object."""
683 683 if not self.pprint:
684 684 return repr(obj)
685 685 else:
686 686 # handle str and unicode on Python 2
687 687 # io.StringIO only accepts unicode,
688 688 # cStringIO doesn't handle unicode on py2,
689 689 # StringIO allows str, unicode but only ascii str
690 690 stream = pretty.CUnicodeIO()
691 691 printer = pretty.RepresentationPrinter(stream, self.verbose,
692 692 self.max_width, self.newline,
693 693 max_seq_length=self.max_seq_length,
694 694 singleton_pprinters=self.singleton_printers,
695 695 type_pprinters=self.type_printers,
696 696 deferred_pprinters=self.deferred_printers)
697 697 printer.pretty(obj)
698 698 printer.flush()
699 699 return stream.getvalue()
700 700
701 701
702 702 class HTMLFormatter(BaseFormatter):
703 703 """An HTML formatter.
704 704
705 705 To define the callables that compute the HTML representation of your
706 706 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
707 707 or :meth:`for_type_by_name` methods to register functions that handle
708 708 this.
709 709
710 710 The return value of this formatter should be a valid HTML snippet that
711 711 could be injected into an existing DOM. It should *not* include the
712 712 ```<html>`` or ```<body>`` tags.
713 713 """
714 714 format_type = Unicode('text/html')
715 715
716 716 print_method = ObjectName('_repr_html_')
717 717
718 718
719 719 class MarkdownFormatter(BaseFormatter):
720 720 """A Markdown formatter.
721 721
722 722 To define the callables that compute the Markdown representation of your
723 723 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
724 724 or :meth:`for_type_by_name` methods to register functions that handle
725 725 this.
726 726
727 727 The return value of this formatter should be a valid Markdown.
728 728 """
729 729 format_type = Unicode('text/markdown')
730 730
731 731 print_method = ObjectName('_repr_markdown_')
732 732
733 733 class SVGFormatter(BaseFormatter):
734 734 """An SVG formatter.
735 735
736 736 To define the callables that compute the SVG representation of your
737 737 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
738 738 or :meth:`for_type_by_name` methods to register functions that handle
739 739 this.
740 740
741 741 The return value of this formatter should be valid SVG enclosed in
742 742 ```<svg>``` tags, that could be injected into an existing DOM. It should
743 743 *not* include the ```<html>`` or ```<body>`` tags.
744 744 """
745 745 format_type = Unicode('image/svg+xml')
746 746
747 747 print_method = ObjectName('_repr_svg_')
748 748
749 749
750 750 class PNGFormatter(BaseFormatter):
751 751 """A PNG formatter.
752 752
753 753 To define the callables that compute the PNG representation of your
754 754 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
755 755 or :meth:`for_type_by_name` methods to register functions that handle
756 756 this.
757 757
758 758 The return value of this formatter should be raw PNG data, *not*
759 759 base64 encoded.
760 760 """
761 761 format_type = Unicode('image/png')
762 762
763 763 print_method = ObjectName('_repr_png_')
764 764
765 765 _return_type = (bytes, unicode_type)
766 766
767 767
768 768 class JPEGFormatter(BaseFormatter):
769 769 """A JPEG formatter.
770 770
771 771 To define the callables that compute the JPEG representation of your
772 772 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
773 773 or :meth:`for_type_by_name` methods to register functions that handle
774 774 this.
775 775
776 776 The return value of this formatter should be raw JPEG data, *not*
777 777 base64 encoded.
778 778 """
779 779 format_type = Unicode('image/jpeg')
780 780
781 781 print_method = ObjectName('_repr_jpeg_')
782 782
783 783 _return_type = (bytes, unicode_type)
784 784
785 785
786 786 class LatexFormatter(BaseFormatter):
787 787 """A LaTeX formatter.
788 788
789 789 To define the callables that compute the LaTeX representation of your
790 790 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
791 791 or :meth:`for_type_by_name` methods to register functions that handle
792 792 this.
793 793
794 794 The return value of this formatter should be a valid LaTeX equation,
795 795 enclosed in either ```$```, ```$$``` or another LaTeX equation
796 796 environment.
797 797 """
798 798 format_type = Unicode('text/latex')
799 799
800 800 print_method = ObjectName('_repr_latex_')
801 801
802 802
803 803 class JSONFormatter(BaseFormatter):
804 804 """A JSON string formatter.
805 805
806 806 To define the callables that compute the JSONable representation of
807 807 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
808 808 or :meth:`for_type_by_name` methods to register functions that handle
809 809 this.
810 810
811 811 The return value of this formatter should be a JSONable list or dict.
812 812 JSON scalars (None, number, string) are not allowed, only dict or list containers.
813 813 """
814 814 format_type = Unicode('application/json')
815 815 _return_type = (list, dict)
816 816
817 817 print_method = ObjectName('_repr_json_')
818 818
819 819 def _check_return(self, r, obj):
820 820 """Check that a return value is appropriate
821 821
822 822 Return the value if so, None otherwise, warning if invalid.
823 823 """
824 824 if r is None:
825 825 return
826 826 md = None
827 827 if isinstance(r, tuple):
828 828 # unpack data, metadata tuple for type checking on first element
829 829 r, md = r
830 830
831 831 # handle deprecated JSON-as-string form from IPython < 3
832 832 if isinstance(r, string_types):
833 833 warnings.warn("JSON expects JSONable list/dict containers, not JSON strings",
834 834 FormatterWarning)
835 835 r = json.loads(r)
836 836
837 837 if md is not None:
838 838 # put the tuple back together
839 839 r = (r, md)
840 840 return super(JSONFormatter, self)._check_return(r, obj)
841 841
842 842
843 843 class JavascriptFormatter(BaseFormatter):
844 844 """A Javascript formatter.
845 845
846 846 To define the callables that compute the Javascript representation of
847 847 your objects, define a :meth:`_repr_javascript_` method or use the
848 848 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
849 849 that handle this.
850 850
851 851 The return value of this formatter should be valid Javascript code and
852 852 should *not* be enclosed in ```<script>``` tags.
853 853 """
854 854 format_type = Unicode('application/javascript')
855 855
856 856 print_method = ObjectName('_repr_javascript_')
857 857
858 858
859 859 class PDFFormatter(BaseFormatter):
860 860 """A PDF formatter.
861 861
862 862 To define the callables that compute the PDF representation of your
863 863 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
864 864 or :meth:`for_type_by_name` methods to register functions that handle
865 865 this.
866 866
867 867 The return value of this formatter should be raw PDF data, *not*
868 868 base64 encoded.
869 869 """
870 870 format_type = Unicode('application/pdf')
871 871
872 872 print_method = ObjectName('_repr_pdf_')
873 873
874 874 _return_type = (bytes, unicode_type)
875 875
876 876 class IPythonDisplayFormatter(BaseFormatter):
877 877 """A Formatter for objects that know how to display themselves.
878 878
879 879 To define the callables that compute the representation of your
880 880 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
881 881 or :meth:`for_type_by_name` methods to register functions that handle
882 882 this. Unlike mime-type displays, this method should not return anything,
883 883 instead calling any appropriate display methods itself.
884 884
885 885 This display formatter has highest priority.
886 886 If it fires, no other display formatter will be called.
887 887 """
888 888 print_method = ObjectName('_ipython_display_')
889 889 _return_type = (type(None), bool)
890 890
891 891
892 892 @catch_format_error
893 893 def __call__(self, obj):
894 894 """Compute the format for an object."""
895 895 if self.enabled:
896 896 # lookup registered printer
897 897 try:
898 898 printer = self.lookup(obj)
899 899 except KeyError:
900 900 pass
901 901 else:
902 902 printer(obj)
903 903 return True
904 904 # Finally look for special method names
905 905 method = _safe_get_formatter_method(obj, self.print_method)
906 906 if method is not None:
907 907 method()
908 908 return True
909 909
910 910
911 911 FormatterABC.register(BaseFormatter)
912 912 FormatterABC.register(PlainTextFormatter)
913 913 FormatterABC.register(HTMLFormatter)
914 914 FormatterABC.register(MarkdownFormatter)
915 915 FormatterABC.register(SVGFormatter)
916 916 FormatterABC.register(PNGFormatter)
917 917 FormatterABC.register(PDFFormatter)
918 918 FormatterABC.register(JPEGFormatter)
919 919 FormatterABC.register(LatexFormatter)
920 920 FormatterABC.register(JSONFormatter)
921 921 FormatterABC.register(JavascriptFormatter)
922 922 FormatterABC.register(IPythonDisplayFormatter)
923 923
924 924
925 925 def format_display_data(obj, include=None, exclude=None):
926 926 """Return a format data dict for an object.
927 927
928 928 By default all format types will be computed.
929 929
930 930 The following MIME types are currently implemented:
931 931
932 932 * text/plain
933 933 * text/html
934 934 * text/markdown
935 935 * text/latex
936 936 * application/json
937 937 * application/javascript
938 938 * application/pdf
939 939 * image/png
940 940 * image/jpeg
941 941 * image/svg+xml
942 942
943 943 Parameters
944 944 ----------
945 945 obj : object
946 946 The Python object whose format data will be computed.
947 947
948 948 Returns
949 949 -------
950 950 format_dict : dict
951 951 A dictionary of key/value pairs, one or each format that was
952 952 generated for the object. The keys are the format types, which
953 953 will usually be MIME type strings and the values and JSON'able
954 954 data structure containing the raw data for the representation in
955 955 that format.
956 956 include : list or tuple, optional
957 957 A list of format type strings (MIME types) to include in the
958 958 format data dict. If this is set *only* the format types included
959 959 in this list will be computed.
960 960 exclude : list or tuple, optional
961 961 A list of format type string (MIME types) to exclue in the format
962 962 data dict. If this is set all format types will be computed,
963 963 except for those included in this argument.
964 964 """
965 965 from IPython.core.interactiveshell import InteractiveShell
966 966
967 967 InteractiveShell.instance().display_formatter.format(
968 968 obj,
969 969 include,
970 970 exclude
971 971 )
972 972
@@ -1,832 +1,817 b''
1 1 """Function signature objects for callables.
2 2
3 3 Back port of Python 3.3's function signature tools from the inspect module,
4 4 modified to be compatible with Python 2.7 and 3.2+.
5 5 """
6 6
7 7 #-----------------------------------------------------------------------------
8 8 # Python 3.3 stdlib inspect.py is public domain
9 9 #
10 10 # Backports Copyright (C) 2013 Aaron Iles
11 11 # Used under Apache License Version 2.0
12 12 #
13 13 # Further Changes are Copyright (C) 2013 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 from __future__ import absolute_import, division, print_function
20 20 import itertools
21 21 import functools
22 22 import re
23 23 import types
24 24
25 25
26 26 # patch for single-file
27 27 # we don't support 2.6, so we can just import OrderedDict
28 28 from collections import OrderedDict
29 29
30 30 __version__ = '0.3'
31 31 # end patch
32 32
33 33 __all__ = ['BoundArguments', 'Parameter', 'Signature', 'signature']
34 34
35 35
36 36 _WrapperDescriptor = type(type.__call__)
37 37 _MethodWrapper = type(all.__call__)
38 38
39 39 _NonUserDefinedCallables = (_WrapperDescriptor,
40 40 _MethodWrapper,
41 41 types.BuiltinFunctionType)
42 42
43 43
44 44 def formatannotation(annotation, base_module=None):
45 45 if isinstance(annotation, type):
46 46 if annotation.__module__ in ('builtins', '__builtin__', base_module):
47 47 return annotation.__name__
48 48 return annotation.__module__+'.'+annotation.__name__
49 49 return repr(annotation)
50 50
51 51
52 52 def _get_user_defined_method(cls, method_name, *nested):
53 53 try:
54 54 if cls is type:
55 55 return
56 56 meth = getattr(cls, method_name)
57 57 for name in nested:
58 58 meth = getattr(meth, name, meth)
59 59 except AttributeError:
60 60 return
61 61 else:
62 62 if not isinstance(meth, _NonUserDefinedCallables):
63 63 # Once '__signature__' will be added to 'C'-level
64 64 # callables, this check won't be necessary
65 65 return meth
66 66
67 67
68 68 def signature(obj):
69 69 '''Get a signature object for the passed callable.'''
70 70
71 71 if not callable(obj):
72 72 raise TypeError('{0!r} is not a callable object'.format(obj))
73 73
74 74 if isinstance(obj, types.MethodType):
75 75 if obj.__self__ is None:
76 76 # Unbound method - treat it as a function (no distinction in Py 3)
77 77 obj = obj.__func__
78 78 else:
79 79 # Bound method: trim off the first parameter (typically self or cls)
80 80 sig = signature(obj.__func__)
81 81 return sig.replace(parameters=tuple(sig.parameters.values())[1:])
82 82
83 83 try:
84 84 sig = obj.__signature__
85 85 except AttributeError:
86 86 pass
87 87 else:
88 88 if sig is not None:
89 89 return sig
90 90
91 91 try:
92 92 # Was this function wrapped by a decorator?
93 93 wrapped = obj.__wrapped__
94 94 except AttributeError:
95 95 pass
96 96 else:
97 97 return signature(wrapped)
98 98
99 99 if isinstance(obj, types.FunctionType):
100 100 return Signature.from_function(obj)
101 101
102 102 if isinstance(obj, functools.partial):
103 103 sig = signature(obj.func)
104 104
105 105 new_params = OrderedDict(sig.parameters.items())
106 106
107 107 partial_args = obj.args or ()
108 108 partial_keywords = obj.keywords or {}
109 109 try:
110 110 ba = sig.bind_partial(*partial_args, **partial_keywords)
111 111 except TypeError as ex:
112 112 msg = 'partial object {0!r} has incorrect arguments'.format(obj)
113 113 raise ValueError(msg)
114 114
115 115 for arg_name, arg_value in ba.arguments.items():
116 116 param = new_params[arg_name]
117 117 if arg_name in partial_keywords:
118 118 # We set a new default value, because the following code
119 119 # is correct:
120 120 #
121 121 # >>> def foo(a): print(a)
122 122 # >>> print(partial(partial(foo, a=10), a=20)())
123 123 # 20
124 124 # >>> print(partial(partial(foo, a=10), a=20)(a=30))
125 125 # 30
126 126 #
127 127 # So, with 'partial' objects, passing a keyword argument is
128 128 # like setting a new default value for the corresponding
129 129 # parameter
130 130 #
131 131 # We also mark this parameter with '_partial_kwarg'
132 132 # flag. Later, in '_bind', the 'default' value of this
133 133 # parameter will be added to 'kwargs', to simulate
134 134 # the 'functools.partial' real call.
135 135 new_params[arg_name] = param.replace(default=arg_value,
136 136 _partial_kwarg=True)
137 137
138 138 elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and
139 139 not param._partial_kwarg):
140 140 new_params.pop(arg_name)
141 141
142 142 return sig.replace(parameters=new_params.values())
143 143
144 144 sig = None
145 145 if isinstance(obj, type):
146 146 # obj is a class or a metaclass
147 147
148 148 # First, let's see if it has an overloaded __call__ defined
149 149 # in its metaclass
150 150 call = _get_user_defined_method(type(obj), '__call__')
151 151 if call is not None:
152 152 sig = signature(call)
153 153 else:
154 154 # Now we check if the 'obj' class has a '__new__' method
155 155 new = _get_user_defined_method(obj, '__new__')
156 156 if new is not None:
157 157 sig = signature(new)
158 158 else:
159 159 # Finally, we should have at least __init__ implemented
160 160 init = _get_user_defined_method(obj, '__init__')
161 161 if init is not None:
162 162 sig = signature(init)
163 163 elif not isinstance(obj, _NonUserDefinedCallables):
164 164 # An object with __call__
165 165 # We also check that the 'obj' is not an instance of
166 166 # _WrapperDescriptor or _MethodWrapper to avoid
167 167 # infinite recursion (and even potential segfault)
168 168 call = _get_user_defined_method(type(obj), '__call__', 'im_func')
169 169 if call is not None:
170 170 sig = signature(call)
171 171
172 172 if sig is not None:
173 173 return sig
174 174
175 175 if isinstance(obj, types.BuiltinFunctionType):
176 176 # Raise a nicer error message for builtins
177 177 msg = 'no signature found for builtin function {0!r}'.format(obj)
178 178 raise ValueError(msg)
179 179
180 180 raise ValueError('callable {0!r} is not supported by signature'.format(obj))
181 181
182 182
183 183 class _void(object):
184 184 '''A private marker - used in Parameter & Signature'''
185 185
186 186
187 187 class _empty(object):
188 188 pass
189 189
190 190
191 191 class _ParameterKind(int):
192 192 def __new__(self, *args, **kwargs):
193 193 obj = int.__new__(self, *args)
194 194 obj._name = kwargs['name']
195 195 return obj
196 196
197 197 def __str__(self):
198 198 return self._name
199 199
200 200 def __repr__(self):
201 201 return '<_ParameterKind: {0!r}>'.format(self._name)
202 202
203 203
204 204 _POSITIONAL_ONLY = _ParameterKind(0, name='POSITIONAL_ONLY')
205 205 _POSITIONAL_OR_KEYWORD = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD')
206 206 _VAR_POSITIONAL = _ParameterKind(2, name='VAR_POSITIONAL')
207 207 _KEYWORD_ONLY = _ParameterKind(3, name='KEYWORD_ONLY')
208 208 _VAR_KEYWORD = _ParameterKind(4, name='VAR_KEYWORD')
209 209
210 210
211 211 class Parameter(object):
212 212 '''Represents a parameter in a function signature.
213 213
214 214 Has the following public attributes:
215 215
216 216 * name : str
217 217 The name of the parameter as a string.
218 218 * default : object
219 219 The default value for the parameter if specified. If the
220 220 parameter has no default value, this attribute is not set.
221 221 * annotation
222 222 The annotation for the parameter if specified. If the
223 223 parameter has no annotation, this attribute is not set.
224 224 * kind : str
225 225 Describes how argument values are bound to the parameter.
226 226 Possible values: `Parameter.POSITIONAL_ONLY`,
227 227 `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
228 228 `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
229 229 '''
230 230
231 231 __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg')
232 232
233 233 POSITIONAL_ONLY = _POSITIONAL_ONLY
234 234 POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
235 235 VAR_POSITIONAL = _VAR_POSITIONAL
236 236 KEYWORD_ONLY = _KEYWORD_ONLY
237 237 VAR_KEYWORD = _VAR_KEYWORD
238 238
239 239 empty = _empty
240 240
241 241 def __init__(self, name, kind, default=_empty, annotation=_empty,
242 242 _partial_kwarg=False):
243 243
244 244 if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
245 245 _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
246 246 raise ValueError("invalid value for 'Parameter.kind' attribute")
247 247 self._kind = kind
248 248
249 249 if default is not _empty:
250 250 if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
251 251 msg = '{0} parameters cannot have default values'.format(kind)
252 252 raise ValueError(msg)
253 253 self._default = default
254 254 self._annotation = annotation
255 255
256 256 if name is None:
257 257 if kind != _POSITIONAL_ONLY:
258 258 raise ValueError("None is not a valid name for a "
259 259 "non-positional-only parameter")
260 260 self._name = name
261 261 else:
262 262 name = str(name)
263 263 if kind != _POSITIONAL_ONLY and not re.match(r'[a-z_]\w*$', name, re.I):
264 264 msg = '{0!r} is not a valid parameter name'.format(name)
265 265 raise ValueError(msg)
266 266 self._name = name
267 267
268 268 self._partial_kwarg = _partial_kwarg
269 269
270 270 @property
271 271 def name(self):
272 272 return self._name
273 273
274 274 @property
275 275 def default(self):
276 276 return self._default
277 277
278 278 @property
279 279 def annotation(self):
280 280 return self._annotation
281 281
282 282 @property
283 283 def kind(self):
284 284 return self._kind
285 285
286 286 def replace(self, name=_void, kind=_void, annotation=_void,
287 287 default=_void, _partial_kwarg=_void):
288 288 '''Creates a customized copy of the Parameter.'''
289 289
290 290 if name is _void:
291 291 name = self._name
292 292
293 293 if kind is _void:
294 294 kind = self._kind
295 295
296 296 if annotation is _void:
297 297 annotation = self._annotation
298 298
299 299 if default is _void:
300 300 default = self._default
301 301
302 302 if _partial_kwarg is _void:
303 303 _partial_kwarg = self._partial_kwarg
304 304
305 305 return type(self)(name, kind, default=default, annotation=annotation,
306 306 _partial_kwarg=_partial_kwarg)
307 307
308 308 def __str__(self):
309 309 kind = self.kind
310 310
311 311 formatted = self._name
312 312 if kind == _POSITIONAL_ONLY:
313 313 if formatted is None:
314 314 formatted = ''
315 315 formatted = '<{0}>'.format(formatted)
316 316
317 317 # Add annotation and default value
318 318 if self._annotation is not _empty:
319 319 formatted = '{0}:{1}'.format(formatted,
320 320 formatannotation(self._annotation))
321 321
322 322 if self._default is not _empty:
323 323 formatted = '{0}={1}'.format(formatted, repr(self._default))
324 324
325 325 if kind == _VAR_POSITIONAL:
326 326 formatted = '*' + formatted
327 327 elif kind == _VAR_KEYWORD:
328 328 formatted = '**' + formatted
329 329
330 330 return formatted
331 331
332 332 def __repr__(self):
333 333 return '<{0} at {1:#x} {2!r}>'.format(self.__class__.__name__,
334 334 id(self), self.name)
335 335
336 336 def __hash__(self):
337 337 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
338 338 raise TypeError(msg)
339 339
340 340 def __eq__(self, other):
341 341 return (issubclass(other.__class__, Parameter) and
342 342 self._name == other._name and
343 343 self._kind == other._kind and
344 344 self._default == other._default and
345 345 self._annotation == other._annotation)
346 346
347 347 def __ne__(self, other):
348 348 return not self.__eq__(other)
349 349
350 350
351 351 class BoundArguments(object):
352 352 '''Result of :meth:`Signature.bind` call. Holds the mapping of arguments
353 353 to the function's parameters.
354 354
355 355 Has the following public attributes:
356 356
357 357 arguments : :class:`collections.OrderedDict`
358 358 An ordered mutable mapping of parameters' names to arguments' values.
359 359 Does not contain arguments' default values.
360 360 signature : :class:`Signature`
361 361 The Signature object that created this instance.
362 362 args : tuple
363 363 Tuple of positional arguments values.
364 364 kwargs : dict
365 365 Dict of keyword arguments values.
366 366 '''
367 367
368 368 def __init__(self, signature, arguments):
369 369 self.arguments = arguments
370 370 self._signature = signature
371 371
372 372 @property
373 373 def signature(self):
374 374 return self._signature
375 375
376 376 @property
377 377 def args(self):
378 378 args = []
379 379 for param_name, param in self._signature.parameters.items():
380 380 if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
381 381 param._partial_kwarg):
382 382 # Keyword arguments mapped by 'functools.partial'
383 383 # (Parameter._partial_kwarg is True) are mapped
384 384 # in 'BoundArguments.kwargs', along with VAR_KEYWORD &
385 385 # KEYWORD_ONLY
386 386 break
387 387
388 388 try:
389 389 arg = self.arguments[param_name]
390 390 except KeyError:
391 391 # We're done here. Other arguments
392 392 # will be mapped in 'BoundArguments.kwargs'
393 393 break
394 394 else:
395 395 if param.kind == _VAR_POSITIONAL:
396 396 # *args
397 397 args.extend(arg)
398 398 else:
399 399 # plain argument
400 400 args.append(arg)
401 401
402 402 return tuple(args)
403 403
404 404 @property
405 405 def kwargs(self):
406 406 kwargs = {}
407 407 kwargs_started = False
408 408 for param_name, param in self._signature.parameters.items():
409 409 if not kwargs_started:
410 410 if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
411 411 param._partial_kwarg):
412 412 kwargs_started = True
413 413 else:
414 414 if param_name not in self.arguments:
415 415 kwargs_started = True
416 416 continue
417 417
418 418 if not kwargs_started:
419 419 continue
420 420
421 421 try:
422 422 arg = self.arguments[param_name]
423 423 except KeyError:
424 424 pass
425 425 else:
426 426 if param.kind == _VAR_KEYWORD:
427 427 # **kwargs
428 428 kwargs.update(arg)
429 429 else:
430 430 # plain keyword argument
431 431 kwargs[param_name] = arg
432 432
433 433 return kwargs
434 434
435 435 def __hash__(self):
436 436 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
437 437 raise TypeError(msg)
438 438
439 439 def __eq__(self, other):
440 440 return (issubclass(other.__class__, BoundArguments) and
441 441 self.signature == other.signature and
442 442 self.arguments == other.arguments)
443 443
444 444 def __ne__(self, other):
445 445 return not self.__eq__(other)
446 446
447 447
448 448 class Signature(object):
449 449 '''A Signature object represents the overall signature of a function.
450 450 It stores a Parameter object for each parameter accepted by the
451 451 function, as well as information specific to the function itself.
452 452
453 453 A Signature object has the following public attributes:
454 454
455 455 parameters : :class:`collections.OrderedDict`
456 456 An ordered mapping of parameters' names to the corresponding
457 457 Parameter objects (keyword-only arguments are in the same order
458 458 as listed in `code.co_varnames`).
459 459 return_annotation
460 460 The annotation for the return type of the function if specified.
461 461 If the function has no annotation for its return type, this
462 462 attribute is not set.
463 463 '''
464 464
465 465 __slots__ = ('_return_annotation', '_parameters')
466 466
467 467 _parameter_cls = Parameter
468 468 _bound_arguments_cls = BoundArguments
469 469
470 470 empty = _empty
471 471
472 472 def __init__(self, parameters=None, return_annotation=_empty,
473 473 __validate_parameters__=True):
474 474 '''Constructs Signature from the given list of Parameter
475 475 objects and 'return_annotation'. All arguments are optional.
476 476 '''
477 477
478 478 if parameters is None:
479 479 params = OrderedDict()
480 480 else:
481 481 if __validate_parameters__:
482 482 params = OrderedDict()
483 483 top_kind = _POSITIONAL_ONLY
484 484
485 485 for idx, param in enumerate(parameters):
486 486 kind = param.kind
487 487 if kind < top_kind:
488 488 msg = 'wrong parameter order: {0} before {1}'
489 489 msg = msg.format(top_kind, param.kind)
490 490 raise ValueError(msg)
491 491 else:
492 492 top_kind = kind
493 493
494 494 name = param.name
495 495 if name is None:
496 496 name = str(idx)
497 497 param = param.replace(name=name)
498 498
499 499 if name in params:
500 500 msg = 'duplicate parameter name: {0!r}'.format(name)
501 501 raise ValueError(msg)
502 502 params[name] = param
503 503 else:
504 504 params = OrderedDict(((param.name, param)
505 505 for param in parameters))
506 506
507 507 self._parameters = params
508 508 self._return_annotation = return_annotation
509 509
510 510 @classmethod
511 511 def from_function(cls, func):
512 512 '''Constructs Signature for the given python function'''
513 513
514 514 if not isinstance(func, types.FunctionType):
515 515 raise TypeError('{0!r} is not a Python function'.format(func))
516 516
517 517 Parameter = cls._parameter_cls
518 518
519 519 # Parameter information.
520 520 func_code = func.__code__
521 521 pos_count = func_code.co_argcount
522 522 arg_names = func_code.co_varnames
523 523 positional = tuple(arg_names[:pos_count])
524 524 keyword_only_count = getattr(func_code, 'co_kwonlyargcount', 0)
525 525 keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
526 526 annotations = getattr(func, '__annotations__', {})
527 527 defaults = func.__defaults__
528 528 kwdefaults = getattr(func, '__kwdefaults__', None)
529 529
530 530 if defaults:
531 531 pos_default_count = len(defaults)
532 532 else:
533 533 pos_default_count = 0
534 534
535 535 parameters = []
536 536
537 537 # Non-keyword-only parameters w/o defaults.
538 538 non_default_count = pos_count - pos_default_count
539 539 for name in positional[:non_default_count]:
540 540 annotation = annotations.get(name, _empty)
541 541 parameters.append(Parameter(name, annotation=annotation,
542 542 kind=_POSITIONAL_OR_KEYWORD))
543 543
544 544 # ... w/ defaults.
545 545 for offset, name in enumerate(positional[non_default_count:]):
546 546 annotation = annotations.get(name, _empty)
547 547 parameters.append(Parameter(name, annotation=annotation,
548 548 kind=_POSITIONAL_OR_KEYWORD,
549 549 default=defaults[offset]))
550 550
551 551 # *args
552 552 if func_code.co_flags & 0x04:
553 553 name = arg_names[pos_count + keyword_only_count]
554 554 annotation = annotations.get(name, _empty)
555 555 parameters.append(Parameter(name, annotation=annotation,
556 556 kind=_VAR_POSITIONAL))
557 557
558 558 # Keyword-only parameters.
559 559 for name in keyword_only:
560 560 default = _empty
561 561 if kwdefaults is not None:
562 562 default = kwdefaults.get(name, _empty)
563 563
564 564 annotation = annotations.get(name, _empty)
565 565 parameters.append(Parameter(name, annotation=annotation,
566 566 kind=_KEYWORD_ONLY,
567 567 default=default))
568 568 # **kwargs
569 569 if func_code.co_flags & 0x08:
570 570 index = pos_count + keyword_only_count
571 571 if func_code.co_flags & 0x04:
572 572 index += 1
573 573
574 574 name = arg_names[index]
575 575 annotation = annotations.get(name, _empty)
576 576 parameters.append(Parameter(name, annotation=annotation,
577 577 kind=_VAR_KEYWORD))
578 578
579 579 return cls(parameters,
580 580 return_annotation=annotations.get('return', _empty),
581 581 __validate_parameters__=False)
582 582
583 583 @property
584 584 def parameters(self):
585 585 try:
586 586 return types.MappingProxyType(self._parameters)
587 587 except AttributeError:
588 588 return OrderedDict(self._parameters.items())
589 589
590 590 @property
591 591 def return_annotation(self):
592 592 return self._return_annotation
593 593
594 594 def replace(self, parameters=_void, return_annotation=_void):
595 595 '''Creates a customized copy of the Signature.
596 596 Pass 'parameters' and/or 'return_annotation' arguments
597 597 to override them in the new copy.
598 598 '''
599 599
600 600 if parameters is _void:
601 601 parameters = self.parameters.values()
602 602
603 603 if return_annotation is _void:
604 604 return_annotation = self._return_annotation
605 605
606 606 return type(self)(parameters,
607 607 return_annotation=return_annotation)
608 608
609 609 def __hash__(self):
610 610 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
611 611 raise TypeError(msg)
612 612
613 613 def __eq__(self, other):
614 614 if (not issubclass(type(other), Signature) or
615 615 self.return_annotation != other.return_annotation or
616 616 len(self.parameters) != len(other.parameters)):
617 617 return False
618 618
619 619 other_positions = dict((param, idx)
620 620 for idx, param in enumerate(other.parameters.keys()))
621 621
622 622 for idx, (param_name, param) in enumerate(self.parameters.items()):
623 623 if param.kind == _KEYWORD_ONLY:
624 624 try:
625 625 other_param = other.parameters[param_name]
626 626 except KeyError:
627 627 return False
628 628 else:
629 629 if param != other_param:
630 630 return False
631 631 else:
632 632 try:
633 633 other_idx = other_positions[param_name]
634 634 except KeyError:
635 635 return False
636 636 else:
637 637 if (idx != other_idx or
638 638 param != other.parameters[param_name]):
639 639 return False
640 640
641 641 return True
642 642
643 643 def __ne__(self, other):
644 644 return not self.__eq__(other)
645 645
646 646 def _bind(self, args, kwargs, partial=False):
647 647 '''Private method. Don't use directly.'''
648 648
649 649 arguments = OrderedDict()
650 650
651 651 parameters = iter(self.parameters.values())
652 652 parameters_ex = ()
653 653 arg_vals = iter(args)
654 654
655 655 if partial:
656 656 # Support for binding arguments to 'functools.partial' objects.
657 657 # See 'functools.partial' case in 'signature()' implementation
658 658 # for details.
659 659 for param_name, param in self.parameters.items():
660 660 if (param._partial_kwarg and param_name not in kwargs):
661 661 # Simulating 'functools.partial' behavior
662 662 kwargs[param_name] = param.default
663 663
664 664 while True:
665 665 # Let's iterate through the positional arguments and corresponding
666 666 # parameters
667 667 try:
668 668 arg_val = next(arg_vals)
669 669 except StopIteration:
670 670 # No more positional arguments
671 671 try:
672 672 param = next(parameters)
673 673 except StopIteration:
674 674 # No more parameters. That's it. Just need to check that
675 675 # we have no `kwargs` after this while loop
676 676 break
677 677 else:
678 678 if param.kind == _VAR_POSITIONAL:
679 679 # That's OK, just empty *args. Let's start parsing
680 680 # kwargs
681 681 break
682 682 elif param.name in kwargs:
683 683 if param.kind == _POSITIONAL_ONLY:
684 684 msg = '{arg!r} parameter is positional only, ' \
685 685 'but was passed as a keyword'
686 686 msg = msg.format(arg=param.name)
687 687 raise TypeError(msg)
688 688 parameters_ex = (param,)
689 689 break
690 690 elif (param.kind == _VAR_KEYWORD or
691 691 param.default is not _empty):
692 692 # That's fine too - we have a default value for this
693 693 # parameter. So, lets start parsing `kwargs`, starting
694 694 # with the current parameter
695 695 parameters_ex = (param,)
696 696 break
697 697 else:
698 698 if partial:
699 699 parameters_ex = (param,)
700 700 break
701 701 else:
702 702 msg = '{arg!r} parameter lacking default value'
703 703 msg = msg.format(arg=param.name)
704 704 raise TypeError(msg)
705 705 else:
706 706 # We have a positional argument to process
707 707 try:
708 708 param = next(parameters)
709 709 except StopIteration:
710 710 raise TypeError('too many positional arguments')
711 711 else:
712 712 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
713 713 # Looks like we have no parameter for this positional
714 714 # argument
715 715 raise TypeError('too many positional arguments')
716 716
717 717 if param.kind == _VAR_POSITIONAL:
718 718 # We have an '*args'-like argument, let's fill it with
719 719 # all positional arguments we have left and move on to
720 720 # the next phase
721 721 values = [arg_val]
722 722 values.extend(arg_vals)
723 723 arguments[param.name] = tuple(values)
724 724 break
725 725
726 726 if param.name in kwargs:
727 727 raise TypeError('multiple values for argument '
728 728 '{arg!r}'.format(arg=param.name))
729 729
730 730 arguments[param.name] = arg_val
731 731
732 732 # Now, we iterate through the remaining parameters to process
733 733 # keyword arguments
734 734 kwargs_param = None
735 735 for param in itertools.chain(parameters_ex, parameters):
736 736 if param.kind == _POSITIONAL_ONLY:
737 737 # This should never happen in case of a properly built
738 738 # Signature object (but let's have this check here
739 739 # to ensure correct behaviour just in case)
740 740 raise TypeError('{arg!r} parameter is positional only, '
741 741 'but was passed as a keyword'. \
742 742 format(arg=param.name))
743 743
744 744 if param.kind == _VAR_KEYWORD:
745 745 # Memorize that we have a '**kwargs'-like parameter
746 746 kwargs_param = param
747 747 continue
748 748
749 749 param_name = param.name
750 750 try:
751 751 arg_val = kwargs.pop(param_name)
752 752 except KeyError:
753 753 # We have no value for this parameter. It's fine though,
754 754 # if it has a default value, or it is an '*args'-like
755 755 # parameter, left alone by the processing of positional
756 756 # arguments.
757 757 if (not partial and param.kind != _VAR_POSITIONAL and
758 758 param.default is _empty):
759 759 raise TypeError('{arg!r} parameter lacking default value'. \
760 760 format(arg=param_name))
761 761
762 762 else:
763 763 arguments[param_name] = arg_val
764 764
765 765 if kwargs:
766 766 if kwargs_param is not None:
767 767 # Process our '**kwargs'-like parameter
768 768 arguments[kwargs_param.name] = kwargs
769 769 else:
770 770 raise TypeError('too many keyword arguments')
771 771
772 772 return self._bound_arguments_cls(self, arguments)
773 773
774 774 def bind(self, *args, **kwargs):
775 775 '''Get a :class:`BoundArguments` object, that maps the passed `args`
776 776 and `kwargs` to the function's signature. Raises :exc:`TypeError`
777 777 if the passed arguments can not be bound.
778 778 '''
779 779 return self._bind(args, kwargs)
780 780
781 781 def bind_partial(self, *args, **kwargs):
782 782 '''Get a :class:`BoundArguments` object, that partially maps the
783 783 passed `args` and `kwargs` to the function's signature.
784 784 Raises :exc:`TypeError` if the passed arguments can not be bound.
785 785 '''
786 786 return self._bind(args, kwargs, partial=True)
787 787
788 788 def __str__(self):
789 789 result = []
790 790 render_kw_only_separator = True
791 791 for idx, param in enumerate(self.parameters.values()):
792 792 formatted = str(param)
793 793
794 794 kind = param.kind
795 795 if kind == _VAR_POSITIONAL:
796 796 # OK, we have an '*args'-like parameter, so we won't need
797 797 # a '*' to separate keyword-only arguments
798 798 render_kw_only_separator = False
799 799 elif kind == _KEYWORD_ONLY and render_kw_only_separator:
800 800 # We have a keyword-only parameter to render and we haven't
801 801 # rendered an '*args'-like parameter before, so add a '*'
802 802 # separator to the parameters list ("foo(arg1, *, arg2)" case)
803 803 result.append('*')
804 804 # This condition should be only triggered once, so
805 805 # reset the flag
806 806 render_kw_only_separator = False
807 807
808 808 result.append(formatted)
809 809
810 810 rendered = '({0})'.format(', '.join(result))
811 811
812 812 if self.return_annotation is not _empty:
813 813 anno = formatannotation(self.return_annotation)
814 814 rendered += ' -> {0}'.format(anno)
815 815
816 816 return rendered
817 817
818 ## Fake unique value as KWargs, in some places.
819 # do not put docstrings here or they will appear
820 # on created fake values.
821 class Sentinel(object):
822
823 def __init__(self, name, module, docstring=None):
824 self.name = name
825 self.module = module
826 if docstring:
827 self.__doc__ = docstring
828
829
830 def __repr__(self):
831 return str(self.module)+'.'+self.name
832
@@ -1,167 +1,167 b''
1 1 """The IPython notebook format
2 2
3 3 Use this module to read or write notebook files as particular nbformat versions.
4 4 """
5 5
6 6 # Copyright (c) IPython Development Team.
7 7 # Distributed under the terms of the Modified BSD License.
8 8 import io
9 9 from IPython.utils import py3compat
10 10
11 11 from IPython.utils.log import get_logger
12 12
13 13 from . import v1
14 14 from . import v2
15 15 from . import v3
16 16 from . import v4
17 from IPython.utils.signatures import Sentinel
17 from .sentinel import Sentinel
18 18
19 19 __all__ = ['versions', 'validate', 'ValidationError', 'convert', 'from_dict',
20 20 'NotebookNode', 'current_nbformat', 'current_nbformat_minor',
21 21 'NBFormatError', 'NO_CONVERT', 'reads', 'read', 'writes', 'write']
22 22
23 23 versions = {
24 24 1: v1,
25 25 2: v2,
26 26 3: v3,
27 27 4: v4,
28 28 }
29 29
30 30 from .validator import validate, ValidationError
31 31 from .converter import convert
32 32 from . import reader
33 33 from .notebooknode import from_dict, NotebookNode
34 34
35 35 from .v4 import (
36 36 nbformat as current_nbformat,
37 37 nbformat_minor as current_nbformat_minor,
38 38 )
39 39
40 40 class NBFormatError(ValueError):
41 41 pass
42 42
43 43 # no-conversion singleton
44 44 NO_CONVERT = Sentinel('NO_CONVERT', __name__,
45 45 """Value to prevent nbformat to convert notebooks to most recent version.
46 46 """)
47 47
48 48
49 49 def reads(s, as_version, **kwargs):
50 50 """Read a notebook from a string and return the NotebookNode object as the given version.
51 51
52 52 The string can contain a notebook of any version.
53 53 The notebook will be returned `as_version`, converting, if necessary.
54 54
55 55 Notebook format errors will be logged.
56 56
57 57 Parameters
58 58 ----------
59 59 s : unicode
60 60 The raw unicode string to read the notebook from.
61 61 as_version : int
62 62 The version of the notebook format to return.
63 63 The notebook will be converted, if necessary.
64 64 Pass nbformat.NO_CONVERT to prevent conversion.
65 65
66 66 Returns
67 67 -------
68 68 nb : NotebookNode
69 69 The notebook that was read.
70 70 """
71 71 nb = reader.reads(s, **kwargs)
72 72 if as_version is not NO_CONVERT:
73 73 nb = convert(nb, as_version)
74 74 try:
75 75 validate(nb)
76 76 except ValidationError as e:
77 77 get_logger().error("Notebook JSON is invalid: %s", e)
78 78 return nb
79 79
80 80
81 81 def writes(nb, version=NO_CONVERT, **kwargs):
82 82 """Write a notebook to a string in a given format in the given nbformat version.
83 83
84 84 Any notebook format errors will be logged.
85 85
86 86 Parameters
87 87 ----------
88 88 nb : NotebookNode
89 89 The notebook to write.
90 90 version : int, optional
91 91 The nbformat version to write.
92 92 If unspecified, or specified as nbformat.NO_CONVERT,
93 93 the notebook's own version will be used and no conversion performed.
94 94
95 95 Returns
96 96 -------
97 97 s : unicode
98 98 The notebook as a JSON string.
99 99 """
100 100 if version is not NO_CONVERT:
101 101 nb = convert(nb, version)
102 102 else:
103 103 version, _ = reader.get_version(nb)
104 104 try:
105 105 validate(nb)
106 106 except ValidationError as e:
107 107 get_logger().error("Notebook JSON is invalid: %s", e)
108 108 return versions[version].writes_json(nb, **kwargs)
109 109
110 110
111 111 def read(fp, as_version, **kwargs):
112 112 """Read a notebook from a file as a NotebookNode of the given version.
113 113
114 114 The string can contain a notebook of any version.
115 115 The notebook will be returned `as_version`, converting, if necessary.
116 116
117 117 Notebook format errors will be logged.
118 118
119 119 Parameters
120 120 ----------
121 121 fp : file or str
122 122 Any file-like object with a read method, or a path to a file.
123 123 as_version: int
124 124 The version of the notebook format to return.
125 125 The notebook will be converted, if necessary.
126 126 Pass nbformat.NO_CONVERT to prevent conversion.
127 127
128 128 Returns
129 129 -------
130 130 nb : NotebookNode
131 131 The notebook that was read.
132 132 """
133 133 if isinstance(fp, py3compat.string_types):
134 134 with io.open(fp, encoding='utf-8') as f:
135 135 return read(f, as_version, **kwargs)
136 136
137 137 return reads(fp.read(), as_version, **kwargs)
138 138
139 139
140 140 def write(nb, fp, version=NO_CONVERT, **kwargs):
141 141 """Write a notebook to a file in a given nbformat version.
142 142
143 143 The file-like object must accept unicode input.
144 144
145 145 Parameters
146 146 ----------
147 147 nb : NotebookNode
148 148 The notebook to write.
149 149 fp : file or str
150 150 Any file-like object with a write method that accepts unicode, or
151 151 a path to write a file.
152 152 version : int, optional
153 153 The nbformat version to write.
154 154 If nb is not this version, it will be converted.
155 155 If unspecified, or specified as nbformat.NO_CONVERT,
156 156 the notebook's own version will be used and no conversion performed.
157 157 """
158 158 if isinstance(fp, py3compat.string_types):
159 159 with io.open(fp, 'w', encoding='utf-8') as f:
160 160 return write(nb, f, version=version, **kwargs)
161 161
162 162 s = writes(nb, version, **kwargs)
163 163 if isinstance(s, bytes):
164 164 s = s.decode('utf8')
165 165 fp.write(s)
166 166 if not s.endswith(u'\n'):
167 167 fp.write(u'\n')
@@ -1,1878 +1,1878 b''
1 1 # encoding: utf-8
2 2 """
3 3 A lightweight Traits like module.
4 4
5 5 This is designed to provide a lightweight, simple, pure Python version of
6 6 many of the capabilities of enthought.traits. This includes:
7 7
8 8 * Validation
9 9 * Type specification with defaults
10 10 * Static and dynamic notification
11 11 * Basic predefined types
12 12 * An API that is similar to enthought.traits
13 13
14 14 We don't support:
15 15
16 16 * Delegation
17 17 * Automatic GUI generation
18 18 * A full set of trait types. Most importantly, we don't provide container
19 19 traits (list, dict, tuple) that can trigger notifications if their
20 20 contents change.
21 21 * API compatibility with enthought.traits
22 22
23 23 There are also some important difference in our design:
24 24
25 25 * enthought.traits does not validate default values. We do.
26 26
27 27 We choose to create this module because we need these capabilities, but
28 28 we need them to be pure Python so they work in all Python implementations,
29 29 including Jython and IronPython.
30 30
31 31 Inheritance diagram:
32 32
33 33 .. inheritance-diagram:: IPython.utils.traitlets
34 34 :parts: 3
35 35 """
36 36
37 37 # Copyright (c) IPython Development Team.
38 38 # Distributed under the terms of the Modified BSD License.
39 39 #
40 40 # Adapted from enthought.traits, Copyright (c) Enthought, Inc.,
41 41 # also under the terms of the Modified BSD License.
42 42
43 43 import contextlib
44 44 import inspect
45 45 import re
46 46 import sys
47 47 import types
48 48 from types import FunctionType
49 49 try:
50 50 from types import ClassType, InstanceType
51 51 ClassTypes = (ClassType, type)
52 52 except:
53 53 ClassTypes = (type,)
54 54 from warnings import warn
55 55
56 56 from IPython.utils import py3compat
57 57 from IPython.utils import eventful
58 58 from IPython.utils.getargspec import getargspec
59 from IPython.utils.signatures import Sentinel
60 59 from IPython.utils.importstring import import_item
61 60 from IPython.utils.py3compat import iteritems, string_types
62 61 from IPython.testing.skipdoctest import skip_doctest
63 62
63 from .sentinel import Sentinel
64 64 SequenceTypes = (list, tuple, set, frozenset)
65 65
66 66 #-----------------------------------------------------------------------------
67 67 # Basic classes
68 68 #-----------------------------------------------------------------------------
69 69
70 70
71 71 NoDefaultSpecified = Sentinel('NoDefaultSpecified', __name__,
72 72 '''
73 73 Used in Traitlets to specify that no defaults are set in kwargs
74 74 '''
75 75 )
76 76
77 77
78 78 class Undefined ( object ): pass
79 79 Undefined = Undefined()
80 80
81 81 class TraitError(Exception):
82 82 pass
83 83
84 84 #-----------------------------------------------------------------------------
85 85 # Utilities
86 86 #-----------------------------------------------------------------------------
87 87
88 88
89 89 def class_of ( object ):
90 90 """ Returns a string containing the class name of an object with the
91 91 correct indefinite article ('a' or 'an') preceding it (e.g., 'an Image',
92 92 'a PlotValue').
93 93 """
94 94 if isinstance( object, py3compat.string_types ):
95 95 return add_article( object )
96 96
97 97 return add_article( object.__class__.__name__ )
98 98
99 99
100 100 def add_article ( name ):
101 101 """ Returns a string containing the correct indefinite article ('a' or 'an')
102 102 prefixed to the specified string.
103 103 """
104 104 if name[:1].lower() in 'aeiou':
105 105 return 'an ' + name
106 106
107 107 return 'a ' + name
108 108
109 109
110 110 def repr_type(obj):
111 111 """ Return a string representation of a value and its type for readable
112 112 error messages.
113 113 """
114 114 the_type = type(obj)
115 115 if (not py3compat.PY3) and the_type is InstanceType:
116 116 # Old-style class.
117 117 the_type = obj.__class__
118 118 msg = '%r %r' % (obj, the_type)
119 119 return msg
120 120
121 121
122 122 def is_trait(t):
123 123 """ Returns whether the given value is an instance or subclass of TraitType.
124 124 """
125 125 return (isinstance(t, TraitType) or
126 126 (isinstance(t, type) and issubclass(t, TraitType)))
127 127
128 128
129 129 def parse_notifier_name(name):
130 130 """Convert the name argument to a list of names.
131 131
132 132 Examples
133 133 --------
134 134
135 135 >>> parse_notifier_name('a')
136 136 ['a']
137 137 >>> parse_notifier_name(['a','b'])
138 138 ['a', 'b']
139 139 >>> parse_notifier_name(None)
140 140 ['anytrait']
141 141 """
142 142 if isinstance(name, string_types):
143 143 return [name]
144 144 elif name is None:
145 145 return ['anytrait']
146 146 elif isinstance(name, (list, tuple)):
147 147 for n in name:
148 148 assert isinstance(n, string_types), "names must be strings"
149 149 return name
150 150
151 151
152 152 class _SimpleTest:
153 153 def __init__ ( self, value ): self.value = value
154 154 def __call__ ( self, test ):
155 155 return test == self.value
156 156 def __repr__(self):
157 157 return "<SimpleTest(%r)" % self.value
158 158 def __str__(self):
159 159 return self.__repr__()
160 160
161 161
162 162 def getmembers(object, predicate=None):
163 163 """A safe version of inspect.getmembers that handles missing attributes.
164 164
165 165 This is useful when there are descriptor based attributes that for
166 166 some reason raise AttributeError even though they exist. This happens
167 167 in zope.inteface with the __provides__ attribute.
168 168 """
169 169 results = []
170 170 for key in dir(object):
171 171 try:
172 172 value = getattr(object, key)
173 173 except AttributeError:
174 174 pass
175 175 else:
176 176 if not predicate or predicate(value):
177 177 results.append((key, value))
178 178 results.sort()
179 179 return results
180 180
181 181 def _validate_link(*tuples):
182 182 """Validate arguments for traitlet link functions"""
183 183 for t in tuples:
184 184 if not len(t) == 2:
185 185 raise TypeError("Each linked traitlet must be specified as (HasTraits, 'trait_name'), not %r" % t)
186 186 obj, trait_name = t
187 187 if not isinstance(obj, HasTraits):
188 188 raise TypeError("Each object must be HasTraits, not %r" % type(obj))
189 189 if not trait_name in obj.traits():
190 190 raise TypeError("%r has no trait %r" % (obj, trait_name))
191 191
192 192 @skip_doctest
193 193 class link(object):
194 194 """Link traits from different objects together so they remain in sync.
195 195
196 196 Parameters
197 197 ----------
198 198 *args : pairs of objects/attributes
199 199
200 200 Examples
201 201 --------
202 202
203 203 >>> c = link((obj1, 'value'), (obj2, 'value'), (obj3, 'value'))
204 204 >>> obj1.value = 5 # updates other objects as well
205 205 """
206 206 updating = False
207 207 def __init__(self, *args):
208 208 if len(args) < 2:
209 209 raise TypeError('At least two traitlets must be provided.')
210 210 _validate_link(*args)
211 211
212 212 self.objects = {}
213 213
214 214 initial = getattr(args[0][0], args[0][1])
215 215 for obj, attr in args:
216 216 setattr(obj, attr, initial)
217 217
218 218 callback = self._make_closure(obj, attr)
219 219 obj.on_trait_change(callback, attr)
220 220 self.objects[(obj, attr)] = callback
221 221
222 222 @contextlib.contextmanager
223 223 def _busy_updating(self):
224 224 self.updating = True
225 225 try:
226 226 yield
227 227 finally:
228 228 self.updating = False
229 229
230 230 def _make_closure(self, sending_obj, sending_attr):
231 231 def update(name, old, new):
232 232 self._update(sending_obj, sending_attr, new)
233 233 return update
234 234
235 235 def _update(self, sending_obj, sending_attr, new):
236 236 if self.updating:
237 237 return
238 238 with self._busy_updating():
239 239 for obj, attr in self.objects.keys():
240 240 setattr(obj, attr, new)
241 241
242 242 def unlink(self):
243 243 for key, callback in self.objects.items():
244 244 (obj, attr) = key
245 245 obj.on_trait_change(callback, attr, remove=True)
246 246
247 247 @skip_doctest
248 248 class directional_link(object):
249 249 """Link the trait of a source object with traits of target objects.
250 250
251 251 Parameters
252 252 ----------
253 253 source : pair of object, name
254 254 targets : pairs of objects/attributes
255 255
256 256 Examples
257 257 --------
258 258
259 259 >>> c = directional_link((src, 'value'), (tgt1, 'value'), (tgt2, 'value'))
260 260 >>> src.value = 5 # updates target objects
261 261 >>> tgt1.value = 6 # does not update other objects
262 262 """
263 263 updating = False
264 264
265 265 def __init__(self, source, *targets):
266 266 if len(targets) < 1:
267 267 raise TypeError('At least two traitlets must be provided.')
268 268 _validate_link(source, *targets)
269 269 self.source = source
270 270 self.targets = targets
271 271
272 272 # Update current value
273 273 src_attr_value = getattr(source[0], source[1])
274 274 for obj, attr in targets:
275 275 setattr(obj, attr, src_attr_value)
276 276
277 277 # Wire
278 278 self.source[0].on_trait_change(self._update, self.source[1])
279 279
280 280 @contextlib.contextmanager
281 281 def _busy_updating(self):
282 282 self.updating = True
283 283 try:
284 284 yield
285 285 finally:
286 286 self.updating = False
287 287
288 288 def _update(self, name, old, new):
289 289 if self.updating:
290 290 return
291 291 with self._busy_updating():
292 292 for obj, attr in self.targets:
293 293 setattr(obj, attr, new)
294 294
295 295 def unlink(self):
296 296 self.source[0].on_trait_change(self._update, self.source[1], remove=True)
297 297 self.source = None
298 298 self.targets = []
299 299
300 300 dlink = directional_link
301 301
302 302
303 303 #-----------------------------------------------------------------------------
304 304 # Base TraitType for all traits
305 305 #-----------------------------------------------------------------------------
306 306
307 307
308 308 class TraitType(object):
309 309 """A base class for all trait descriptors.
310 310
311 311 Notes
312 312 -----
313 313 Our implementation of traits is based on Python's descriptor
314 314 prototol. This class is the base class for all such descriptors. The
315 315 only magic we use is a custom metaclass for the main :class:`HasTraits`
316 316 class that does the following:
317 317
318 318 1. Sets the :attr:`name` attribute of every :class:`TraitType`
319 319 instance in the class dict to the name of the attribute.
320 320 2. Sets the :attr:`this_class` attribute of every :class:`TraitType`
321 321 instance in the class dict to the *class* that declared the trait.
322 322 This is used by the :class:`This` trait to allow subclasses to
323 323 accept superclasses for :class:`This` values.
324 324 """
325 325
326 326 metadata = {}
327 327 default_value = Undefined
328 328 allow_none = False
329 329 info_text = 'any value'
330 330
331 331 def __init__(self, default_value=NoDefaultSpecified, allow_none=None, **metadata):
332 332 """Create a TraitType.
333 333 """
334 334 if default_value is not NoDefaultSpecified:
335 335 self.default_value = default_value
336 336 if allow_none is not None:
337 337 self.allow_none = allow_none
338 338
339 339 if 'default' in metadata:
340 340 # Warn the user that they probably meant default_value.
341 341 warn(
342 342 "Parameter 'default' passed to TraitType. "
343 343 "Did you mean 'default_value'?"
344 344 )
345 345
346 346 if len(metadata) > 0:
347 347 if len(self.metadata) > 0:
348 348 self._metadata = self.metadata.copy()
349 349 self._metadata.update(metadata)
350 350 else:
351 351 self._metadata = metadata
352 352 else:
353 353 self._metadata = self.metadata
354 354
355 355 self.init()
356 356
357 357 def init(self):
358 358 pass
359 359
360 360 def get_default_value(self):
361 361 """Create a new instance of the default value."""
362 362 return self.default_value
363 363
364 364 def instance_init(self):
365 365 """Part of the initialization which may depends on the underlying
366 366 HasTraits instance.
367 367
368 368 It is typically overloaded for specific trait types.
369 369
370 370 This method is called by :meth:`HasTraits.__new__` and in the
371 371 :meth:`TraitType.instance_init` method of trait types holding
372 372 other trait types.
373 373 """
374 374 pass
375 375
376 376 def init_default_value(self, obj):
377 377 """Instantiate the default value for the trait type.
378 378
379 379 This method is called by :meth:`TraitType.set_default_value` in the
380 380 case a default value is provided at construction time or later when
381 381 accessing the trait value for the first time in
382 382 :meth:`HasTraits.__get__`.
383 383 """
384 384 value = self.get_default_value()
385 385 value = self._validate(obj, value)
386 386 obj._trait_values[self.name] = value
387 387 return value
388 388
389 389 def set_default_value(self, obj):
390 390 """Set the default value on a per instance basis.
391 391
392 392 This method is called by :meth:`HasTraits.__new__` to instantiate and
393 393 validate the default value. The creation and validation of
394 394 default values must be delayed until the parent :class:`HasTraits`
395 395 class has been instantiated.
396 396 Parameters
397 397 ----------
398 398 obj : :class:`HasTraits` instance
399 399 The parent :class:`HasTraits` instance that has just been
400 400 created.
401 401 """
402 402 # Check for a deferred initializer defined in the same class as the
403 403 # trait declaration or above.
404 404 mro = type(obj).mro()
405 405 meth_name = '_%s_default' % self.name
406 406 for cls in mro[:mro.index(self.this_class)+1]:
407 407 if meth_name in cls.__dict__:
408 408 break
409 409 else:
410 410 # We didn't find one. Do static initialization.
411 411 self.init_default_value(obj)
412 412 return
413 413 # Complete the dynamic initialization.
414 414 obj._trait_dyn_inits[self.name] = meth_name
415 415
416 416 def __get__(self, obj, cls=None):
417 417 """Get the value of the trait by self.name for the instance.
418 418
419 419 Default values are instantiated when :meth:`HasTraits.__new__`
420 420 is called. Thus by the time this method gets called either the
421 421 default value or a user defined value (they called :meth:`__set__`)
422 422 is in the :class:`HasTraits` instance.
423 423 """
424 424 if obj is None:
425 425 return self
426 426 else:
427 427 try:
428 428 value = obj._trait_values[self.name]
429 429 except KeyError:
430 430 # Check for a dynamic initializer.
431 431 if self.name in obj._trait_dyn_inits:
432 432 method = getattr(obj, obj._trait_dyn_inits[self.name])
433 433 value = method()
434 434 # FIXME: Do we really validate here?
435 435 value = self._validate(obj, value)
436 436 obj._trait_values[self.name] = value
437 437 return value
438 438 else:
439 439 return self.init_default_value(obj)
440 440 except Exception:
441 441 # HasTraits should call set_default_value to populate
442 442 # this. So this should never be reached.
443 443 raise TraitError('Unexpected error in TraitType: '
444 444 'default value not set properly')
445 445 else:
446 446 return value
447 447
448 448 def __set__(self, obj, value):
449 449 new_value = self._validate(obj, value)
450 450 try:
451 451 old_value = obj._trait_values[self.name]
452 452 except KeyError:
453 453 old_value = Undefined
454 454
455 455 obj._trait_values[self.name] = new_value
456 456 try:
457 457 silent = bool(old_value == new_value)
458 458 except:
459 459 # if there is an error in comparing, default to notify
460 460 silent = False
461 461 if silent is not True:
462 462 # we explicitly compare silent to True just in case the equality
463 463 # comparison above returns something other than True/False
464 464 obj._notify_trait(self.name, old_value, new_value)
465 465
466 466 def _validate(self, obj, value):
467 467 if value is None and self.allow_none:
468 468 return value
469 469 if hasattr(self, 'validate'):
470 470 value = self.validate(obj, value)
471 471 if obj._cross_validation_lock is False:
472 472 value = self._cross_validate(obj, value)
473 473 return value
474 474
475 475 def _cross_validate(self, obj, value):
476 476 if hasattr(obj, '_%s_validate' % self.name):
477 477 cross_validate = getattr(obj, '_%s_validate' % self.name)
478 478 value = cross_validate(value, self)
479 479 return value
480 480
481 481 def __or__(self, other):
482 482 if isinstance(other, Union):
483 483 return Union([self] + other.trait_types)
484 484 else:
485 485 return Union([self, other])
486 486
487 487 def info(self):
488 488 return self.info_text
489 489
490 490 def error(self, obj, value):
491 491 if obj is not None:
492 492 e = "The '%s' trait of %s instance must be %s, but a value of %s was specified." \
493 493 % (self.name, class_of(obj),
494 494 self.info(), repr_type(value))
495 495 else:
496 496 e = "The '%s' trait must be %s, but a value of %r was specified." \
497 497 % (self.name, self.info(), repr_type(value))
498 498 raise TraitError(e)
499 499
500 500 def get_metadata(self, key, default=None):
501 501 return getattr(self, '_metadata', {}).get(key, default)
502 502
503 503 def set_metadata(self, key, value):
504 504 getattr(self, '_metadata', {})[key] = value
505 505
506 506
507 507 #-----------------------------------------------------------------------------
508 508 # The HasTraits implementation
509 509 #-----------------------------------------------------------------------------
510 510
511 511
512 512 class MetaHasTraits(type):
513 513 """A metaclass for HasTraits.
514 514
515 515 This metaclass makes sure that any TraitType class attributes are
516 516 instantiated and sets their name attribute.
517 517 """
518 518
519 519 def __new__(mcls, name, bases, classdict):
520 520 """Create the HasTraits class.
521 521
522 522 This instantiates all TraitTypes in the class dict and sets their
523 523 :attr:`name` attribute.
524 524 """
525 525 # print "MetaHasTraitlets (mcls, name): ", mcls, name
526 526 # print "MetaHasTraitlets (bases): ", bases
527 527 # print "MetaHasTraitlets (classdict): ", classdict
528 528 for k,v in iteritems(classdict):
529 529 if isinstance(v, TraitType):
530 530 v.name = k
531 531 elif inspect.isclass(v):
532 532 if issubclass(v, TraitType):
533 533 vinst = v()
534 534 vinst.name = k
535 535 classdict[k] = vinst
536 536 return super(MetaHasTraits, mcls).__new__(mcls, name, bases, classdict)
537 537
538 538 def __init__(cls, name, bases, classdict):
539 539 """Finish initializing the HasTraits class.
540 540
541 541 This sets the :attr:`this_class` attribute of each TraitType in the
542 542 class dict to the newly created class ``cls``.
543 543 """
544 544 for k, v in iteritems(classdict):
545 545 if isinstance(v, TraitType):
546 546 v.this_class = cls
547 547 super(MetaHasTraits, cls).__init__(name, bases, classdict)
548 548
549 549
550 550 class HasTraits(py3compat.with_metaclass(MetaHasTraits, object)):
551 551
552 552 def __new__(cls, *args, **kw):
553 553 # This is needed because object.__new__ only accepts
554 554 # the cls argument.
555 555 new_meth = super(HasTraits, cls).__new__
556 556 if new_meth is object.__new__:
557 557 inst = new_meth(cls)
558 558 else:
559 559 inst = new_meth(cls, **kw)
560 560 inst._trait_values = {}
561 561 inst._trait_notifiers = {}
562 562 inst._trait_dyn_inits = {}
563 563 inst._cross_validation_lock = True
564 564 # Here we tell all the TraitType instances to set their default
565 565 # values on the instance.
566 566 for key in dir(cls):
567 567 # Some descriptors raise AttributeError like zope.interface's
568 568 # __provides__ attributes even though they exist. This causes
569 569 # AttributeErrors even though they are listed in dir(cls).
570 570 try:
571 571 value = getattr(cls, key)
572 572 except AttributeError:
573 573 pass
574 574 else:
575 575 if isinstance(value, TraitType):
576 576 value.instance_init()
577 577 if key not in kw:
578 578 value.set_default_value(inst)
579 579 inst._cross_validation_lock = False
580 580 return inst
581 581
582 582 def __init__(self, *args, **kw):
583 583 # Allow trait values to be set using keyword arguments.
584 584 # We need to use setattr for this to trigger validation and
585 585 # notifications.
586 586 with self.hold_trait_notifications():
587 587 for key, value in iteritems(kw):
588 588 setattr(self, key, value)
589 589
590 590 @contextlib.contextmanager
591 591 def hold_trait_notifications(self):
592 592 """Context manager for bundling trait change notifications and cross
593 593 validation.
594 594
595 595 Use this when doing multiple trait assignments (init, config), to avoid
596 596 race conditions in trait notifiers requesting other trait values.
597 597 All trait notifications will fire after all values have been assigned.
598 598 """
599 599 if self._cross_validation_lock is True:
600 600 yield
601 601 return
602 602 else:
603 603 self._cross_validation_lock = True
604 604 cache = {}
605 605 notifications = {}
606 606 _notify_trait = self._notify_trait
607 607
608 608 def cache_values(*a):
609 609 cache[a[0]] = a
610 610
611 611 def hold_notifications(*a):
612 612 notifications[a[0]] = a
613 613
614 614 self._notify_trait = cache_values
615 615
616 616 try:
617 617 yield
618 618 finally:
619 619 try:
620 620 self._notify_trait = hold_notifications
621 621 for name in cache:
622 622 if hasattr(self, '_%s_validate' % name):
623 623 cross_validate = getattr(self, '_%s_validate' % name)
624 624 setattr(self, name, cross_validate(getattr(self, name), self))
625 625 except TraitError as e:
626 626 self._notify_trait = lambda *x: None
627 627 for name in cache:
628 628 if cache[name][1] is not Undefined:
629 629 setattr(self, name, cache[name][1])
630 630 else:
631 631 delattr(self, name)
632 632 cache = {}
633 633 notifications = {}
634 634 raise e
635 635 finally:
636 636 self._notify_trait = _notify_trait
637 637 self._cross_validation_lock = False
638 638 if isinstance(_notify_trait, types.MethodType):
639 639 # FIXME: remove when support is bumped to 3.4.
640 640 # when original method is restored,
641 641 # remove the redundant value from __dict__
642 642 # (only used to preserve pickleability on Python < 3.4)
643 643 self.__dict__.pop('_notify_trait', None)
644 644 # trigger delayed notifications
645 645 for v in dict(cache, **notifications).values():
646 646 self._notify_trait(*v)
647 647
648 648 def _notify_trait(self, name, old_value, new_value):
649 649
650 650 # First dynamic ones
651 651 callables = []
652 652 callables.extend(self._trait_notifiers.get(name,[]))
653 653 callables.extend(self._trait_notifiers.get('anytrait',[]))
654 654
655 655 # Now static ones
656 656 try:
657 657 cb = getattr(self, '_%s_changed' % name)
658 658 except:
659 659 pass
660 660 else:
661 661 callables.append(cb)
662 662
663 663 # Call them all now
664 664 for c in callables:
665 665 # Traits catches and logs errors here. I allow them to raise
666 666 if callable(c):
667 667 argspec = getargspec(c)
668 668
669 669 nargs = len(argspec[0])
670 670 # Bound methods have an additional 'self' argument
671 671 # I don't know how to treat unbound methods, but they
672 672 # can't really be used for callbacks.
673 673 if isinstance(c, types.MethodType):
674 674 offset = -1
675 675 else:
676 676 offset = 0
677 677 if nargs + offset == 0:
678 678 c()
679 679 elif nargs + offset == 1:
680 680 c(name)
681 681 elif nargs + offset == 2:
682 682 c(name, new_value)
683 683 elif nargs + offset == 3:
684 684 c(name, old_value, new_value)
685 685 else:
686 686 raise TraitError('a trait changed callback '
687 687 'must have 0-3 arguments.')
688 688 else:
689 689 raise TraitError('a trait changed callback '
690 690 'must be callable.')
691 691
692 692
693 693 def _add_notifiers(self, handler, name):
694 694 if name not in self._trait_notifiers:
695 695 nlist = []
696 696 self._trait_notifiers[name] = nlist
697 697 else:
698 698 nlist = self._trait_notifiers[name]
699 699 if handler not in nlist:
700 700 nlist.append(handler)
701 701
702 702 def _remove_notifiers(self, handler, name):
703 703 if name in self._trait_notifiers:
704 704 nlist = self._trait_notifiers[name]
705 705 try:
706 706 index = nlist.index(handler)
707 707 except ValueError:
708 708 pass
709 709 else:
710 710 del nlist[index]
711 711
712 712 def on_trait_change(self, handler, name=None, remove=False):
713 713 """Setup a handler to be called when a trait changes.
714 714
715 715 This is used to setup dynamic notifications of trait changes.
716 716
717 717 Static handlers can be created by creating methods on a HasTraits
718 718 subclass with the naming convention '_[traitname]_changed'. Thus,
719 719 to create static handler for the trait 'a', create the method
720 720 _a_changed(self, name, old, new) (fewer arguments can be used, see
721 721 below).
722 722
723 723 Parameters
724 724 ----------
725 725 handler : callable
726 726 A callable that is called when a trait changes. Its
727 727 signature can be handler(), handler(name), handler(name, new)
728 728 or handler(name, old, new).
729 729 name : list, str, None
730 730 If None, the handler will apply to all traits. If a list
731 731 of str, handler will apply to all names in the list. If a
732 732 str, the handler will apply just to that name.
733 733 remove : bool
734 734 If False (the default), then install the handler. If True
735 735 then unintall it.
736 736 """
737 737 if remove:
738 738 names = parse_notifier_name(name)
739 739 for n in names:
740 740 self._remove_notifiers(handler, n)
741 741 else:
742 742 names = parse_notifier_name(name)
743 743 for n in names:
744 744 self._add_notifiers(handler, n)
745 745
746 746 @classmethod
747 747 def class_trait_names(cls, **metadata):
748 748 """Get a list of all the names of this class' traits.
749 749
750 750 This method is just like the :meth:`trait_names` method,
751 751 but is unbound.
752 752 """
753 753 return cls.class_traits(**metadata).keys()
754 754
755 755 @classmethod
756 756 def class_traits(cls, **metadata):
757 757 """Get a `dict` of all the traits of this class. The dictionary
758 758 is keyed on the name and the values are the TraitType objects.
759 759
760 760 This method is just like the :meth:`traits` method, but is unbound.
761 761
762 762 The TraitTypes returned don't know anything about the values
763 763 that the various HasTrait's instances are holding.
764 764
765 765 The metadata kwargs allow functions to be passed in which
766 766 filter traits based on metadata values. The functions should
767 767 take a single value as an argument and return a boolean. If
768 768 any function returns False, then the trait is not included in
769 769 the output. This does not allow for any simple way of
770 770 testing that a metadata name exists and has any
771 771 value because get_metadata returns None if a metadata key
772 772 doesn't exist.
773 773 """
774 774 traits = dict([memb for memb in getmembers(cls) if
775 775 isinstance(memb[1], TraitType)])
776 776
777 777 if len(metadata) == 0:
778 778 return traits
779 779
780 780 for meta_name, meta_eval in metadata.items():
781 781 if type(meta_eval) is not FunctionType:
782 782 metadata[meta_name] = _SimpleTest(meta_eval)
783 783
784 784 result = {}
785 785 for name, trait in traits.items():
786 786 for meta_name, meta_eval in metadata.items():
787 787 if not meta_eval(trait.get_metadata(meta_name)):
788 788 break
789 789 else:
790 790 result[name] = trait
791 791
792 792 return result
793 793
794 794 def trait_names(self, **metadata):
795 795 """Get a list of all the names of this class' traits."""
796 796 return self.traits(**metadata).keys()
797 797
798 798 def traits(self, **metadata):
799 799 """Get a `dict` of all the traits of this class. The dictionary
800 800 is keyed on the name and the values are the TraitType objects.
801 801
802 802 The TraitTypes returned don't know anything about the values
803 803 that the various HasTrait's instances are holding.
804 804
805 805 The metadata kwargs allow functions to be passed in which
806 806 filter traits based on metadata values. The functions should
807 807 take a single value as an argument and return a boolean. If
808 808 any function returns False, then the trait is not included in
809 809 the output. This does not allow for any simple way of
810 810 testing that a metadata name exists and has any
811 811 value because get_metadata returns None if a metadata key
812 812 doesn't exist.
813 813 """
814 814 traits = dict([memb for memb in getmembers(self.__class__) if
815 815 isinstance(memb[1], TraitType)])
816 816
817 817 if len(metadata) == 0:
818 818 return traits
819 819
820 820 for meta_name, meta_eval in metadata.items():
821 821 if type(meta_eval) is not FunctionType:
822 822 metadata[meta_name] = _SimpleTest(meta_eval)
823 823
824 824 result = {}
825 825 for name, trait in traits.items():
826 826 for meta_name, meta_eval in metadata.items():
827 827 if not meta_eval(trait.get_metadata(meta_name)):
828 828 break
829 829 else:
830 830 result[name] = trait
831 831
832 832 return result
833 833
834 834 def trait_metadata(self, traitname, key, default=None):
835 835 """Get metadata values for trait by key."""
836 836 try:
837 837 trait = getattr(self.__class__, traitname)
838 838 except AttributeError:
839 839 raise TraitError("Class %s does not have a trait named %s" %
840 840 (self.__class__.__name__, traitname))
841 841 else:
842 842 return trait.get_metadata(key, default)
843 843
844 844 def add_trait(self, traitname, trait):
845 845 """Dynamically add a trait attribute to the HasTraits instance."""
846 846 self.__class__ = type(self.__class__.__name__, (self.__class__,),
847 847 {traitname: trait})
848 848 trait.set_default_value(self)
849 849
850 850 #-----------------------------------------------------------------------------
851 851 # Actual TraitTypes implementations/subclasses
852 852 #-----------------------------------------------------------------------------
853 853
854 854 #-----------------------------------------------------------------------------
855 855 # TraitTypes subclasses for handling classes and instances of classes
856 856 #-----------------------------------------------------------------------------
857 857
858 858
859 859 class ClassBasedTraitType(TraitType):
860 860 """
861 861 A trait with error reporting and string -> type resolution for Type,
862 862 Instance and This.
863 863 """
864 864
865 865 def _resolve_string(self, string):
866 866 """
867 867 Resolve a string supplied for a type into an actual object.
868 868 """
869 869 return import_item(string)
870 870
871 871 def error(self, obj, value):
872 872 kind = type(value)
873 873 if (not py3compat.PY3) and kind is InstanceType:
874 874 msg = 'class %s' % value.__class__.__name__
875 875 else:
876 876 msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
877 877
878 878 if obj is not None:
879 879 e = "The '%s' trait of %s instance must be %s, but a value of %s was specified." \
880 880 % (self.name, class_of(obj),
881 881 self.info(), msg)
882 882 else:
883 883 e = "The '%s' trait must be %s, but a value of %r was specified." \
884 884 % (self.name, self.info(), msg)
885 885
886 886 raise TraitError(e)
887 887
888 888
889 889 class Type(ClassBasedTraitType):
890 890 """A trait whose value must be a subclass of a specified class."""
891 891
892 892 def __init__ (self, default_value=None, klass=None, allow_none=False,
893 893 **metadata):
894 894 """Construct a Type trait
895 895
896 896 A Type trait specifies that its values must be subclasses of
897 897 a particular class.
898 898
899 899 If only ``default_value`` is given, it is used for the ``klass`` as
900 900 well.
901 901
902 902 Parameters
903 903 ----------
904 904 default_value : class, str or None
905 905 The default value must be a subclass of klass. If an str,
906 906 the str must be a fully specified class name, like 'foo.bar.Bah'.
907 907 The string is resolved into real class, when the parent
908 908 :class:`HasTraits` class is instantiated.
909 909 klass : class, str, None
910 910 Values of this trait must be a subclass of klass. The klass
911 911 may be specified in a string like: 'foo.bar.MyClass'.
912 912 The string is resolved into real class, when the parent
913 913 :class:`HasTraits` class is instantiated.
914 914 allow_none : bool [ default True ]
915 915 Indicates whether None is allowed as an assignable value. Even if
916 916 ``False``, the default value may be ``None``.
917 917 """
918 918 if default_value is None:
919 919 if klass is None:
920 920 klass = object
921 921 elif klass is None:
922 922 klass = default_value
923 923
924 924 if not (inspect.isclass(klass) or isinstance(klass, py3compat.string_types)):
925 925 raise TraitError("A Type trait must specify a class.")
926 926
927 927 self.klass = klass
928 928
929 929 super(Type, self).__init__(default_value, allow_none=allow_none, **metadata)
930 930
931 931 def validate(self, obj, value):
932 932 """Validates that the value is a valid object instance."""
933 933 if isinstance(value, py3compat.string_types):
934 934 try:
935 935 value = self._resolve_string(value)
936 936 except ImportError:
937 937 raise TraitError("The '%s' trait of %s instance must be a type, but "
938 938 "%r could not be imported" % (self.name, obj, value))
939 939 try:
940 940 if issubclass(value, self.klass):
941 941 return value
942 942 except:
943 943 pass
944 944
945 945 self.error(obj, value)
946 946
947 947 def info(self):
948 948 """ Returns a description of the trait."""
949 949 if isinstance(self.klass, py3compat.string_types):
950 950 klass = self.klass
951 951 else:
952 952 klass = self.klass.__name__
953 953 result = 'a subclass of ' + klass
954 954 if self.allow_none:
955 955 return result + ' or None'
956 956 return result
957 957
958 958 def instance_init(self):
959 959 self._resolve_classes()
960 960 super(Type, self).instance_init()
961 961
962 962 def _resolve_classes(self):
963 963 if isinstance(self.klass, py3compat.string_types):
964 964 self.klass = self._resolve_string(self.klass)
965 965 if isinstance(self.default_value, py3compat.string_types):
966 966 self.default_value = self._resolve_string(self.default_value)
967 967
968 968 def get_default_value(self):
969 969 return self.default_value
970 970
971 971
972 972 class DefaultValueGenerator(object):
973 973 """A class for generating new default value instances."""
974 974
975 975 def __init__(self, *args, **kw):
976 976 self.args = args
977 977 self.kw = kw
978 978
979 979 def generate(self, klass):
980 980 return klass(*self.args, **self.kw)
981 981
982 982
983 983 class Instance(ClassBasedTraitType):
984 984 """A trait whose value must be an instance of a specified class.
985 985
986 986 The value can also be an instance of a subclass of the specified class.
987 987
988 988 Subclasses can declare default classes by overriding the klass attribute
989 989 """
990 990
991 991 klass = None
992 992
993 993 def __init__(self, klass=None, args=None, kw=None, allow_none=False,
994 994 **metadata ):
995 995 """Construct an Instance trait.
996 996
997 997 This trait allows values that are instances of a particular
998 998 class or its subclasses. Our implementation is quite different
999 999 from that of enthough.traits as we don't allow instances to be used
1000 1000 for klass and we handle the ``args`` and ``kw`` arguments differently.
1001 1001
1002 1002 Parameters
1003 1003 ----------
1004 1004 klass : class, str
1005 1005 The class that forms the basis for the trait. Class names
1006 1006 can also be specified as strings, like 'foo.bar.Bar'.
1007 1007 args : tuple
1008 1008 Positional arguments for generating the default value.
1009 1009 kw : dict
1010 1010 Keyword arguments for generating the default value.
1011 1011 allow_none : bool [default True]
1012 1012 Indicates whether None is allowed as a value.
1013 1013
1014 1014 Notes
1015 1015 -----
1016 1016 If both ``args`` and ``kw`` are None, then the default value is None.
1017 1017 If ``args`` is a tuple and ``kw`` is a dict, then the default is
1018 1018 created as ``klass(*args, **kw)``. If exactly one of ``args`` or ``kw`` is
1019 1019 None, the None is replaced by ``()`` or ``{}``, respectively.
1020 1020 """
1021 1021 if klass is None:
1022 1022 klass = self.klass
1023 1023
1024 1024 if (klass is not None) and (inspect.isclass(klass) or isinstance(klass, py3compat.string_types)):
1025 1025 self.klass = klass
1026 1026 else:
1027 1027 raise TraitError('The klass attribute must be a class'
1028 1028 ' not: %r' % klass)
1029 1029
1030 1030 # self.klass is a class, so handle default_value
1031 1031 if args is None and kw is None:
1032 1032 default_value = None
1033 1033 else:
1034 1034 if args is None:
1035 1035 # kw is not None
1036 1036 args = ()
1037 1037 elif kw is None:
1038 1038 # args is not None
1039 1039 kw = {}
1040 1040
1041 1041 if not isinstance(kw, dict):
1042 1042 raise TraitError("The 'kw' argument must be a dict or None.")
1043 1043 if not isinstance(args, tuple):
1044 1044 raise TraitError("The 'args' argument must be a tuple or None.")
1045 1045
1046 1046 default_value = DefaultValueGenerator(*args, **kw)
1047 1047
1048 1048 super(Instance, self).__init__(default_value, allow_none=allow_none, **metadata)
1049 1049
1050 1050 def validate(self, obj, value):
1051 1051 if isinstance(value, self.klass):
1052 1052 return value
1053 1053 else:
1054 1054 self.error(obj, value)
1055 1055
1056 1056 def info(self):
1057 1057 if isinstance(self.klass, py3compat.string_types):
1058 1058 klass = self.klass
1059 1059 else:
1060 1060 klass = self.klass.__name__
1061 1061 result = class_of(klass)
1062 1062 if self.allow_none:
1063 1063 return result + ' or None'
1064 1064
1065 1065 return result
1066 1066
1067 1067 def instance_init(self):
1068 1068 self._resolve_classes()
1069 1069 super(Instance, self).instance_init()
1070 1070
1071 1071 def _resolve_classes(self):
1072 1072 if isinstance(self.klass, py3compat.string_types):
1073 1073 self.klass = self._resolve_string(self.klass)
1074 1074
1075 1075 def get_default_value(self):
1076 1076 """Instantiate a default value instance.
1077 1077
1078 1078 This is called when the containing HasTraits classes'
1079 1079 :meth:`__new__` method is called to ensure that a unique instance
1080 1080 is created for each HasTraits instance.
1081 1081 """
1082 1082 dv = self.default_value
1083 1083 if isinstance(dv, DefaultValueGenerator):
1084 1084 return dv.generate(self.klass)
1085 1085 else:
1086 1086 return dv
1087 1087
1088 1088
1089 1089 class ForwardDeclaredMixin(object):
1090 1090 """
1091 1091 Mixin for forward-declared versions of Instance and Type.
1092 1092 """
1093 1093 def _resolve_string(self, string):
1094 1094 """
1095 1095 Find the specified class name by looking for it in the module in which
1096 1096 our this_class attribute was defined.
1097 1097 """
1098 1098 modname = self.this_class.__module__
1099 1099 return import_item('.'.join([modname, string]))
1100 1100
1101 1101
1102 1102 class ForwardDeclaredType(ForwardDeclaredMixin, Type):
1103 1103 """
1104 1104 Forward-declared version of Type.
1105 1105 """
1106 1106 pass
1107 1107
1108 1108
1109 1109 class ForwardDeclaredInstance(ForwardDeclaredMixin, Instance):
1110 1110 """
1111 1111 Forward-declared version of Instance.
1112 1112 """
1113 1113 pass
1114 1114
1115 1115
1116 1116 class This(ClassBasedTraitType):
1117 1117 """A trait for instances of the class containing this trait.
1118 1118
1119 1119 Because how how and when class bodies are executed, the ``This``
1120 1120 trait can only have a default value of None. This, and because we
1121 1121 always validate default values, ``allow_none`` is *always* true.
1122 1122 """
1123 1123
1124 1124 info_text = 'an instance of the same type as the receiver or None'
1125 1125
1126 1126 def __init__(self, **metadata):
1127 1127 super(This, self).__init__(None, **metadata)
1128 1128
1129 1129 def validate(self, obj, value):
1130 1130 # What if value is a superclass of obj.__class__? This is
1131 1131 # complicated if it was the superclass that defined the This
1132 1132 # trait.
1133 1133 if isinstance(value, self.this_class) or (value is None):
1134 1134 return value
1135 1135 else:
1136 1136 self.error(obj, value)
1137 1137
1138 1138
1139 1139 class Union(TraitType):
1140 1140 """A trait type representing a Union type."""
1141 1141
1142 1142 def __init__(self, trait_types, **metadata):
1143 1143 """Construct a Union trait.
1144 1144
1145 1145 This trait allows values that are allowed by at least one of the
1146 1146 specified trait types. A Union traitlet cannot have metadata on
1147 1147 its own, besides the metadata of the listed types.
1148 1148
1149 1149 Parameters
1150 1150 ----------
1151 1151 trait_types: sequence
1152 1152 The list of trait types of length at least 1.
1153 1153
1154 1154 Notes
1155 1155 -----
1156 1156 Union([Float(), Bool(), Int()]) attempts to validate the provided values
1157 1157 with the validation function of Float, then Bool, and finally Int.
1158 1158 """
1159 1159 self.trait_types = trait_types
1160 1160 self.info_text = " or ".join([tt.info_text for tt in self.trait_types])
1161 1161 self.default_value = self.trait_types[0].get_default_value()
1162 1162 super(Union, self).__init__(**metadata)
1163 1163
1164 1164 def instance_init(self):
1165 1165 for trait_type in self.trait_types:
1166 1166 trait_type.name = self.name
1167 1167 trait_type.this_class = self.this_class
1168 1168 trait_type.instance_init()
1169 1169 super(Union, self).instance_init()
1170 1170
1171 1171 def validate(self, obj, value):
1172 1172 for trait_type in self.trait_types:
1173 1173 try:
1174 1174 v = trait_type._validate(obj, value)
1175 1175 self._metadata = trait_type._metadata
1176 1176 return v
1177 1177 except TraitError:
1178 1178 continue
1179 1179 self.error(obj, value)
1180 1180
1181 1181 def __or__(self, other):
1182 1182 if isinstance(other, Union):
1183 1183 return Union(self.trait_types + other.trait_types)
1184 1184 else:
1185 1185 return Union(self.trait_types + [other])
1186 1186
1187 1187 #-----------------------------------------------------------------------------
1188 1188 # Basic TraitTypes implementations/subclasses
1189 1189 #-----------------------------------------------------------------------------
1190 1190
1191 1191
1192 1192 class Any(TraitType):
1193 1193 default_value = None
1194 1194 info_text = 'any value'
1195 1195
1196 1196
1197 1197 class Int(TraitType):
1198 1198 """An int trait."""
1199 1199
1200 1200 default_value = 0
1201 1201 info_text = 'an int'
1202 1202
1203 1203 def validate(self, obj, value):
1204 1204 if isinstance(value, int):
1205 1205 return value
1206 1206 self.error(obj, value)
1207 1207
1208 1208 class CInt(Int):
1209 1209 """A casting version of the int trait."""
1210 1210
1211 1211 def validate(self, obj, value):
1212 1212 try:
1213 1213 return int(value)
1214 1214 except:
1215 1215 self.error(obj, value)
1216 1216
1217 1217 if py3compat.PY3:
1218 1218 Long, CLong = Int, CInt
1219 1219 Integer = Int
1220 1220 else:
1221 1221 class Long(TraitType):
1222 1222 """A long integer trait."""
1223 1223
1224 1224 default_value = 0
1225 1225 info_text = 'a long'
1226 1226
1227 1227 def validate(self, obj, value):
1228 1228 if isinstance(value, long):
1229 1229 return value
1230 1230 if isinstance(value, int):
1231 1231 return long(value)
1232 1232 self.error(obj, value)
1233 1233
1234 1234
1235 1235 class CLong(Long):
1236 1236 """A casting version of the long integer trait."""
1237 1237
1238 1238 def validate(self, obj, value):
1239 1239 try:
1240 1240 return long(value)
1241 1241 except:
1242 1242 self.error(obj, value)
1243 1243
1244 1244 class Integer(TraitType):
1245 1245 """An integer trait.
1246 1246
1247 1247 Longs that are unnecessary (<= sys.maxint) are cast to ints."""
1248 1248
1249 1249 default_value = 0
1250 1250 info_text = 'an integer'
1251 1251
1252 1252 def validate(self, obj, value):
1253 1253 if isinstance(value, int):
1254 1254 return value
1255 1255 if isinstance(value, long):
1256 1256 # downcast longs that fit in int:
1257 1257 # note that int(n > sys.maxint) returns a long, so
1258 1258 # we don't need a condition on this cast
1259 1259 return int(value)
1260 1260 if sys.platform == "cli":
1261 1261 from System import Int64
1262 1262 if isinstance(value, Int64):
1263 1263 return int(value)
1264 1264 self.error(obj, value)
1265 1265
1266 1266
1267 1267 class Float(TraitType):
1268 1268 """A float trait."""
1269 1269
1270 1270 default_value = 0.0
1271 1271 info_text = 'a float'
1272 1272
1273 1273 def validate(self, obj, value):
1274 1274 if isinstance(value, float):
1275 1275 return value
1276 1276 if isinstance(value, int):
1277 1277 return float(value)
1278 1278 self.error(obj, value)
1279 1279
1280 1280
1281 1281 class CFloat(Float):
1282 1282 """A casting version of the float trait."""
1283 1283
1284 1284 def validate(self, obj, value):
1285 1285 try:
1286 1286 return float(value)
1287 1287 except:
1288 1288 self.error(obj, value)
1289 1289
1290 1290 class Complex(TraitType):
1291 1291 """A trait for complex numbers."""
1292 1292
1293 1293 default_value = 0.0 + 0.0j
1294 1294 info_text = 'a complex number'
1295 1295
1296 1296 def validate(self, obj, value):
1297 1297 if isinstance(value, complex):
1298 1298 return value
1299 1299 if isinstance(value, (float, int)):
1300 1300 return complex(value)
1301 1301 self.error(obj, value)
1302 1302
1303 1303
1304 1304 class CComplex(Complex):
1305 1305 """A casting version of the complex number trait."""
1306 1306
1307 1307 def validate (self, obj, value):
1308 1308 try:
1309 1309 return complex(value)
1310 1310 except:
1311 1311 self.error(obj, value)
1312 1312
1313 1313 # We should always be explicit about whether we're using bytes or unicode, both
1314 1314 # for Python 3 conversion and for reliable unicode behaviour on Python 2. So
1315 1315 # we don't have a Str type.
1316 1316 class Bytes(TraitType):
1317 1317 """A trait for byte strings."""
1318 1318
1319 1319 default_value = b''
1320 1320 info_text = 'a bytes object'
1321 1321
1322 1322 def validate(self, obj, value):
1323 1323 if isinstance(value, bytes):
1324 1324 return value
1325 1325 self.error(obj, value)
1326 1326
1327 1327
1328 1328 class CBytes(Bytes):
1329 1329 """A casting version of the byte string trait."""
1330 1330
1331 1331 def validate(self, obj, value):
1332 1332 try:
1333 1333 return bytes(value)
1334 1334 except:
1335 1335 self.error(obj, value)
1336 1336
1337 1337
1338 1338 class Unicode(TraitType):
1339 1339 """A trait for unicode strings."""
1340 1340
1341 1341 default_value = u''
1342 1342 info_text = 'a unicode string'
1343 1343
1344 1344 def validate(self, obj, value):
1345 1345 if isinstance(value, py3compat.unicode_type):
1346 1346 return value
1347 1347 if isinstance(value, bytes):
1348 1348 try:
1349 1349 return value.decode('ascii', 'strict')
1350 1350 except UnicodeDecodeError:
1351 1351 msg = "Could not decode {!r} for unicode trait '{}' of {} instance."
1352 1352 raise TraitError(msg.format(value, self.name, class_of(obj)))
1353 1353 self.error(obj, value)
1354 1354
1355 1355
1356 1356 class CUnicode(Unicode):
1357 1357 """A casting version of the unicode trait."""
1358 1358
1359 1359 def validate(self, obj, value):
1360 1360 try:
1361 1361 return py3compat.unicode_type(value)
1362 1362 except:
1363 1363 self.error(obj, value)
1364 1364
1365 1365
1366 1366 class ObjectName(TraitType):
1367 1367 """A string holding a valid object name in this version of Python.
1368 1368
1369 1369 This does not check that the name exists in any scope."""
1370 1370 info_text = "a valid object identifier in Python"
1371 1371
1372 1372 if py3compat.PY3:
1373 1373 # Python 3:
1374 1374 coerce_str = staticmethod(lambda _,s: s)
1375 1375
1376 1376 else:
1377 1377 # Python 2:
1378 1378 def coerce_str(self, obj, value):
1379 1379 "In Python 2, coerce ascii-only unicode to str"
1380 1380 if isinstance(value, unicode):
1381 1381 try:
1382 1382 return str(value)
1383 1383 except UnicodeEncodeError:
1384 1384 self.error(obj, value)
1385 1385 return value
1386 1386
1387 1387 def validate(self, obj, value):
1388 1388 value = self.coerce_str(obj, value)
1389 1389
1390 1390 if isinstance(value, string_types) and py3compat.isidentifier(value):
1391 1391 return value
1392 1392 self.error(obj, value)
1393 1393
1394 1394 class DottedObjectName(ObjectName):
1395 1395 """A string holding a valid dotted object name in Python, such as A.b3._c"""
1396 1396 def validate(self, obj, value):
1397 1397 value = self.coerce_str(obj, value)
1398 1398
1399 1399 if isinstance(value, string_types) and py3compat.isidentifier(value, dotted=True):
1400 1400 return value
1401 1401 self.error(obj, value)
1402 1402
1403 1403
1404 1404 class Bool(TraitType):
1405 1405 """A boolean (True, False) trait."""
1406 1406
1407 1407 default_value = False
1408 1408 info_text = 'a boolean'
1409 1409
1410 1410 def validate(self, obj, value):
1411 1411 if isinstance(value, bool):
1412 1412 return value
1413 1413 self.error(obj, value)
1414 1414
1415 1415
1416 1416 class CBool(Bool):
1417 1417 """A casting version of the boolean trait."""
1418 1418
1419 1419 def validate(self, obj, value):
1420 1420 try:
1421 1421 return bool(value)
1422 1422 except:
1423 1423 self.error(obj, value)
1424 1424
1425 1425
1426 1426 class Enum(TraitType):
1427 1427 """An enum that whose value must be in a given sequence."""
1428 1428
1429 1429 def __init__(self, values, default_value=None, **metadata):
1430 1430 self.values = values
1431 1431 super(Enum, self).__init__(default_value, **metadata)
1432 1432
1433 1433 def validate(self, obj, value):
1434 1434 if value in self.values:
1435 1435 return value
1436 1436 self.error(obj, value)
1437 1437
1438 1438 def info(self):
1439 1439 """ Returns a description of the trait."""
1440 1440 result = 'any of ' + repr(self.values)
1441 1441 if self.allow_none:
1442 1442 return result + ' or None'
1443 1443 return result
1444 1444
1445 1445 class CaselessStrEnum(Enum):
1446 1446 """An enum of strings that are caseless in validate."""
1447 1447
1448 1448 def validate(self, obj, value):
1449 1449 if not isinstance(value, py3compat.string_types):
1450 1450 self.error(obj, value)
1451 1451
1452 1452 for v in self.values:
1453 1453 if v.lower() == value.lower():
1454 1454 return v
1455 1455 self.error(obj, value)
1456 1456
1457 1457 class Container(Instance):
1458 1458 """An instance of a container (list, set, etc.)
1459 1459
1460 1460 To be subclassed by overriding klass.
1461 1461 """
1462 1462 klass = None
1463 1463 _cast_types = ()
1464 1464 _valid_defaults = SequenceTypes
1465 1465 _trait = None
1466 1466
1467 1467 def __init__(self, trait=None, default_value=None, allow_none=False,
1468 1468 **metadata):
1469 1469 """Create a container trait type from a list, set, or tuple.
1470 1470
1471 1471 The default value is created by doing ``List(default_value)``,
1472 1472 which creates a copy of the ``default_value``.
1473 1473
1474 1474 ``trait`` can be specified, which restricts the type of elements
1475 1475 in the container to that TraitType.
1476 1476
1477 1477 If only one arg is given and it is not a Trait, it is taken as
1478 1478 ``default_value``:
1479 1479
1480 1480 ``c = List([1,2,3])``
1481 1481
1482 1482 Parameters
1483 1483 ----------
1484 1484
1485 1485 trait : TraitType [ optional ]
1486 1486 the type for restricting the contents of the Container. If unspecified,
1487 1487 types are not checked.
1488 1488
1489 1489 default_value : SequenceType [ optional ]
1490 1490 The default value for the Trait. Must be list/tuple/set, and
1491 1491 will be cast to the container type.
1492 1492
1493 1493 allow_none : bool [ default False ]
1494 1494 Whether to allow the value to be None
1495 1495
1496 1496 **metadata : any
1497 1497 further keys for extensions to the Trait (e.g. config)
1498 1498
1499 1499 """
1500 1500 # allow List([values]):
1501 1501 if default_value is None and not is_trait(trait):
1502 1502 default_value = trait
1503 1503 trait = None
1504 1504
1505 1505 if default_value is None:
1506 1506 args = ()
1507 1507 elif isinstance(default_value, self._valid_defaults):
1508 1508 args = (default_value,)
1509 1509 else:
1510 1510 raise TypeError('default value of %s was %s' %(self.__class__.__name__, default_value))
1511 1511
1512 1512 if is_trait(trait):
1513 1513 self._trait = trait() if isinstance(trait, type) else trait
1514 1514 self._trait.name = 'element'
1515 1515 elif trait is not None:
1516 1516 raise TypeError("`trait` must be a Trait or None, got %s"%repr_type(trait))
1517 1517
1518 1518 super(Container,self).__init__(klass=self.klass, args=args,
1519 1519 allow_none=allow_none, **metadata)
1520 1520
1521 1521 def element_error(self, obj, element, validator):
1522 1522 e = "Element of the '%s' trait of %s instance must be %s, but a value of %s was specified." \
1523 1523 % (self.name, class_of(obj), validator.info(), repr_type(element))
1524 1524 raise TraitError(e)
1525 1525
1526 1526 def validate(self, obj, value):
1527 1527 if isinstance(value, self._cast_types):
1528 1528 value = self.klass(value)
1529 1529 value = super(Container, self).validate(obj, value)
1530 1530 if value is None:
1531 1531 return value
1532 1532
1533 1533 value = self.validate_elements(obj, value)
1534 1534
1535 1535 return value
1536 1536
1537 1537 def validate_elements(self, obj, value):
1538 1538 validated = []
1539 1539 if self._trait is None or isinstance(self._trait, Any):
1540 1540 return value
1541 1541 for v in value:
1542 1542 try:
1543 1543 v = self._trait._validate(obj, v)
1544 1544 except TraitError:
1545 1545 self.element_error(obj, v, self._trait)
1546 1546 else:
1547 1547 validated.append(v)
1548 1548 return self.klass(validated)
1549 1549
1550 1550 def instance_init(self):
1551 1551 if isinstance(self._trait, TraitType):
1552 1552 self._trait.this_class = self.this_class
1553 1553 self._trait.instance_init()
1554 1554 super(Container, self).instance_init()
1555 1555
1556 1556
1557 1557 class List(Container):
1558 1558 """An instance of a Python list."""
1559 1559 klass = list
1560 1560 _cast_types = (tuple,)
1561 1561
1562 1562 def __init__(self, trait=None, default_value=None, minlen=0, maxlen=sys.maxsize, **metadata):
1563 1563 """Create a List trait type from a list, set, or tuple.
1564 1564
1565 1565 The default value is created by doing ``List(default_value)``,
1566 1566 which creates a copy of the ``default_value``.
1567 1567
1568 1568 ``trait`` can be specified, which restricts the type of elements
1569 1569 in the container to that TraitType.
1570 1570
1571 1571 If only one arg is given and it is not a Trait, it is taken as
1572 1572 ``default_value``:
1573 1573
1574 1574 ``c = List([1,2,3])``
1575 1575
1576 1576 Parameters
1577 1577 ----------
1578 1578
1579 1579 trait : TraitType [ optional ]
1580 1580 the type for restricting the contents of the Container. If unspecified,
1581 1581 types are not checked.
1582 1582
1583 1583 default_value : SequenceType [ optional ]
1584 1584 The default value for the Trait. Must be list/tuple/set, and
1585 1585 will be cast to the container type.
1586 1586
1587 1587 minlen : Int [ default 0 ]
1588 1588 The minimum length of the input list
1589 1589
1590 1590 maxlen : Int [ default sys.maxsize ]
1591 1591 The maximum length of the input list
1592 1592
1593 1593 allow_none : bool [ default False ]
1594 1594 Whether to allow the value to be None
1595 1595
1596 1596 **metadata : any
1597 1597 further keys for extensions to the Trait (e.g. config)
1598 1598
1599 1599 """
1600 1600 self._minlen = minlen
1601 1601 self._maxlen = maxlen
1602 1602 super(List, self).__init__(trait=trait, default_value=default_value,
1603 1603 **metadata)
1604 1604
1605 1605 def length_error(self, obj, value):
1606 1606 e = "The '%s' trait of %s instance must be of length %i <= L <= %i, but a value of %s was specified." \
1607 1607 % (self.name, class_of(obj), self._minlen, self._maxlen, value)
1608 1608 raise TraitError(e)
1609 1609
1610 1610 def validate_elements(self, obj, value):
1611 1611 length = len(value)
1612 1612 if length < self._minlen or length > self._maxlen:
1613 1613 self.length_error(obj, value)
1614 1614
1615 1615 return super(List, self).validate_elements(obj, value)
1616 1616
1617 1617 def validate(self, obj, value):
1618 1618 value = super(List, self).validate(obj, value)
1619 1619 value = self.validate_elements(obj, value)
1620 1620 return value
1621 1621
1622 1622
1623 1623 class Set(List):
1624 1624 """An instance of a Python set."""
1625 1625 klass = set
1626 1626 _cast_types = (tuple, list)
1627 1627
1628 1628
1629 1629 class Tuple(Container):
1630 1630 """An instance of a Python tuple."""
1631 1631 klass = tuple
1632 1632 _cast_types = (list,)
1633 1633
1634 1634 def __init__(self, *traits, **metadata):
1635 1635 """Tuple(*traits, default_value=None, **medatata)
1636 1636
1637 1637 Create a tuple from a list, set, or tuple.
1638 1638
1639 1639 Create a fixed-type tuple with Traits:
1640 1640
1641 1641 ``t = Tuple(Int, Str, CStr)``
1642 1642
1643 1643 would be length 3, with Int,Str,CStr for each element.
1644 1644
1645 1645 If only one arg is given and it is not a Trait, it is taken as
1646 1646 default_value:
1647 1647
1648 1648 ``t = Tuple((1,2,3))``
1649 1649
1650 1650 Otherwise, ``default_value`` *must* be specified by keyword.
1651 1651
1652 1652 Parameters
1653 1653 ----------
1654 1654
1655 1655 *traits : TraitTypes [ optional ]
1656 1656 the types for restricting the contents of the Tuple. If unspecified,
1657 1657 types are not checked. If specified, then each positional argument
1658 1658 corresponds to an element of the tuple. Tuples defined with traits
1659 1659 are of fixed length.
1660 1660
1661 1661 default_value : SequenceType [ optional ]
1662 1662 The default value for the Tuple. Must be list/tuple/set, and
1663 1663 will be cast to a tuple. If `traits` are specified, the
1664 1664 `default_value` must conform to the shape and type they specify.
1665 1665
1666 1666 allow_none : bool [ default False ]
1667 1667 Whether to allow the value to be None
1668 1668
1669 1669 **metadata : any
1670 1670 further keys for extensions to the Trait (e.g. config)
1671 1671
1672 1672 """
1673 1673 default_value = metadata.pop('default_value', None)
1674 1674 allow_none = metadata.pop('allow_none', True)
1675 1675
1676 1676 # allow Tuple((values,)):
1677 1677 if len(traits) == 1 and default_value is None and not is_trait(traits[0]):
1678 1678 default_value = traits[0]
1679 1679 traits = ()
1680 1680
1681 1681 if default_value is None:
1682 1682 args = ()
1683 1683 elif isinstance(default_value, self._valid_defaults):
1684 1684 args = (default_value,)
1685 1685 else:
1686 1686 raise TypeError('default value of %s was %s' %(self.__class__.__name__, default_value))
1687 1687
1688 1688 self._traits = []
1689 1689 for trait in traits:
1690 1690 t = trait() if isinstance(trait, type) else trait
1691 1691 t.name = 'element'
1692 1692 self._traits.append(t)
1693 1693
1694 1694 if self._traits and default_value is None:
1695 1695 # don't allow default to be an empty container if length is specified
1696 1696 args = None
1697 1697 super(Container,self).__init__(klass=self.klass, args=args, allow_none=allow_none, **metadata)
1698 1698
1699 1699 def validate_elements(self, obj, value):
1700 1700 if not self._traits:
1701 1701 # nothing to validate
1702 1702 return value
1703 1703 if len(value) != len(self._traits):
1704 1704 e = "The '%s' trait of %s instance requires %i elements, but a value of %s was specified." \
1705 1705 % (self.name, class_of(obj), len(self._traits), repr_type(value))
1706 1706 raise TraitError(e)
1707 1707
1708 1708 validated = []
1709 1709 for t, v in zip(self._traits, value):
1710 1710 try:
1711 1711 v = t._validate(obj, v)
1712 1712 except TraitError:
1713 1713 self.element_error(obj, v, t)
1714 1714 else:
1715 1715 validated.append(v)
1716 1716 return tuple(validated)
1717 1717
1718 1718 def instance_init(self):
1719 1719 for trait in self._traits:
1720 1720 if isinstance(trait, TraitType):
1721 1721 trait.this_class = self.this_class
1722 1722 trait.instance_init()
1723 1723 super(Container, self).instance_init()
1724 1724
1725 1725
1726 1726 class Dict(Instance):
1727 1727 """An instance of a Python dict."""
1728 1728 _trait = None
1729 1729
1730 1730 def __init__(self, trait=None, default_value=NoDefaultSpecified, allow_none=False, **metadata):
1731 1731 """Create a dict trait type from a dict.
1732 1732
1733 1733 The default value is created by doing ``dict(default_value)``,
1734 1734 which creates a copy of the ``default_value``.
1735 1735
1736 1736 trait : TraitType [ optional ]
1737 1737 the type for restricting the contents of the Container. If unspecified,
1738 1738 types are not checked.
1739 1739
1740 1740 default_value : SequenceType [ optional ]
1741 1741 The default value for the Dict. Must be dict, tuple, or None, and
1742 1742 will be cast to a dict if not None. If `trait` is specified, the
1743 1743 `default_value` must conform to the constraints it specifies.
1744 1744
1745 1745 allow_none : bool [ default False ]
1746 1746 Whether to allow the value to be None
1747 1747
1748 1748 """
1749 1749 if default_value is NoDefaultSpecified and trait is not None:
1750 1750 if not is_trait(trait):
1751 1751 default_value = trait
1752 1752 trait = None
1753 1753 if default_value is NoDefaultSpecified:
1754 1754 default_value = {}
1755 1755 if default_value is None:
1756 1756 args = None
1757 1757 elif isinstance(default_value, dict):
1758 1758 args = (default_value,)
1759 1759 elif isinstance(default_value, SequenceTypes):
1760 1760 args = (default_value,)
1761 1761 else:
1762 1762 raise TypeError('default value of Dict was %s' % default_value)
1763 1763
1764 1764 if is_trait(trait):
1765 1765 self._trait = trait() if isinstance(trait, type) else trait
1766 1766 self._trait.name = 'element'
1767 1767 elif trait is not None:
1768 1768 raise TypeError("`trait` must be a Trait or None, got %s"%repr_type(trait))
1769 1769
1770 1770 super(Dict,self).__init__(klass=dict, args=args,
1771 1771 allow_none=allow_none, **metadata)
1772 1772
1773 1773 def element_error(self, obj, element, validator):
1774 1774 e = "Element of the '%s' trait of %s instance must be %s, but a value of %s was specified." \
1775 1775 % (self.name, class_of(obj), validator.info(), repr_type(element))
1776 1776 raise TraitError(e)
1777 1777
1778 1778 def validate(self, obj, value):
1779 1779 value = super(Dict, self).validate(obj, value)
1780 1780 if value is None:
1781 1781 return value
1782 1782 value = self.validate_elements(obj, value)
1783 1783 return value
1784 1784
1785 1785 def validate_elements(self, obj, value):
1786 1786 if self._trait is None or isinstance(self._trait, Any):
1787 1787 return value
1788 1788 validated = {}
1789 1789 for key in value:
1790 1790 v = value[key]
1791 1791 try:
1792 1792 v = self._trait._validate(obj, v)
1793 1793 except TraitError:
1794 1794 self.element_error(obj, v, self._trait)
1795 1795 else:
1796 1796 validated[key] = v
1797 1797 return self.klass(validated)
1798 1798
1799 1799 def instance_init(self):
1800 1800 if isinstance(self._trait, TraitType):
1801 1801 self._trait.this_class = self.this_class
1802 1802 self._trait.instance_init()
1803 1803 super(Dict, self).instance_init()
1804 1804
1805 1805
1806 1806 class EventfulDict(Instance):
1807 1807 """An instance of an EventfulDict."""
1808 1808
1809 1809 def __init__(self, default_value={}, allow_none=False, **metadata):
1810 1810 """Create a EventfulDict trait type from a dict.
1811 1811
1812 1812 The default value is created by doing
1813 1813 ``eventful.EvenfulDict(default_value)``, which creates a copy of the
1814 1814 ``default_value``.
1815 1815 """
1816 1816 if default_value is None:
1817 1817 args = None
1818 1818 elif isinstance(default_value, dict):
1819 1819 args = (default_value,)
1820 1820 elif isinstance(default_value, SequenceTypes):
1821 1821 args = (default_value,)
1822 1822 else:
1823 1823 raise TypeError('default value of EventfulDict was %s' % default_value)
1824 1824
1825 1825 super(EventfulDict, self).__init__(klass=eventful.EventfulDict, args=args,
1826 1826 allow_none=allow_none, **metadata)
1827 1827
1828 1828
1829 1829 class EventfulList(Instance):
1830 1830 """An instance of an EventfulList."""
1831 1831
1832 1832 def __init__(self, default_value=None, allow_none=False, **metadata):
1833 1833 """Create a EventfulList trait type from a dict.
1834 1834
1835 1835 The default value is created by doing
1836 1836 ``eventful.EvenfulList(default_value)``, which creates a copy of the
1837 1837 ``default_value``.
1838 1838 """
1839 1839 if default_value is None:
1840 1840 args = ((),)
1841 1841 else:
1842 1842 args = (default_value,)
1843 1843
1844 1844 super(EventfulList, self).__init__(klass=eventful.EventfulList, args=args,
1845 1845 allow_none=allow_none, **metadata)
1846 1846
1847 1847
1848 1848 class TCPAddress(TraitType):
1849 1849 """A trait for an (ip, port) tuple.
1850 1850
1851 1851 This allows for both IPv4 IP addresses as well as hostnames.
1852 1852 """
1853 1853
1854 1854 default_value = ('127.0.0.1', 0)
1855 1855 info_text = 'an (ip, port) tuple'
1856 1856
1857 1857 def validate(self, obj, value):
1858 1858 if isinstance(value, tuple):
1859 1859 if len(value) == 2:
1860 1860 if isinstance(value[0], py3compat.string_types) and isinstance(value[1], int):
1861 1861 port = value[1]
1862 1862 if port >= 0 and port <= 65535:
1863 1863 return value
1864 1864 self.error(obj, value)
1865 1865
1866 1866 class CRegExp(TraitType):
1867 1867 """A casting compiled regular expression trait.
1868 1868
1869 1869 Accepts both strings and compiled regular expressions. The resulting
1870 1870 attribute will be a compiled regular expression."""
1871 1871
1872 1872 info_text = 'a regular expression'
1873 1873
1874 1874 def validate(self, obj, value):
1875 1875 try:
1876 1876 return re.compile(value)
1877 1877 except:
1878 1878 self.error(obj, value)
General Comments 0
You need to be logged in to leave comments. Login now