diff --git a/IPython/utils/tests/test_traitlets.py b/IPython/utils/tests/test_traitlets.py index 5751cbc..5f89be5 100644 --- a/IPython/utils/tests/test_traitlets.py +++ b/IPython/utils/tests/test_traitlets.py @@ -1326,11 +1326,11 @@ class TestEventful(TestCase): ### class ForwardDeclaredInstanceTrait(HasTraits): - value = ForwardDeclaredInstance(klass='ForwardDeclaredBar') + value = ForwardDeclaredInstance('ForwardDeclaredBar') class ForwardDeclaredTypeTrait(HasTraits): - value = ForwardDeclaredType(klass='ForwardDeclaredBar') + value = ForwardDeclaredType('ForwardDeclaredBar') class ForwardDeclaredInstanceListTrait(HasTraits): diff --git a/IPython/utils/traitlets.py b/IPython/utils/traitlets.py index 5939a05..d51a986 100644 --- a/IPython/utils/traitlets.py +++ b/IPython/utils/traitlets.py @@ -750,6 +750,12 @@ class HasTraits(py3compat.with_metaclass(MetaHasTraits, object)): class ClassBasedTraitType(TraitType): """A trait with error reporting for Type, Instance and This.""" + def _resolve_string(self, string): + """ + Resolve a string supplied for a type into an actual object. + """ + return import_item(string) + def error(self, obj, value): kind = type(value) if (not py3compat.PY3) and kind is InstanceType: @@ -842,9 +848,9 @@ class Type(ClassBasedTraitType): def _resolve_classes(self): if isinstance(self.klass, py3compat.string_types): - self.klass = import_item(self.klass) + self.klass = self._resolve_string(self.klass) if isinstance(self.default_value, py3compat.string_types): - self.default_value = import_item(self.default_value) + self.default_value = self._resolve_string(self.default_value) def get_default_value(self): return self.default_value @@ -951,7 +957,7 @@ class Instance(ClassBasedTraitType): def _resolve_classes(self): if isinstance(self.klass, py3compat.string_types): - self.klass = import_item(self.klass) + self.klass = self._resolve_string(self.klass) def get_default_value(self): """Instantiate a default value instance. @@ -971,17 +977,17 @@ class ForwardDeclaredMixin(object): """ Mixin for forward-declared versions of Instance and Type. """ - def _resolve_classes(self): + def _resolve_string(self, string): """ Find the specified class name by looking for it in the module in which our this_class attribute was defined. """ try: modname = self.this_class.__module__ - self.klass = import_item('.'.join([modname, self.klass])) + return import_item('.'.join([modname, string])) except AttributeError: raise ImportError( - "Module {} has no attribute {}".format(modname, self.klass) + "Module {} has no attribute {}".format(modname, string) ) @@ -1388,8 +1394,8 @@ class Container(Instance): def instance_init(self, obj): if isinstance(self._trait, TraitType): self._trait.this_class = self.this_class - if hasattr(self._trait, '_resolve_classes'): - self._trait._resolve_classes() + if hasattr(self._trait, 'instance_init'): + self._trait.instance_init(obj) super(Container, self).instance_init(obj)