Show More
@@ -0,0 +1,186 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | # encoding: utf-8 | |
|
3 | """A factory for creating configuration objects. | |
|
4 | """ | |
|
5 | ||
|
6 | #----------------------------------------------------------------------------- | |
|
7 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
8 | # | |
|
9 | # Distributed under the terms of the BSD License. The full license is in | |
|
10 | # the file COPYING, distributed as part of this software. | |
|
11 | #----------------------------------------------------------------------------- | |
|
12 | ||
|
13 | #----------------------------------------------------------------------------- | |
|
14 | # Imports | |
|
15 | #----------------------------------------------------------------------------- | |
|
16 | ||
|
17 | import os | |
|
18 | ||
|
19 | from IPython.utils.ipstruct import Struct | |
|
20 | ||
|
21 | #----------------------------------------------------------------------------- | |
|
22 | # Code | |
|
23 | #----------------------------------------------------------------------------- | |
|
24 | ||
|
25 | ||
|
26 | class ConfigLoaderError(Exception): | |
|
27 | pass | |
|
28 | ||
|
29 | ||
|
30 | class ConfigLoader(object): | |
|
31 | """A object for loading configurations from just about anywhere. | |
|
32 | ||
|
33 | The resulting configuration is packaged as a :class:`Struct`. | |
|
34 | """ | |
|
35 | ||
|
36 | def __init__(self): | |
|
37 | """A base class for config loaders. | |
|
38 | ||
|
39 | Examples | |
|
40 | -------- | |
|
41 | ||
|
42 | >>> cl = ConfigLoader() | |
|
43 | >>> config = cl.load_config() | |
|
44 | >>> config | |
|
45 | {} | |
|
46 | """ | |
|
47 | self.clear() | |
|
48 | ||
|
49 | def clear(self): | |
|
50 | self.config = Struct() | |
|
51 | ||
|
52 | def load_config(self): | |
|
53 | """Load a config from somewhere, return a Struct. | |
|
54 | ||
|
55 | Usually, this will cause self.config to be set and then returned. | |
|
56 | """ | |
|
57 | return self.config | |
|
58 | ||
|
59 | ||
|
60 | class FileConfigLoader(ConfigLoader): | |
|
61 | """A config loader for pure python files. | |
|
62 | ||
|
63 | This calls execfile on a plain python file and looks for attributes | |
|
64 | that are all caps. These attribute are added to the config Struct. | |
|
65 | """ | |
|
66 | ||
|
67 | def __init__(self, filename, path='.'): | |
|
68 | """Build a config loader for a filename and path. | |
|
69 | ||
|
70 | Parameters | |
|
71 | ---------- | |
|
72 | filename : str | |
|
73 | The file name of the config file. | |
|
74 | path : str, list, tuple | |
|
75 | The path to search for the config file on, or a sequence of | |
|
76 | paths to try in order | |
|
77 | ||
|
78 | Examples | |
|
79 | -------- | |
|
80 | ||
|
81 | ||
|
82 | """ | |
|
83 | self.filename = filename | |
|
84 | self.path = path | |
|
85 | self.full_filename = '' | |
|
86 | self.data = None | |
|
87 | ConfigLoader.__init__(self) | |
|
88 | ||
|
89 | def find_file(self): | |
|
90 | """Implement file finding logic here.""" | |
|
91 | self.full_filename = self.filename | |
|
92 | ||
|
93 | def read_file_as_dict(self): | |
|
94 | if not os.path.isfile(self.full_filename): | |
|
95 | raise IOError("config file does not exist: %r" % self.fullfilename) | |
|
96 | self.data = {} | |
|
97 | execfile(self.full_filename, self.data) | |
|
98 | ||
|
99 | def convert_to_struct(self): | |
|
100 | if self.data is None: | |
|
101 | ConfigLoaderError('self.data does not exist') | |
|
102 | for k, v in self.data.iteritems(): | |
|
103 | if k == k.upper(): | |
|
104 | self.config[k] = v | |
|
105 | ||
|
106 | def load_config(self): | |
|
107 | self.find_file() | |
|
108 | self.read_file_as_dict() | |
|
109 | self.convert_to_struct() | |
|
110 | return self.config | |
|
111 | ||
|
112 | class PyConfigLoader(object): | |
|
113 | pass | |
|
114 | ||
|
115 | ||
|
116 | class DefaultFileConfigLoader(object): | |
|
117 | ||
|
118 | def __init__(self, filename, install_location): | |
|
119 | pass | |
|
120 | ||
|
121 | def load_config(self): | |
|
122 | pass | |
|
123 | ||
|
124 | def install(self, force=False): | |
|
125 | pass | |
|
126 | ||
|
127 | ||
|
128 | class CommandLineConfigLoader(ConfigLoader): | |
|
129 | ||
|
130 | def __init__(self): | |
|
131 | self.parser = None | |
|
132 | self.parsed_data = None | |
|
133 | self.clear() | |
|
134 | ||
|
135 | ||
|
136 | def clear(self): | |
|
137 | self.config = Struct() | |
|
138 | ||
|
139 | def load_config(self, args=None): | |
|
140 | self.create_parser() | |
|
141 | self.parse_args(args) | |
|
142 | self.convert_to_struct() | |
|
143 | return self.config | |
|
144 | ||
|
145 | def create_parser(self): | |
|
146 | """Create self.parser""" | |
|
147 | ||
|
148 | def parse_args(self, args=None): | |
|
149 | """self.parser->self.parsed_data""" | |
|
150 | if self.parser is None: | |
|
151 | raise ConfigLoaderError('self.parser does not exist') | |
|
152 | if args is None: | |
|
153 | self.parsed_data = parser.parse_args() | |
|
154 | else: | |
|
155 | self.parse_data = parser.parse_args(args) | |
|
156 | ||
|
157 | def convert_to_struct(self): | |
|
158 | """self.parsed_data->self.config""" | |
|
159 | if self.parsed_data is None: | |
|
160 | raise ConfigLoaderError('self.parsed_data does not exist') | |
|
161 | self.config = Struct(vars(self.parsed_data)) | |
|
162 | ||
|
163 | ||
|
164 | class ArgParseConfigLoader(CommandLineConfigLoader): | |
|
165 | ||
|
166 | # arguments = [(('-f','--file'),dict(type=str,dest='file'))] | |
|
167 | arguments = [] | |
|
168 | ||
|
169 | def __init__(self, *args, **kw): | |
|
170 | """Create a config loader for use with argparse. | |
|
171 | ||
|
172 | The args and kwargs arguments here are passed onto the constructor | |
|
173 | of :class:`argparse.ArgumentParser`. | |
|
174 | """ | |
|
175 | self.args = args | |
|
176 | self.kw = kw | |
|
177 | CommandLineConfigLoader.__init__(self) | |
|
178 | ||
|
179 | def create_parser(self): | |
|
180 | self.parser = argparse.ArgumentParser(*self.args, **self.kw) | |
|
181 | self.add_arguments() | |
|
182 | ||
|
183 | def add_arguments(self): | |
|
184 | for argument in self.arguments: | |
|
185 | self.parser.add_argument(*argument[0],**argument[1]) | |
|
186 |
@@ -0,0 +1,184 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | # encoding: utf-8 | |
|
3 | """ | |
|
4 | A lightweight component system for IPython. | |
|
5 | ||
|
6 | Authors: | |
|
7 | ||
|
8 | * Brian Granger | |
|
9 | * Fernando Perez | |
|
10 | """ | |
|
11 | ||
|
12 | #----------------------------------------------------------------------------- | |
|
13 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
14 | # | |
|
15 | # Distributed under the terms of the BSD License. The full license is in | |
|
16 | # the file COPYING, distributed as part of this software. | |
|
17 | #----------------------------------------------------------------------------- | |
|
18 | ||
|
19 | #----------------------------------------------------------------------------- | |
|
20 | # Imports | |
|
21 | #----------------------------------------------------------------------------- | |
|
22 | ||
|
23 | ||
|
24 | from weakref import WeakValueDictionary | |
|
25 | ||
|
26 | from IPython.utils.traitlets import ( | |
|
27 | HasTraitlets, TraitletError, MetaHasTraitlets, | |
|
28 | Int, Float, Str, Bool, Unicode | |
|
29 | ) | |
|
30 | ||
|
31 | ||
|
32 | #----------------------------------------------------------------------------- | |
|
33 | # Helper classes for Components | |
|
34 | #----------------------------------------------------------------------------- | |
|
35 | ||
|
36 | ||
|
37 | class Config(object): | |
|
38 | pass | |
|
39 | ||
|
40 | ||
|
41 | class MetaComponentTracker(type): | |
|
42 | """A metaclass that tracks instances of Components and its subclasses.""" | |
|
43 | ||
|
44 | def __init__(cls, name, bases, d): | |
|
45 | super(MetaComponentTracker, cls).__init__(name, bases, d) | |
|
46 | cls.__instance_refs = WeakValueDictionary() | |
|
47 | cls.__numcreated = 0 | |
|
48 | ||
|
49 | def __call__(cls, *args, **kw): | |
|
50 | """Called when class is called (instantiated)!!! | |
|
51 | ||
|
52 | Then a Component or subclass is instantiated, this is called and | |
|
53 | the instance is saved in a WeakValueDictionary for tracking. | |
|
54 | """ | |
|
55 | ||
|
56 | instance = super(MetaComponentTracker, cls).__call__(*args, **kw) | |
|
57 | for c in cls.__mro__: | |
|
58 | if issubclass(cls, c) and issubclass(c, Component): | |
|
59 | c.__numcreated += 1 | |
|
60 | c.__instance_refs[c.__numcreated] = instance | |
|
61 | return instance | |
|
62 | ||
|
63 | def get_instances(cls): | |
|
64 | """Get all instances of cls and its subclasses.""" | |
|
65 | return cls.__instance_refs.values() | |
|
66 | ||
|
67 | def get_instances_by_name(cls, name): | |
|
68 | """Get all instances of cls and its subclasses by name.""" | |
|
69 | return [i for i in cls.get_instances() if i.name == name] | |
|
70 | ||
|
71 | def get_instances_by_subclass(cls, thisclass): | |
|
72 | """Get all instances of cls that are instances of thisclass. | |
|
73 | ||
|
74 | This includes all instances of subclasses of thisclass. | |
|
75 | """ | |
|
76 | return [i for i in cls.get_instances() if isinstance(i, thisclass)] | |
|
77 | ||
|
78 | def get_instances_by_class(cls, thisclass): | |
|
79 | """Get all instances of cls that are instances of thisclass. | |
|
80 | ||
|
81 | This exclused instances of thisclass subclasses. | |
|
82 | """ | |
|
83 | ||
|
84 | return [i for i in cls.get_instances() if type(i) is thisclass] | |
|
85 | ||
|
86 | def get_instances_by_condition(cls, call): | |
|
87 | """Get all instances of cls, i such that call(i)==True.""" | |
|
88 | return [i for i in cls.get_instances() if call(i)] | |
|
89 | ||
|
90 | ||
|
91 | class ComponentNameGenerator(object): | |
|
92 | """A Singleton to generate unique component names.""" | |
|
93 | ||
|
94 | def __init__(self, prefix): | |
|
95 | self.prefix = prefix | |
|
96 | self.i = 0 | |
|
97 | ||
|
98 | def __call__(self): | |
|
99 | count = self.i | |
|
100 | self.i += 1 | |
|
101 | return "%s%s" % (self.prefix, count) | |
|
102 | ||
|
103 | ||
|
104 | ComponentNameGenerator = ComponentNameGenerator('ipython.component') | |
|
105 | ||
|
106 | ||
|
107 | class MetaComponent(MetaHasTraitlets, MetaComponentTracker): | |
|
108 | pass | |
|
109 | ||
|
110 | ||
|
111 | #----------------------------------------------------------------------------- | |
|
112 | # Component implementation | |
|
113 | #----------------------------------------------------------------------------- | |
|
114 | ||
|
115 | ||
|
116 | class Component(HasTraitlets): | |
|
117 | ||
|
118 | __metaclass__ = MetaComponent | |
|
119 | ||
|
120 | config = Config() | |
|
121 | ||
|
122 | def __init__(self, parent, name=None, config=None): | |
|
123 | """Create a component given a parent. | |
|
124 | ||
|
125 | Parameters | |
|
126 | ---------- | |
|
127 | parent : Component subclass | |
|
128 | The parent in the component graph. The parent is used | |
|
129 | to get the root of the component graph. | |
|
130 | name : str | |
|
131 | The unique name of the component. If empty, then a unique | |
|
132 | one will be autogenerated. | |
|
133 | config : Config | |
|
134 | If this is empty, self.config = root.config, otherwise | |
|
135 | self.config = config and root.config is ignored. This argument | |
|
136 | should be used to pass the config to the root. Otherwise, it | |
|
137 | can be used to *override* the inheritance of root.config. If a | |
|
138 | caller wants to modify root.config (not override), the caller | |
|
139 | should make a copy and change attributes and then pass the copy | |
|
140 | to this argument. We might think about changing this behavior. | |
|
141 | """ | |
|
142 | super(Component, self).__init__() | |
|
143 | if name is None: | |
|
144 | self._name = ComponentNameGenerator() | |
|
145 | else: | |
|
146 | self._name = name | |
|
147 | self.parent = parent # this uses the property and handles None | |
|
148 | if config is not None: | |
|
149 | self.config = config | |
|
150 | else: | |
|
151 | if self.parent is not None: | |
|
152 | self.config = self.parent.config | |
|
153 | ||
|
154 | #------------------------------------------------------------------------- | |
|
155 | # Properties | |
|
156 | #------------------------------------------------------------------------- | |
|
157 | ||
|
158 | def _set_name(self, name): | |
|
159 | # This should use the ComponentNameGenerator to test for uniqueness | |
|
160 | self._name = name | |
|
161 | ||
|
162 | def _get_name(self): | |
|
163 | return self._name | |
|
164 | ||
|
165 | name = property(_get_name, _set_name) | |
|
166 | ||
|
167 | def _set_parent(self, parent): | |
|
168 | if parent is None: | |
|
169 | self._parent = None | |
|
170 | self._root = self | |
|
171 | else: | |
|
172 | assert isinstance(parent, Component), 'parent must be a component' | |
|
173 | self._parent = parent | |
|
174 | self._root = parent.root | |
|
175 | ||
|
176 | def _get_parent(self): | |
|
177 | return self._parent | |
|
178 | ||
|
179 | parent = property(_get_parent, _set_parent) | |
|
180 | ||
|
181 | @property | |
|
182 | def root(self): | |
|
183 | return self._root | |
|
184 |
@@ -0,0 +1,324 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | # encoding: utf-8 | |
|
3 | """ | |
|
4 | A lightweight Traits like module. | |
|
5 | ||
|
6 | Authors: | |
|
7 | ||
|
8 | * Brian Granger | |
|
9 | * Enthought, Inc. Some of the code in this file comes from enthought.traits | |
|
10 | and is licensed under the BSD license. Also, many of the ideas also come | |
|
11 | from enthought.traits even though our implementation is very different. | |
|
12 | """ | |
|
13 | ||
|
14 | #----------------------------------------------------------------------------- | |
|
15 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
16 | # | |
|
17 | # Distributed under the terms of the BSD License. The full license is in | |
|
18 | # the file COPYING, distributed as part of this software. | |
|
19 | #----------------------------------------------------------------------------- | |
|
20 | ||
|
21 | #----------------------------------------------------------------------------- | |
|
22 | # Imports | |
|
23 | #----------------------------------------------------------------------------- | |
|
24 | ||
|
25 | import inspect | |
|
26 | import types | |
|
27 | from types import InstanceType | |
|
28 | ||
|
29 | #----------------------------------------------------------------------------- | |
|
30 | # Basic classes | |
|
31 | #----------------------------------------------------------------------------- | |
|
32 | ||
|
33 | ||
|
34 | class NoDefaultSpecified ( object ): pass | |
|
35 | NoDefaultSpecified = NoDefaultSpecified() | |
|
36 | ||
|
37 | ||
|
38 | class Undefined ( object ): pass | |
|
39 | Undefined = Undefined() | |
|
40 | ||
|
41 | ||
|
42 | class TraitletError(Exception): | |
|
43 | pass | |
|
44 | ||
|
45 | ||
|
46 | #----------------------------------------------------------------------------- | |
|
47 | # Utilities | |
|
48 | #----------------------------------------------------------------------------- | |
|
49 | ||
|
50 | ||
|
51 | def class_of ( object ): | |
|
52 | """ Returns a string containing the class name of an object with the | |
|
53 | correct indefinite article ('a' or 'an') preceding it (e.g., 'an Image', | |
|
54 | 'a PlotValue'). | |
|
55 | """ | |
|
56 | if isinstance( object, basestring ): | |
|
57 | return add_article( object ) | |
|
58 | ||
|
59 | return add_article( object.__class__.__name__ ) | |
|
60 | ||
|
61 | ||
|
62 | def add_article ( name ): | |
|
63 | """ Returns a string containing the correct indefinite article ('a' or 'an') | |
|
64 | prefixed to the specified string. | |
|
65 | """ | |
|
66 | if name[:1].lower() in 'aeiou': | |
|
67 | return 'an ' + name | |
|
68 | ||
|
69 | return 'a ' + name | |
|
70 | ||
|
71 | ||
|
72 | def repr_type(obj): | |
|
73 | """ Return a string representation of a value and its type for readable | |
|
74 | error messages. | |
|
75 | """ | |
|
76 | the_type = type(obj) | |
|
77 | if the_type is InstanceType: | |
|
78 | # Old-style class. | |
|
79 | the_type = obj.__class__ | |
|
80 | msg = '%r %r' % (obj, the_type) | |
|
81 | return msg | |
|
82 | ||
|
83 | ||
|
84 | def parse_notifier_name(name): | |
|
85 | if isinstance(name, str): | |
|
86 | return [name] | |
|
87 | elif name is None: | |
|
88 | return ['anytraitlet'] | |
|
89 | elif isinstance(name, (list, tuple)): | |
|
90 | for n in name: | |
|
91 | assert isinstance(n, str), "names must be strings" | |
|
92 | return name | |
|
93 | ||
|
94 | ||
|
95 | #----------------------------------------------------------------------------- | |
|
96 | # Base TraitletType for all traitlets | |
|
97 | #----------------------------------------------------------------------------- | |
|
98 | ||
|
99 | ||
|
100 | class TraitletType(object): | |
|
101 | ||
|
102 | metadata = {} | |
|
103 | default_value = None | |
|
104 | info_text = 'any value' | |
|
105 | ||
|
106 | # def __init__(self, name, default_value=NoDefaultSpecified, **metadata): | |
|
107 | # self.name = name | |
|
108 | def __init__(self, default_value=NoDefaultSpecified, **metadata): | |
|
109 | if default_value is not NoDefaultSpecified: | |
|
110 | self.default_value = default_value | |
|
111 | self.metadata.update(metadata) | |
|
112 | ||
|
113 | def __get__(self, inst, cls=None): | |
|
114 | if inst is None: | |
|
115 | return self | |
|
116 | else: | |
|
117 | return inst._traitlet_values.get(self.name, self.default_value) | |
|
118 | ||
|
119 | def __set__(self, inst, value): | |
|
120 | new_value = self._validate(inst, value) | |
|
121 | old_value = self.__get__(inst) | |
|
122 | if old_value != new_value: | |
|
123 | inst._traitlet_values[self.name] = new_value | |
|
124 | inst._notify(self.name, old_value, value) | |
|
125 | ||
|
126 | def _validate(self, inst, value): | |
|
127 | if hasattr(self, 'validate'): | |
|
128 | return self.validate(inst, value) | |
|
129 | elif hasattr(self, 'is_valid_for'): | |
|
130 | valid = self.is_valid_for(value) | |
|
131 | if valid: | |
|
132 | return value | |
|
133 | else: | |
|
134 | raise TraitletError('invalid value for type: %r' % value) | |
|
135 | elif hasattr(self, 'value_for'): | |
|
136 | return self.value_for(value) | |
|
137 | else: | |
|
138 | return value | |
|
139 | ||
|
140 | def info(self): | |
|
141 | return self.info_text | |
|
142 | ||
|
143 | def error(self, obj, value): | |
|
144 | if obj is not None: | |
|
145 | e = "The '%s' traitlet of %s instance must be %s, but a value of %s was specified." \ | |
|
146 | % (self.name, class_of(obj), | |
|
147 | self.info(), repr_type(value)) | |
|
148 | else: | |
|
149 | e = "The '%s' traitlet must be %s, but a value of %r was specified." \ | |
|
150 | % (self.name, self.info(), repr_type(value)) | |
|
151 | raise TraitletError(e) | |
|
152 | ||
|
153 | ||
|
154 | #----------------------------------------------------------------------------- | |
|
155 | # The HasTraitlets implementation | |
|
156 | #----------------------------------------------------------------------------- | |
|
157 | ||
|
158 | ||
|
159 | class MetaHasTraitlets(type): | |
|
160 | """A metaclass for HasTraitlets. | |
|
161 | ||
|
162 | This metaclass makes sure that any TraitletType class attributes are | |
|
163 | instantiated and sets their name attribute. | |
|
164 | """ | |
|
165 | ||
|
166 | def __new__(mcls, name, bases, classdict): | |
|
167 | for k,v in classdict.iteritems(): | |
|
168 | if isinstance(v, TraitletType): | |
|
169 | v.name = k | |
|
170 | elif inspect.isclass(v): | |
|
171 | if issubclass(v, TraitletType): | |
|
172 | vinst = v() | |
|
173 | vinst.name = k | |
|
174 | classdict[k] = vinst | |
|
175 | return super(MetaHasTraitlets, mcls).__new__(mcls, name, bases, classdict) | |
|
176 | ||
|
177 | ||
|
178 | class HasTraitlets(object): | |
|
179 | ||
|
180 | __metaclass__ = MetaHasTraitlets | |
|
181 | ||
|
182 | def __init__(self): | |
|
183 | self._traitlet_values = {} | |
|
184 | self._notifiers = {} | |
|
185 | ||
|
186 | def _notify(self, name, old_value, new_value): | |
|
187 | callables = self._notifiers.get(name,[]) | |
|
188 | more_callables = self._notifiers.get('anytraitlet',[]) | |
|
189 | callables.extend(more_callables) | |
|
190 | for c in callables: | |
|
191 | # Traits catches and logs errors here. I allow them to raise | |
|
192 | c(name, old_value, new_value) | |
|
193 | ||
|
194 | def _add_notifiers(self, handler, name): | |
|
195 | if not self._notifiers.has_key(name): | |
|
196 | nlist = [] | |
|
197 | self._notifiers[name] = nlist | |
|
198 | else: | |
|
199 | nlist = self._notifiers[name] | |
|
200 | if handler not in nlist: | |
|
201 | nlist.append(handler) | |
|
202 | ||
|
203 | def _remove_notifiers(self, handler, name): | |
|
204 | if self._notifiers.has_key(name): | |
|
205 | nlist = self._notifiers[name] | |
|
206 | try: | |
|
207 | index = nlist.index(handler) | |
|
208 | except ValueError: | |
|
209 | pass | |
|
210 | else: | |
|
211 | del nlist[index] | |
|
212 | ||
|
213 | def on_traitlet_change(self, handler, name=None, remove=False): | |
|
214 | if remove: | |
|
215 | names = parse_notifier_name(name) | |
|
216 | for n in names: | |
|
217 | self._remove_notifiers(handler, n) | |
|
218 | else: | |
|
219 | names = parse_notifier_name(name) | |
|
220 | for n in names: | |
|
221 | self._add_notifiers(handler, n) | |
|
222 | ||
|
223 | ||
|
224 | #----------------------------------------------------------------------------- | |
|
225 | # Actual TraitletTypes implementations/subclasses | |
|
226 | #----------------------------------------------------------------------------- | |
|
227 | ||
|
228 | ||
|
229 | class Any(TraitletType): | |
|
230 | default_value = None | |
|
231 | info_text = 'any value' | |
|
232 | ||
|
233 | ||
|
234 | class Int(TraitletType): | |
|
235 | ||
|
236 | evaluate = int | |
|
237 | default_value = 0 | |
|
238 | info_text = 'an integer' | |
|
239 | ||
|
240 | def validate(self, obj, value): | |
|
241 | if isinstance(value, int): | |
|
242 | return value | |
|
243 | self.error(obj, value) | |
|
244 | ||
|
245 | ||
|
246 | class Long(TraitletType): | |
|
247 | ||
|
248 | evaluate = long | |
|
249 | default_value = 0L | |
|
250 | info_text = 'a long' | |
|
251 | ||
|
252 | def validate(self, obj, value): | |
|
253 | if isinstance(value, long): | |
|
254 | return value | |
|
255 | if isinstance(value, int): | |
|
256 | return long(value) | |
|
257 | self.error(obj, value) | |
|
258 | ||
|
259 | ||
|
260 | class Float(TraitletType): | |
|
261 | ||
|
262 | evaluate = float | |
|
263 | default_value = 0.0 | |
|
264 | info_text = 'a float' | |
|
265 | ||
|
266 | def validate(self, obj, value): | |
|
267 | if isinstance(value, float): | |
|
268 | return value | |
|
269 | if isinstance(value, int): | |
|
270 | return float(value) | |
|
271 | self.error(obj, value) | |
|
272 | ||
|
273 | ||
|
274 | class Complex(TraitletType): | |
|
275 | ||
|
276 | evaluate = complex | |
|
277 | default_value = 0.0 + 0.0j | |
|
278 | info_text = 'a complex number' | |
|
279 | ||
|
280 | def validate(self, obj, value): | |
|
281 | if isinstance(value, complex): | |
|
282 | return value | |
|
283 | if isinstance(value, (float, int)): | |
|
284 | return complex(value) | |
|
285 | self.error(obj, value) | |
|
286 | ||
|
287 | ||
|
288 | class Str(TraitletType): | |
|
289 | ||
|
290 | evaluate = lambda x: x | |
|
291 | default_value = '' | |
|
292 | info_text = 'a string' | |
|
293 | ||
|
294 | def validate(self, obj, value): | |
|
295 | if isinstance(value, str): | |
|
296 | return value | |
|
297 | self.error(obj, value) | |
|
298 | ||
|
299 | ||
|
300 | class Unicode(TraitletType): | |
|
301 | ||
|
302 | evaluate = unicode | |
|
303 | default_value = u'' | |
|
304 | info_text = 'a unicode string' | |
|
305 | ||
|
306 | def validate(self, obj, value): | |
|
307 | if isinstance(value, unicode): | |
|
308 | return value | |
|
309 | if isinstance(value, str): | |
|
310 | return unicode(value) | |
|
311 | self.error(obj, value) | |
|
312 | ||
|
313 | ||
|
314 | class Bool(TraitletType): | |
|
315 | ||
|
316 | evaluate = bool | |
|
317 | default_value = False | |
|
318 | info_text = 'a boolean' | |
|
319 | ||
|
320 | def validate(self, obj, value): | |
|
321 | if isinstance(value, bool): | |
|
322 | return value | |
|
323 | self.error(obj, value) | |
|
324 |
General Comments 0
You need to be logged in to leave comments.
Login now