##// END OF EJS Templates
Removed reduntant klass argument from Component.get_instances.
Brian Granger -
Show More
@@ -1,225 +1,221 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 A lightweight component system for IPython.
4 A lightweight component system for IPython.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez
9 * Fernando Perez
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 from copy import deepcopy
23 from copy import deepcopy
24 from weakref import WeakValueDictionary
24 from weakref import WeakValueDictionary
25
25
26 from IPython.utils.ipstruct import Struct
26 from IPython.utils.ipstruct import Struct
27 from IPython.utils.traitlets import (
27 from IPython.utils.traitlets import (
28 HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This
28 HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This
29 )
29 )
30
30
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Helper classes for Components
33 # Helper classes for Components
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36
36
37 class ComponentError(Exception):
37 class ComponentError(Exception):
38 pass
38 pass
39
39
40 class MetaComponentTracker(type):
40 class MetaComponentTracker(type):
41 """A metaclass that tracks instances of Components and its subclasses."""
41 """A metaclass that tracks instances of Components and its subclasses."""
42
42
43 def __init__(cls, name, bases, d):
43 def __init__(cls, name, bases, d):
44 super(MetaComponentTracker, cls).__init__(name, bases, d)
44 super(MetaComponentTracker, cls).__init__(name, bases, d)
45 cls.__instance_refs = WeakValueDictionary()
45 cls.__instance_refs = WeakValueDictionary()
46 cls.__numcreated = 0
46 cls.__numcreated = 0
47
47
48 def __call__(cls, *args, **kw):
48 def __call__(cls, *args, **kw):
49 """Called when *class* is called (instantiated)!!!
49 """Called when *class* is called (instantiated)!!!
50
50
51 When a Component or subclass is instantiated, this is called and
51 When a Component or subclass is instantiated, this is called and
52 the instance is saved in a WeakValueDictionary for tracking.
52 the instance is saved in a WeakValueDictionary for tracking.
53 """
53 """
54
54
55 instance = super(MetaComponentTracker, cls).__call__(*args, **kw)
55 instance = super(MetaComponentTracker, cls).__call__(*args, **kw)
56 for c in cls.__mro__:
56 for c in cls.__mro__:
57 if issubclass(cls, c) and issubclass(c, Component):
57 if issubclass(cls, c) and issubclass(c, Component):
58 c.__numcreated += 1
58 c.__numcreated += 1
59 c.__instance_refs[c.__numcreated] = instance
59 c.__instance_refs[c.__numcreated] = instance
60 return instance
60 return instance
61
61
62 def get_instances(cls, name=None, klass=None, root=None):
62 def get_instances(cls, name=None, root=None):
63 """Get all instances of cls and its subclasses.
63 """Get all instances of cls and its subclasses.
64
64
65 Parameters
65 Parameters
66 ----------
66 ----------
67 name : str
67 name : str
68 Limit to components with this name.
68 Limit to components with this name.
69 klass : class
70 Limit to components having isinstance(component, klass)
71 root : Component or subclass
69 root : Component or subclass
72 Limit to components having this root.
70 Limit to components having this root.
73 """
71 """
74 instances = cls.__instance_refs.values()
72 instances = cls.__instance_refs.values()
75 if name is not None:
73 if name is not None:
76 instances = [i for i in instances if i.name == name]
74 instances = [i for i in instances if i.name == name]
77 if klass is not None:
78 instances = [i for i in instances if isinstance(i, klass)]
79 if root is not None:
75 if root is not None:
80 instances = [i for i in instances if i.root == root]
76 instances = [i for i in instances if i.root == root]
81 return instances
77 return instances
82
78
83 def get_instances_by_condition(cls, call, name=None, klass=None, root=None):
79 def get_instances_by_condition(cls, call, name=None, root=None):
84 """Get all instances of cls, i such that call(i)==True.
80 """Get all instances of cls, i such that call(i)==True.
85
81
86 This also takes the ``name``, ``klass`` and ``root`` arguments of
82 This also takes the ``name`` and ``root`` arguments of
87 :meth:`get_instance`
83 :meth:`get_instance`
88 """
84 """
89 return [i for i in cls.get_instances(name,klass,root) if call(i)]
85 return [i for i in cls.get_instances(name, root) if call(i)]
90
86
91
87
92 class ComponentNameGenerator(object):
88 class ComponentNameGenerator(object):
93 """A Singleton to generate unique component names."""
89 """A Singleton to generate unique component names."""
94
90
95 def __init__(self, prefix):
91 def __init__(self, prefix):
96 self.prefix = prefix
92 self.prefix = prefix
97 self.i = 0
93 self.i = 0
98
94
99 def __call__(self):
95 def __call__(self):
100 count = self.i
96 count = self.i
101 self.i += 1
97 self.i += 1
102 return "%s%s" % (self.prefix, count)
98 return "%s%s" % (self.prefix, count)
103
99
104
100
105 ComponentNameGenerator = ComponentNameGenerator('ipython.component')
101 ComponentNameGenerator = ComponentNameGenerator('ipython.component')
106
102
107
103
108 class MetaComponent(MetaHasTraitlets, MetaComponentTracker):
104 class MetaComponent(MetaHasTraitlets, MetaComponentTracker):
109 pass
105 pass
110
106
111
107
112 #-----------------------------------------------------------------------------
108 #-----------------------------------------------------------------------------
113 # Component implementation
109 # Component implementation
114 #-----------------------------------------------------------------------------
110 #-----------------------------------------------------------------------------
115
111
116
112
117 class Component(HasTraitlets):
113 class Component(HasTraitlets):
118
114
119 __metaclass__ = MetaComponent
115 __metaclass__ = MetaComponent
120
116
121 # Traitlets are fun!
117 # Traitlets are fun!
122 config = Instance(Struct,(),{})
118 config = Instance(Struct,(),{})
123 parent = This()
119 parent = This()
124 root = This()
120 root = This()
125
121
126 def __init__(self, parent, name=None, config=None):
122 def __init__(self, parent, name=None, config=None):
127 """Create a component given a parent and possibly and name and config.
123 """Create a component given a parent and possibly and name and config.
128
124
129 Parameters
125 Parameters
130 ----------
126 ----------
131 parent : Component subclass
127 parent : Component subclass
132 The parent in the component graph. The parent is used
128 The parent in the component graph. The parent is used
133 to get the root of the component graph.
129 to get the root of the component graph.
134 name : str
130 name : str
135 The unique name of the component. If empty, then a unique
131 The unique name of the component. If empty, then a unique
136 one will be autogenerated.
132 one will be autogenerated.
137 config : Struct
133 config : Struct
138 If this is empty, self.config = parent.config, otherwise
134 If this is empty, self.config = parent.config, otherwise
139 self.config = config and root.config is ignored. This argument
135 self.config = config and root.config is ignored. This argument
140 should only be used to *override* the automatic inheritance of
136 should only be used to *override* the automatic inheritance of
141 parent.config. If a caller wants to modify parent.config
137 parent.config. If a caller wants to modify parent.config
142 (not override), the caller should make a copy and change
138 (not override), the caller should make a copy and change
143 attributes and then pass the copy to this argument.
139 attributes and then pass the copy to this argument.
144
140
145 Notes
141 Notes
146 -----
142 -----
147 Subclasses of Component must call the :meth:`__init__` method of
143 Subclasses of Component must call the :meth:`__init__` method of
148 :class:`Component` *before* doing anything else and using
144 :class:`Component` *before* doing anything else and using
149 :func:`super`::
145 :func:`super`::
150
146
151 class MyComponent(Component):
147 class MyComponent(Component):
152 def __init__(self, parent, name=None, config=None):
148 def __init__(self, parent, name=None, config=None):
153 super(MyComponent, self).__init__(parent, name, config)
149 super(MyComponent, self).__init__(parent, name, config)
154 # Then any other code you need to finish initialization.
150 # Then any other code you need to finish initialization.
155
151
156 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
152 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
157 attributes are handled properly.
153 attributes are handled properly.
158 """
154 """
159 super(Component, self).__init__()
155 super(Component, self).__init__()
160 self._children = []
156 self._children = []
161 if name is None:
157 if name is None:
162 self.name = ComponentNameGenerator()
158 self.name = ComponentNameGenerator()
163 else:
159 else:
164 self.name = name
160 self.name = name
165 self.root = self # This is the default, it is set when parent is set
161 self.root = self # This is the default, it is set when parent is set
166 self.parent = parent
162 self.parent = parent
167 if config is not None:
163 if config is not None:
168 self.config = deepcopy(config)
164 self.config = deepcopy(config)
169 else:
165 else:
170 if self.parent is not None:
166 if self.parent is not None:
171 self.config = deepcopy(self.parent.config)
167 self.config = deepcopy(self.parent.config)
172
168
173 #-------------------------------------------------------------------------
169 #-------------------------------------------------------------------------
174 # Static traitlet notifiations
170 # Static traitlet notifiations
175 #-------------------------------------------------------------------------
171 #-------------------------------------------------------------------------
176
172
177 def _parent_changed(self, name, old, new):
173 def _parent_changed(self, name, old, new):
178 if old is not None:
174 if old is not None:
179 old._remove_child(self)
175 old._remove_child(self)
180 if new is not None:
176 if new is not None:
181 new._add_child(self)
177 new._add_child(self)
182
178
183 if new is None:
179 if new is None:
184 self.root = self
180 self.root = self
185 else:
181 else:
186 self.root = new.root
182 self.root = new.root
187
183
188 def _root_changed(self, name, old, new):
184 def _root_changed(self, name, old, new):
189 if self.parent is None:
185 if self.parent is None:
190 if not (new is self):
186 if not (new is self):
191 raise ComponentError("Root not self, but parent is None.")
187 raise ComponentError("Root not self, but parent is None.")
192 else:
188 else:
193 if not self.parent.root is new:
189 if not self.parent.root is new:
194 raise ComponentError("Error in setting the root attribute: "
190 raise ComponentError("Error in setting the root attribute: "
195 "root != parent.root")
191 "root != parent.root")
196
192
197 def _config_changed(self, name, old, new):
193 def _config_changed(self, name, old, new):
198 # Get all traitlets with a config_key metadata entry
194 # Get all traitlets with a config_key metadata entry
199 traitlets = self.traitlets('config_key')
195 traitlets = self.traitlets('config_key')
200 for k, v in traitlets.items():
196 for k, v in traitlets.items():
201 try:
197 try:
202 config_value = new[v.get_metadata('config_key')]
198 config_value = new[v.get_metadata('config_key')]
203 except KeyError:
199 except KeyError:
204 pass
200 pass
205 else:
201 else:
206 setattr(self, k, config_value)
202 setattr(self, k, config_value)
207
203
208 @property
204 @property
209 def children(self):
205 def children(self):
210 """A list of all my child components."""
206 """A list of all my child components."""
211 return self._children
207 return self._children
212
208
213 def _remove_child(self, child):
209 def _remove_child(self, child):
214 """A private method for removing children components."""
210 """A private method for removing children components."""
215 if child in self._children:
211 if child in self._children:
216 index = self._children.index(child)
212 index = self._children.index(child)
217 del self._children[index]
213 del self._children[index]
218
214
219 def _add_child(self, child):
215 def _add_child(self, child):
220 """A private method for adding children components."""
216 """A private method for adding children components."""
221 if child not in self._children:
217 if child not in self._children:
222 self._children.append(child)
218 self._children.append(child)
223
219
224 def __repr__(self):
220 def __repr__(self):
225 return "<Component('%s')>" % self.name
221 return "<Component('%s')>" % self.name
@@ -1,194 +1,194 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Tests for IPython.core.component
4 Tests for IPython.core.component
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez (design help)
9 * Fernando Perez (design help)
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 from unittest import TestCase
23 from unittest import TestCase
24
24
25 from IPython.core.component import Component, ComponentError
25 from IPython.core.component import Component, ComponentError
26 from IPython.utils.traitlets import (
26 from IPython.utils.traitlets import (
27 TraitletError, Int, Float, Str
27 TraitletError, Int, Float, Str
28 )
28 )
29 from IPython.utils.ipstruct import Struct
29 from IPython.utils.ipstruct import Struct
30
30
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Test cases
33 # Test cases
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36
36
37 class TestComponentMeta(TestCase):
37 class TestComponentMeta(TestCase):
38
38
39 def test_get_instances(self):
39 def test_get_instances(self):
40 class BaseComponent(Component):
40 class BaseComponent(Component):
41 pass
41 pass
42 c1 = BaseComponent(None)
42 c1 = BaseComponent(None)
43 c2 = BaseComponent(c1)
43 c2 = BaseComponent(c1)
44 self.assertEquals(BaseComponent.get_instances(),[c1,c2])
44 self.assertEquals(BaseComponent.get_instances(),[c1,c2])
45
45
46 def test_get_instances_subclass(self):
46 def test_get_instances_subclass(self):
47 class MyComponent(Component):
47 class MyComponent(Component):
48 pass
48 pass
49 class MyOtherComponent(MyComponent):
49 class MyOtherComponent(MyComponent):
50 pass
50 pass
51 c1 = MyComponent(None)
51 c1 = MyComponent(None)
52 c2 = MyOtherComponent(c1)
52 c2 = MyOtherComponent(c1)
53 c3 = MyOtherComponent(c2)
53 c3 = MyOtherComponent(c2)
54 self.assertEquals(MyComponent.get_instances(), [c1, c2, c3])
54 self.assertEquals(MyComponent.get_instances(), [c1, c2, c3])
55 self.assertEquals(MyComponent.get_instances(klass=MyOtherComponent), [c2, c3])
55 self.assertEquals(MyOtherComponent.get_instances(), [c2, c3])
56
56
57 def test_get_instances_root(self):
57 def test_get_instances_root(self):
58 class MyComponent(Component):
58 class MyComponent(Component):
59 pass
59 pass
60 class MyOtherComponent(MyComponent):
60 class MyOtherComponent(MyComponent):
61 pass
61 pass
62 c1 = MyComponent(None)
62 c1 = MyComponent(None)
63 c2 = MyOtherComponent(c1)
63 c2 = MyOtherComponent(c1)
64 c3 = MyOtherComponent(c2)
64 c3 = MyOtherComponent(c2)
65 c4 = MyComponent(None)
65 c4 = MyComponent(None)
66 c5 = MyComponent(c4)
66 c5 = MyComponent(c4)
67 self.assertEquals(MyComponent.get_instances(root=c1), [c1, c2, c3])
67 self.assertEquals(MyComponent.get_instances(root=c1), [c1, c2, c3])
68 self.assertEquals(MyComponent.get_instances(root=c4), [c4, c5])
68 self.assertEquals(MyComponent.get_instances(root=c4), [c4, c5])
69
69
70
70
71 class TestComponent(TestCase):
71 class TestComponent(TestCase):
72
72
73 def test_parent_child(self):
73 def test_parent_child(self):
74 c1 = Component(None)
74 c1 = Component(None)
75 c2 = Component(c1)
75 c2 = Component(c1)
76 c3 = Component(c1)
76 c3 = Component(c1)
77 c4 = Component(c3)
77 c4 = Component(c3)
78 self.assertEquals(c1.parent, None)
78 self.assertEquals(c1.parent, None)
79 self.assertEquals(c2.parent, c1)
79 self.assertEquals(c2.parent, c1)
80 self.assertEquals(c3.parent, c1)
80 self.assertEquals(c3.parent, c1)
81 self.assertEquals(c4.parent, c3)
81 self.assertEquals(c4.parent, c3)
82 self.assertEquals(c1.children, [c2, c3])
82 self.assertEquals(c1.children, [c2, c3])
83 self.assertEquals(c2.children, [])
83 self.assertEquals(c2.children, [])
84 self.assertEquals(c3.children, [c4])
84 self.assertEquals(c3.children, [c4])
85 self.assertEquals(c4.children, [])
85 self.assertEquals(c4.children, [])
86
86
87 def test_root(self):
87 def test_root(self):
88 c1 = Component(None)
88 c1 = Component(None)
89 c2 = Component(c1)
89 c2 = Component(c1)
90 c3 = Component(c1)
90 c3 = Component(c1)
91 c4 = Component(c3)
91 c4 = Component(c3)
92 self.assertEquals(c1.root, c1.root)
92 self.assertEquals(c1.root, c1.root)
93 self.assertEquals(c2.root, c1)
93 self.assertEquals(c2.root, c1)
94 self.assertEquals(c3.root, c1)
94 self.assertEquals(c3.root, c1)
95 self.assertEquals(c4.root, c1)
95 self.assertEquals(c4.root, c1)
96
96
97 def test_change_parent(self):
97 def test_change_parent(self):
98 c1 = Component(None)
98 c1 = Component(None)
99 c2 = Component(None)
99 c2 = Component(None)
100 c3 = Component(c1)
100 c3 = Component(c1)
101 self.assertEquals(c3.root, c1)
101 self.assertEquals(c3.root, c1)
102 self.assertEquals(c3.parent, c1)
102 self.assertEquals(c3.parent, c1)
103 self.assertEquals(c1.children,[c3])
103 self.assertEquals(c1.children,[c3])
104 c3.parent = c2
104 c3.parent = c2
105 self.assertEquals(c3.root, c2)
105 self.assertEquals(c3.root, c2)
106 self.assertEquals(c3.parent, c2)
106 self.assertEquals(c3.parent, c2)
107 self.assertEquals(c2.children,[c3])
107 self.assertEquals(c2.children,[c3])
108 self.assertEquals(c1.children,[])
108 self.assertEquals(c1.children,[])
109
109
110 def test_subclass_parent(self):
110 def test_subclass_parent(self):
111 c1 = Component(None)
111 c1 = Component(None)
112 self.assertRaises(TraitletError, setattr, c1, 'parent', 10)
112 self.assertRaises(TraitletError, setattr, c1, 'parent', 10)
113
113
114 class MyComponent(Component):
114 class MyComponent(Component):
115 pass
115 pass
116 c1 = Component(None)
116 c1 = Component(None)
117 c2 = MyComponent(c1)
117 c2 = MyComponent(c1)
118 self.assertEquals(MyComponent.parent.this_class, Component)
118 self.assertEquals(MyComponent.parent.this_class, Component)
119 self.assertEquals(c2.parent, c1)
119 self.assertEquals(c2.parent, c1)
120
120
121 def test_bad_root(self):
121 def test_bad_root(self):
122 c1 = Component(None)
122 c1 = Component(None)
123 c2 = Component(None)
123 c2 = Component(None)
124 c3 = Component(None)
124 c3 = Component(None)
125 self.assertRaises(ComponentError, setattr, c1, 'root', c2)
125 self.assertRaises(ComponentError, setattr, c1, 'root', c2)
126 c1.parent = c2
126 c1.parent = c2
127 self.assertEquals(c1.root, c2)
127 self.assertEquals(c1.root, c2)
128 self.assertRaises(ComponentError, setattr, c1, 'root', c3)
128 self.assertRaises(ComponentError, setattr, c1, 'root', c3)
129
129
130
130
131 class TestComponentConfig(TestCase):
131 class TestComponentConfig(TestCase):
132
132
133 def test_default(self):
133 def test_default(self):
134 c1 = Component(None)
134 c1 = Component(None)
135 c2 = Component(c1)
135 c2 = Component(c1)
136 c3 = Component(c2)
136 c3 = Component(c2)
137 self.assertEquals(c1.config, c2.config)
137 self.assertEquals(c1.config, c2.config)
138 self.assertEquals(c2.config, c3.config)
138 self.assertEquals(c2.config, c3.config)
139
139
140 def test_custom(self):
140 def test_custom(self):
141 config = Struct()
141 config = Struct()
142 config.FOO = 'foo'
142 config.FOO = 'foo'
143 config.BAR = 'bar'
143 config.BAR = 'bar'
144 c1 = Component(None, config=config)
144 c1 = Component(None, config=config)
145 c2 = Component(c1)
145 c2 = Component(c1)
146 c3 = Component(c2)
146 c3 = Component(c2)
147 self.assertEquals(c1.config, config)
147 self.assertEquals(c1.config, config)
148 self.assertEquals(c2.config, config)
148 self.assertEquals(c2.config, config)
149 self.assertEquals(c3.config, config)
149 self.assertEquals(c3.config, config)
150 # Test that we always make copies
150 # Test that we always make copies
151 self.assert_(c1.config is not config)
151 self.assert_(c1.config is not config)
152 self.assert_(c2.config is not config)
152 self.assert_(c2.config is not config)
153 self.assert_(c3.config is not config)
153 self.assert_(c3.config is not config)
154 self.assert_(c1.config is not c2.config)
154 self.assert_(c1.config is not c2.config)
155 self.assert_(c2.config is not c3.config)
155 self.assert_(c2.config is not c3.config)
156
156
157 def test_inheritance(self):
157 def test_inheritance(self):
158 class MyComponent(Component):
158 class MyComponent(Component):
159 a = Int(1, config_key='A')
159 a = Int(1, config_key='A')
160 b = Float(1.0, config_key='B')
160 b = Float(1.0, config_key='B')
161 c = Str('no config')
161 c = Str('no config')
162 config = Struct()
162 config = Struct()
163 config.A = 2
163 config.A = 2
164 config.B = 2.0
164 config.B = 2.0
165 c1 = MyComponent(None, config=config)
165 c1 = MyComponent(None, config=config)
166 c2 = MyComponent(c1)
166 c2 = MyComponent(c1)
167 self.assertEquals(c1.a, config.A)
167 self.assertEquals(c1.a, config.A)
168 self.assertEquals(c1.b, config.B)
168 self.assertEquals(c1.b, config.B)
169 self.assertEquals(c2.a, config.A)
169 self.assertEquals(c2.a, config.A)
170 self.assertEquals(c2.b, config.B)
170 self.assertEquals(c2.b, config.B)
171 c4 = MyComponent(c2, config=Struct())
171 c4 = MyComponent(c2, config=Struct())
172 self.assertEquals(c4.a, 1)
172 self.assertEquals(c4.a, 1)
173 self.assertEquals(c4.b, 1.0)
173 self.assertEquals(c4.b, 1.0)
174
174
175 class TestComponentName(TestCase):
175 class TestComponentName(TestCase):
176
176
177 def test_default(self):
177 def test_default(self):
178 class MyComponent(Component):
178 class MyComponent(Component):
179 pass
179 pass
180 c1 = Component(None)
180 c1 = Component(None)
181 c2 = MyComponent(None)
181 c2 = MyComponent(None)
182 c3 = Component(c2)
182 c3 = Component(c2)
183 self.assertNotEquals(c1.name, c2.name)
183 self.assertNotEquals(c1.name, c2.name)
184 self.assertNotEquals(c1.name, c3.name)
184 self.assertNotEquals(c1.name, c3.name)
185
185
186 def test_manual(self):
186 def test_manual(self):
187 class MyComponent(Component):
187 class MyComponent(Component):
188 pass
188 pass
189 c1 = Component(None, name='foo')
189 c1 = Component(None, name='foo')
190 c2 = MyComponent(None, name='bar')
190 c2 = MyComponent(None, name='bar')
191 c3 = Component(c2, name='bah')
191 c3 = Component(c2, name='bah')
192 self.assertEquals(c1.name, 'foo')
192 self.assertEquals(c1.name, 'foo')
193 self.assertEquals(c2.name, 'bar')
193 self.assertEquals(c2.name, 'bar')
194 self.assertEquals(c3.name, 'bah')
194 self.assertEquals(c3.name, 'bah')
General Comments 0
You need to be logged in to leave comments. Login now