Show More
@@ -0,0 +1,32 b'' | |||||
|
1 | #!/usr/bin/env python | |||
|
2 | # encoding: utf-8 | |||
|
3 | """ | |||
|
4 | A simple utility to import something by its string name. | |||
|
5 | ||||
|
6 | Authors: | |||
|
7 | ||||
|
8 | * Brian Granger | |||
|
9 | """ | |||
|
10 | ||||
|
11 | #----------------------------------------------------------------------------- | |||
|
12 | # Copyright (C) 2008-2009 The IPython Development Team | |||
|
13 | # | |||
|
14 | # Distributed under the terms of the BSD License. The full license is in | |||
|
15 | # the file COPYING, distributed as part of this software. | |||
|
16 | #----------------------------------------------------------------------------- | |||
|
17 | ||||
|
18 | #----------------------------------------------------------------------------- | |||
|
19 | # Functions and classes | |||
|
20 | #----------------------------------------------------------------------------- | |||
|
21 | ||||
|
22 | def import_item(name): | |||
|
23 | """Import and return bar given the string foo.bar.""" | |||
|
24 | package = '.'.join(name.split('.')[0:-1]) | |||
|
25 | obj = name.split('.')[-1] | |||
|
26 | execString = 'from %s import %s' % (package, obj) | |||
|
27 | try: | |||
|
28 | exec execString | |||
|
29 | except SyntaxError: | |||
|
30 | raise ImportError("Invalid class specification: %s" % name) | |||
|
31 | exec 'temp = %s' % obj | |||
|
32 | return temp |
@@ -24,6 +24,8 b' import __builtin__' | |||||
24 | from IPython.core.component import Component |
|
24 | from IPython.core.component import Component | |
25 | from IPython.core.quitter import Quitter |
|
25 | from IPython.core.quitter import Quitter | |
26 |
|
26 | |||
|
27 | from IPython.utils.traitlets import Instance | |||
|
28 | ||||
27 | #----------------------------------------------------------------------------- |
|
29 | #----------------------------------------------------------------------------- | |
28 | # Classes and functions |
|
30 | # Classes and functions | |
29 | #----------------------------------------------------------------------------- |
|
31 | #----------------------------------------------------------------------------- | |
@@ -34,12 +36,13 b' BuiltinUndefined = BuiltinUndefined()' | |||||
34 |
|
36 | |||
35 |
|
37 | |||
36 | class BuiltinTrap(Component): |
|
38 | class BuiltinTrap(Component): | |
|
39 | shell = Instance('IPython.core.iplib.InteractiveShell') | |||
37 |
|
40 | |||
38 | def __init__(self, parent, name=None, config=None): |
|
41 | def __init__(self, parent, name=None, config=None): | |
39 | super(BuiltinTrap, self).__init__(parent, name, config) |
|
42 | super(BuiltinTrap, self).__init__(parent, name, config) | |
40 | # Don't just grab parent!!! |
|
43 | # Don't just grab parent!!! | |
41 | from IPython.core.iplib import InteractiveShell |
|
44 | self.shell = Component.get_instances(root=self.root, | |
42 | self.shell = InteractiveShell.get_instances(root=self.root)[0] |
|
45 | klass='IPython.core.iplib.InteractiveShell')[0] | |
43 | self._orig_builtins = {} |
|
46 | self._orig_builtins = {} | |
44 |
|
47 | |||
45 | def __enter__(self): |
|
48 | def __enter__(self): |
@@ -24,6 +24,7 b' from copy import deepcopy' | |||||
24 | import datetime |
|
24 | import datetime | |
25 | from weakref import WeakValueDictionary |
|
25 | from weakref import WeakValueDictionary | |
26 |
|
26 | |||
|
27 | from IPython.utils.importstring import import_item | |||
27 | from IPython.utils.ipstruct import Struct |
|
28 | from IPython.utils.ipstruct import Struct | |
28 | from IPython.utils.traitlets import ( |
|
29 | from IPython.utils.traitlets import ( | |
29 | HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This |
|
30 | HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This | |
@@ -64,7 +65,7 b' class MetaComponentTracker(type):' | |||||
64 |
|
65 | |||
65 | return instance |
|
66 | return instance | |
66 |
|
67 | |||
67 |
def get_instances(cls, name=None, root=None, |
|
68 | def get_instances(cls, name=None, root=None, klass=None): | |
68 | """Get all instances of cls and its subclasses. |
|
69 | """Get all instances of cls and its subclasses. | |
69 |
|
70 | |||
70 | Parameters |
|
71 | Parameters | |
@@ -73,26 +74,31 b' class MetaComponentTracker(type):' | |||||
73 | Limit to components with this name. |
|
74 | Limit to components with this name. | |
74 | root : Component or subclass |
|
75 | root : Component or subclass | |
75 | Limit to components having this root. |
|
76 | Limit to components having this root. | |
76 |
|
|
77 | klass : class or str | |
77 | The string name of a class to match exactly. |
|
78 | Limits to instances of the class or its subclasses. If a str | |
|
79 | is given ut must be in the form 'foo.bar.MyClass'. The str | |||
|
80 | form of this argument is useful for forward declarations. | |||
78 | """ |
|
81 | """ | |
|
82 | if klass is not None: | |||
|
83 | if isinstance(klass, basestring): | |||
|
84 | klass = import_item(klass) | |||
79 | instances = cls.__instance_refs.values() |
|
85 | instances = cls.__instance_refs.values() | |
80 | if name is not None: |
|
86 | if name is not None: | |
81 | instances = [i for i in instances if i.name == name] |
|
87 | instances = [i for i in instances if i.name == name] | |
82 |
if |
|
88 | if klass is not None: | |
83 |
instances = [i for i in instances if i |
|
89 | instances = [i for i in instances if isinstance(i, klass)] | |
84 | if root is not None: |
|
90 | if root is not None: | |
85 | instances = [i for i in instances if i.root == root] |
|
91 | instances = [i for i in instances if i.root == root] | |
86 | return instances |
|
92 | return instances | |
87 |
|
93 | |||
88 | def get_instances_by_condition(cls, call, name=None, root=None, |
|
94 | def get_instances_by_condition(cls, call, name=None, root=None, | |
89 |
|
|
95 | klass=None): | |
90 | """Get all instances of cls, i such that call(i)==True. |
|
96 | """Get all instances of cls, i such that call(i)==True. | |
91 |
|
97 | |||
92 | This also takes the ``name`` and ``root`` and ``classname`` |
|
98 | This also takes the ``name`` and ``root`` and ``classname`` | |
93 | arguments of :meth:`get_instance` |
|
99 | arguments of :meth:`get_instance` | |
94 | """ |
|
100 | """ | |
95 |
return [i for i in cls.get_instances(name, root, |
|
101 | return [i for i in cls.get_instances(name, root, klass) if call(i)] | |
96 |
|
102 | |||
97 |
|
103 | |||
98 | class ComponentNameGenerator(object): |
|
104 | class ComponentNameGenerator(object): |
@@ -1252,8 +1252,8 b' class InteractiveShell(Component, Magic):' | |||||
1252 | else: |
|
1252 | else: | |
1253 | magic_args = self.var_expand(magic_args,1) |
|
1253 | magic_args = self.var_expand(magic_args,1) | |
1254 | with self.builtin_trap: |
|
1254 | with self.builtin_trap: | |
1255 |
re |
|
1255 | return fn(magic_args) | |
1256 | return result |
|
1256 | # return result | |
1257 |
|
1257 | |||
1258 | def define_magic(self, magicname, func): |
|
1258 | def define_magic(self, magicname, func): | |
1259 | """Expose own function as magic function for ipython |
|
1259 | """Expose own function as magic function for ipython | |
@@ -1357,8 +1357,7 b' class InteractiveShell(Component, Magic):' | |||||
1357 | Returns the result of evaluation |
|
1357 | Returns the result of evaluation | |
1358 | """ |
|
1358 | """ | |
1359 | with self.builtin_trap: |
|
1359 | with self.builtin_trap: | |
1360 |
re |
|
1360 | return eval(expr, self.user_global_ns, self.user_ns) | |
1361 | return result |
|
|||
1362 |
|
1361 | |||
1363 | def getoutput(self, cmd): |
|
1362 | def getoutput(self, cmd): | |
1364 | return getoutput(self.var_expand(cmd,depth=2), |
|
1363 | return getoutput(self.var_expand(cmd,depth=2), |
@@ -20,7 +20,7 b' from twisted.internet import defer' | |||||
20 | from IPython.kernel.fcutil import Tub, UnauthenticatedTub |
|
20 | from IPython.kernel.fcutil import Tub, UnauthenticatedTub | |
21 |
|
21 | |||
22 | from IPython.kernel.config import config_manager as kernel_config_manager |
|
22 | from IPython.kernel.config import config_manager as kernel_config_manager | |
23 |
from IPython. |
|
23 | from IPython.utils.importstring import import_item | |
24 | from IPython.kernel.fcutil import find_furl |
|
24 | from IPython.kernel.fcutil import find_furl | |
25 |
|
25 | |||
26 | co = kernel_config_manager.get_config_obj() |
|
26 | co = kernel_config_manager.get_config_obj() |
@@ -52,7 +52,7 b' get_log_dir()' | |||||
52 | get_security_dir() |
|
52 | get_security_dir() | |
53 |
|
53 | |||
54 | from IPython.kernel.config import config_manager as kernel_config_manager |
|
54 | from IPython.kernel.config import config_manager as kernel_config_manager | |
55 |
from IPython. |
|
55 | from IPython.utils.importstring import import_item | |
56 |
|
56 | |||
57 |
|
57 | |||
58 | #------------------------------------------------------------------------------- |
|
58 | #------------------------------------------------------------------------------- |
@@ -31,7 +31,7 b' from twisted.python import log' | |||||
31 | from IPython.kernel.fcutil import Tub, UnauthenticatedTub |
|
31 | from IPython.kernel.fcutil import Tub, UnauthenticatedTub | |
32 |
|
32 | |||
33 | from IPython.kernel.core.config import config_manager as core_config_manager |
|
33 | from IPython.kernel.core.config import config_manager as core_config_manager | |
34 |
from IPython. |
|
34 | from IPython.utils.importstring import import_item | |
35 | from IPython.kernel.engineservice import EngineService |
|
35 | from IPython.kernel.engineservice import EngineService | |
36 |
|
36 | |||
37 | # Create various ipython directories if they don't exist. |
|
37 | # Create various ipython directories if they don't exist. |
@@ -377,6 +377,7 b' class TestType(TestCase):' | |||||
377 |
|
377 | |||
378 | a = A() |
|
378 | a = A() | |
379 | self.assertEquals(a.klass, None) |
|
379 | self.assertEquals(a.klass, None) | |
|
380 | ||||
380 | a.klass = B |
|
381 | a.klass = B | |
381 | self.assertEquals(a.klass, B) |
|
382 | self.assertEquals(a.klass, B) | |
382 | self.assertRaises(TraitletError, setattr, a, 'klass', 10) |
|
383 | self.assertRaises(TraitletError, setattr, a, 'klass', 10) | |
@@ -409,11 +410,15 b' class TestType(TestCase):' | |||||
409 |
|
410 | |||
410 | def test_validate_klass(self): |
|
411 | def test_validate_klass(self): | |
411 |
|
412 | |||
412 | def inner(): |
|
|||
413 |
|
|
413 | class A(HasTraitlets): | |
414 |
|
|
414 | klass = Type('no strings allowed') | |
415 |
|
415 | |||
416 |
self.assertRaises( |
|
416 | self.assertRaises(ImportError, A) | |
|
417 | ||||
|
418 | class A(HasTraitlets): | |||
|
419 | klass = Type('rub.adub.Duck') | |||
|
420 | ||||
|
421 | self.assertRaises(ImportError, A) | |||
417 |
|
422 | |||
418 | def test_validate_default(self): |
|
423 | def test_validate_default(self): | |
419 |
|
424 | |||
@@ -421,13 +426,25 b' class TestType(TestCase):' | |||||
421 | class A(HasTraitlets): |
|
426 | class A(HasTraitlets): | |
422 | klass = Type('bad default', B) |
|
427 | klass = Type('bad default', B) | |
423 |
|
428 | |||
424 |
self.assertRaises( |
|
429 | self.assertRaises(ImportError, A) | |
425 |
|
430 | |||
426 | class C(HasTraitlets): |
|
431 | class C(HasTraitlets): | |
427 | klass = Type(None, B, allow_none=False) |
|
432 | klass = Type(None, B, allow_none=False) | |
428 |
|
433 | |||
429 | self.assertRaises(TraitletError, C) |
|
434 | self.assertRaises(TraitletError, C) | |
430 |
|
435 | |||
|
436 | def test_str_klass(self): | |||
|
437 | ||||
|
438 | class A(HasTraitlets): | |||
|
439 | klass = Type('IPython.utils.ipstruct.Struct') | |||
|
440 | ||||
|
441 | from IPython.utils.ipstruct import Struct | |||
|
442 | a = A() | |||
|
443 | a.klass = Struct | |||
|
444 | self.assertEquals(a.klass, Struct) | |||
|
445 | ||||
|
446 | self.assertRaises(TraitletError, setattr, a, 'klass', 10) | |||
|
447 | ||||
431 | class TestInstance(TestCase): |
|
448 | class TestInstance(TestCase): | |
432 |
|
449 | |||
433 | def test_basic(self): |
|
450 | def test_basic(self): |
@@ -57,6 +57,8 b' from types import (' | |||||
57 | ListType, TupleType |
|
57 | ListType, TupleType | |
58 | ) |
|
58 | ) | |
59 |
|
59 | |||
|
60 | from IPython.utils.importstring import import_item | |||
|
61 | ||||
60 | ClassTypes = (ClassType, type) |
|
62 | ClassTypes = (ClassType, type) | |
61 |
|
63 | |||
62 | SequenceTypes = (ListType, TupleType) |
|
64 | SequenceTypes = (ListType, TupleType) | |
@@ -142,7 +144,6 b' def parse_notifier_name(name):' | |||||
142 | class _SimpleTest: |
|
144 | class _SimpleTest: | |
143 | def __init__ ( self, value ): self.value = value |
|
145 | def __init__ ( self, value ): self.value = value | |
144 | def __call__ ( self, test ): |
|
146 | def __call__ ( self, test ): | |
145 | print test, self.value |
|
|||
146 | return test == self.value |
|
147 | return test == self.value | |
147 | def __repr__(self): |
|
148 | def __repr__(self): | |
148 | return "<SimpleTest(%r)" % self.value |
|
149 | return "<SimpleTest(%r)" % self.value | |
@@ -203,12 +204,38 b' class TraitletType(object):' | |||||
203 | dv = self.default_value |
|
204 | dv = self.default_value | |
204 | return dv |
|
205 | return dv | |
205 |
|
206 | |||
|
207 | def instance_init(self, obj): | |||
|
208 | """This is called by :meth:`HasTraitlets.__new__` to finish init'ing. | |||
|
209 | ||||
|
210 | Some stages of initialization must be delayed until the parent | |||
|
211 | :class:`HasTraitlets` instance has been created. This method is | |||
|
212 | called in :meth:`HasTraitlets.__new__` after the instance has been | |||
|
213 | created. | |||
|
214 | ||||
|
215 | This method trigger the creation and validation of default values | |||
|
216 | and also things like the resolution of str given class names in | |||
|
217 | :class:`Type` and :class`Instance`. | |||
|
218 | ||||
|
219 | Parameters | |||
|
220 | ---------- | |||
|
221 | obj : :class:`HasTraitlets` instance | |||
|
222 | The parent :class:`HasTraitlets` instance that has just been | |||
|
223 | created. | |||
|
224 | """ | |||
|
225 | self.set_default_value(obj) | |||
|
226 | ||||
206 | def set_default_value(self, obj): |
|
227 | def set_default_value(self, obj): | |
|
228 | """Set the default value on a per instance basis. | |||
|
229 | ||||
|
230 | This method is called by :meth:`instance_init` to create and | |||
|
231 | validate the default value. The creation and validation of | |||
|
232 | default values must be delayed until the parent :class:`HasTraitlets` | |||
|
233 | class has been instantiated. | |||
|
234 | """ | |||
207 | dv = self.get_default_value() |
|
235 | dv = self.get_default_value() | |
208 | newdv = self._validate(obj, dv) |
|
236 | newdv = self._validate(obj, dv) | |
209 | obj._traitlet_values[self.name] = newdv |
|
237 | obj._traitlet_values[self.name] = newdv | |
210 |
|
238 | |||
211 |
|
||||
212 | def __get__(self, obj, cls=None): |
|
239 | def __get__(self, obj, cls=None): | |
213 | """Get the value of the traitlet by self.name for the instance. |
|
240 | """Get the value of the traitlet by self.name for the instance. | |
214 |
|
241 | |||
@@ -289,12 +316,6 b' class MetaHasTraitlets(type):' | |||||
289 | This instantiates all TraitletTypes in the class dict and sets their |
|
316 | This instantiates all TraitletTypes in the class dict and sets their | |
290 | :attr:`name` attribute. |
|
317 | :attr:`name` attribute. | |
291 | """ |
|
318 | """ | |
292 | # print "=========================" |
|
|||
293 | # print "MetaHasTraitlets.__new__" |
|
|||
294 | # print "mcls, ", mcls |
|
|||
295 | # print "name, ", name |
|
|||
296 | # print "bases, ", bases |
|
|||
297 | # print "classdict, ", classdict |
|
|||
298 | for k,v in classdict.iteritems(): |
|
319 | for k,v in classdict.iteritems(): | |
299 | if isinstance(v, TraitletType): |
|
320 | if isinstance(v, TraitletType): | |
300 | v.name = k |
|
321 | v.name = k | |
@@ -311,12 +332,6 b' class MetaHasTraitlets(type):' | |||||
311 | This sets the :attr:`this_class` attribute of each TraitletType in the |
|
332 | This sets the :attr:`this_class` attribute of each TraitletType in the | |
312 | class dict to the newly created class ``cls``. |
|
333 | class dict to the newly created class ``cls``. | |
313 | """ |
|
334 | """ | |
314 | # print "=========================" |
|
|||
315 | # print "MetaHasTraitlets.__init__" |
|
|||
316 | # print "cls, ", cls |
|
|||
317 | # print "name, ", name |
|
|||
318 | # print "bases, ", bases |
|
|||
319 | # print "classdict, ", classdict |
|
|||
320 | for k, v in classdict.iteritems(): |
|
335 | for k, v in classdict.iteritems(): | |
321 | if isinstance(v, TraitletType): |
|
336 | if isinstance(v, TraitletType): | |
322 | v.this_class = cls |
|
337 | v.this_class = cls | |
@@ -335,7 +350,7 b' class HasTraitlets(object):' | |||||
335 | for key in dir(cls): |
|
350 | for key in dir(cls): | |
336 | value = getattr(cls, key) |
|
351 | value = getattr(cls, key) | |
337 | if isinstance(value, TraitletType): |
|
352 | if isinstance(value, TraitletType): | |
338 |
value. |
|
353 | value.instance_init(inst) | |
339 | return inst |
|
354 | return inst | |
340 |
|
355 | |||
341 | # def __init__(self): |
|
356 | # def __init__(self): | |
@@ -512,13 +527,21 b' class Type(ClassBasedTraitletType):' | |||||
512 | A Type traitlet specifies that its values must be subclasses of |
|
527 | A Type traitlet specifies that its values must be subclasses of | |
513 | a particular class. |
|
528 | a particular class. | |
514 |
|
529 | |||
|
530 | If only ``default_value`` is given, it is used for the ``klass`` as | |||
|
531 | well. | |||
|
532 | ||||
515 | Parameters |
|
533 | Parameters | |
516 | ---------- |
|
534 | ---------- | |
517 | default_value : class |
|
535 | default_value : class, str or None | |
518 | The default value must be a subclass of klass. |
|
536 | The default value must be a subclass of klass. If an str, | |
|
537 | the str must be a fully specified class name, like 'foo.bar.Bah'. | |||
|
538 | The string is resolved into real class, when the parent | |||
|
539 | :class:`HasTraitlets` class is instantiated. | |||
519 | klass : class, str, None |
|
540 | klass : class, str, None | |
520 | Values of this traitlet must be a subclass of klass. The klass |
|
541 | Values of this traitlet must be a subclass of klass. The klass | |
521 | may be specified in a string like: 'foo.bar.MyClass'. |
|
542 | may be specified in a string like: 'foo.bar.MyClass'. | |
|
543 | The string is resolved into real class, when the parent | |||
|
544 | :class:`HasTraitlets` class is instantiated. | |||
522 | allow_none : boolean |
|
545 | allow_none : boolean | |
523 | Indicates whether None is allowed as an assignable value. Even if |
|
546 | Indicates whether None is allowed as an assignable value. Even if | |
524 | ``False``, the default value may be ``None``. |
|
547 | ``False``, the default value may be ``None``. | |
@@ -529,7 +552,7 b' class Type(ClassBasedTraitletType):' | |||||
529 | elif klass is None: |
|
552 | elif klass is None: | |
530 | klass = default_value |
|
553 | klass = default_value | |
531 |
|
554 | |||
532 | if not inspect.isclass(klass): |
|
555 | if not (inspect.isclass(klass) or isinstance(klass, basestring)): | |
533 | raise TraitletError("A Type traitlet must specify a class.") |
|
556 | raise TraitletError("A Type traitlet must specify a class.") | |
534 |
|
557 | |||
535 | self.klass = klass |
|
558 | self.klass = klass | |
@@ -550,23 +573,38 b' class Type(ClassBasedTraitletType):' | |||||
550 |
|
573 | |||
551 | def info(self): |
|
574 | def info(self): | |
552 | """ Returns a description of the trait.""" |
|
575 | """ Returns a description of the trait.""" | |
|
576 | if isinstance(self.klass, basestring): | |||
|
577 | klass = self.klass | |||
|
578 | else: | |||
553 | klass = self.klass.__name__ |
|
579 | klass = self.klass.__name__ | |
554 | result = 'a subclass of ' + klass |
|
580 | result = 'a subclass of ' + klass | |
555 | if self._allow_none: |
|
581 | if self._allow_none: | |
556 | return result + ' or None' |
|
582 | return result + ' or None' | |
557 | return result |
|
583 | return result | |
558 |
|
584 | |||
|
585 | def instance_init(self, obj): | |||
|
586 | self._resolve_classes() | |||
|
587 | super(Type, self).instance_init(obj) | |||
|
588 | ||||
|
589 | def _resolve_classes(self): | |||
|
590 | if isinstance(self.klass, basestring): | |||
|
591 | self.klass = import_item(self.klass) | |||
|
592 | if isinstance(self.default_value, basestring): | |||
|
593 | self.default_value = import_item(self.default_value) | |||
|
594 | ||||
|
595 | def get_default_value(self): | |||
|
596 | return self.default_value | |||
|
597 | ||||
559 |
|
598 | |||
560 | class DefaultValueGenerator(object): |
|
599 | class DefaultValueGenerator(object): | |
561 | """A class for generating new default value instances.""" |
|
600 | """A class for generating new default value instances.""" | |
562 |
|
601 | |||
563 |
def __init__(self |
|
602 | def __init__(self, *args, **kw): | |
564 | self.klass = klass |
|
|||
565 | self.args = args |
|
603 | self.args = args | |
566 | self.kw = kw |
|
604 | self.kw = kw | |
567 |
|
605 | |||
568 | def generate(self): |
|
606 | def generate(self, klass): | |
569 |
return |
|
607 | return klass(*self.args, **self.kw) | |
570 |
|
608 | |||
571 |
|
609 | |||
572 | class Instance(ClassBasedTraitletType): |
|
610 | class Instance(ClassBasedTraitletType): | |
@@ -586,9 +624,9 b' class Instance(ClassBasedTraitletType):' | |||||
586 |
|
624 | |||
587 | Parameters |
|
625 | Parameters | |
588 | ---------- |
|
626 | ---------- | |
589 | klass : class |
|
627 | klass : class, str | |
590 |
The class that forms the basis for the traitlet. |
|
628 | The class that forms the basis for the traitlet. Class names | |
591 | and strings are not allowed. |
|
629 | can also be specified as strings, like 'foo.bar.Bar'. | |
592 | args : tuple |
|
630 | args : tuple | |
593 | Positional arguments for generating the default value. |
|
631 | Positional arguments for generating the default value. | |
594 | kw : dict |
|
632 | kw : dict | |
@@ -606,7 +644,7 b' class Instance(ClassBasedTraitletType):' | |||||
606 |
|
644 | |||
607 | self._allow_none = allow_none |
|
645 | self._allow_none = allow_none | |
608 |
|
646 | |||
609 | if (klass is None) or (not inspect.isclass(klass)): |
|
647 | if (klass is None) or (not (inspect.isclass(klass) or isinstance(klass, basestring))): | |
610 | raise TraitletError('The klass argument must be a class' |
|
648 | raise TraitletError('The klass argument must be a class' | |
611 | ' you gave: %r' % klass) |
|
649 | ' you gave: %r' % klass) | |
612 | self.klass = klass |
|
650 | self.klass = klass | |
@@ -627,7 +665,7 b' class Instance(ClassBasedTraitletType):' | |||||
627 | if not isinstance(args, tuple): |
|
665 | if not isinstance(args, tuple): | |
628 | raise TraitletError("The 'args' argument must be a tuple or None.") |
|
666 | raise TraitletError("The 'args' argument must be a tuple or None.") | |
629 |
|
667 | |||
630 |
default_value = DefaultValueGenerator( |
|
668 | default_value = DefaultValueGenerator(*args, **kw) | |
631 |
|
669 | |||
632 | super(Instance, self).__init__(default_value, **metadata) |
|
670 | super(Instance, self).__init__(default_value, **metadata) | |
633 |
|
671 | |||
@@ -643,6 +681,9 b' class Instance(ClassBasedTraitletType):' | |||||
643 | self.error(obj, value) |
|
681 | self.error(obj, value) | |
644 |
|
682 | |||
645 | def info(self): |
|
683 | def info(self): | |
|
684 | if isinstance(self.klass, basestring): | |||
|
685 | klass = self.klass | |||
|
686 | else: | |||
646 | klass = self.klass.__name__ |
|
687 | klass = self.klass.__name__ | |
647 | result = class_of(klass) |
|
688 | result = class_of(klass) | |
648 | if self._allow_none: |
|
689 | if self._allow_none: | |
@@ -650,6 +691,14 b' class Instance(ClassBasedTraitletType):' | |||||
650 |
|
691 | |||
651 | return result |
|
692 | return result | |
652 |
|
693 | |||
|
694 | def instance_init(self, obj): | |||
|
695 | self._resolve_classes() | |||
|
696 | super(Instance, self).instance_init(obj) | |||
|
697 | ||||
|
698 | def _resolve_classes(self): | |||
|
699 | if isinstance(self.klass, basestring): | |||
|
700 | self.klass = import_item(self.klass) | |||
|
701 | ||||
653 | def get_default_value(self): |
|
702 | def get_default_value(self): | |
654 | """Instantiate a default value instance. |
|
703 | """Instantiate a default value instance. | |
655 |
|
704 | |||
@@ -659,7 +708,7 b' class Instance(ClassBasedTraitletType):' | |||||
659 | """ |
|
708 | """ | |
660 | dv = self.default_value |
|
709 | dv = self.default_value | |
661 | if isinstance(dv, DefaultValueGenerator): |
|
710 | if isinstance(dv, DefaultValueGenerator): | |
662 | return dv.generate() |
|
711 | return dv.generate(self.klass) | |
663 | else: |
|
712 | else: | |
664 | return dv |
|
713 | return dv | |
665 |
|
714 |
General Comments 0
You need to be logged in to leave comments.
Login now