class DummyHook(Atom): fail_check = Bool().tag(pref=True) fail_run = Bool() should_pause = Bool() accept_pause = Bool(True) should_resume = Bool() stop_called = Bool() waiting = Value(factory=Event) go_on = Value(factory=Event) signal_resuming = Value(factory=Event) go_on_resuming = Value(factory=Event) signal_resumed = Value(factory=Event) go_on_resumed = Value(factory=Event) def run(self, workbench, engine): self.waiting.set() self.go_on.wait() if self.fail_run: raise RuntimeError() if self.accept_pause and self.should_pause: self.paused = True while True: sleep(0.001) if self.should_resume: self.signal_resuming.set() self.go_on_resuming.wait() self.resumed = True break self.signal_resumed.set() self.go_on_resumed.wait() self.waiting.clear() self.go_on.clear() def pause(self): self.should_pause = True def resume(self): self.should_resume = True def stop(self, force=False): self.stop_called = True
class WebApplication(Application): """ Base enaml web application that uses the widgets defined in `web.components.html` """ #: Logger logger = Instance(logging.Logger, factory=lambda: logging.getLogger('enaml')) #: Database database = Value() def __init__(self, *args, **kwargs): """ Initialize a WebApplication. """ super(WebApplication, self).__init__(*args, **kwargs) self.resolver = ProxyResolver(factories=lxml_components.FACTORIES)
class Records(Atom): """ A simple class representing a records object. """ items = List() # This property holds the timeout interval in milliseconds. interval = Int() current_position = Int(0) current_value = Value() @observe("current_position") def _select_curval(self, change): idx = change["value"] if idx < len(self.items): self.current_value = self.items[idx]
class Person(Atom): """ A simple class representing a person object. """ last_name = Unicode() first_name = Unicode() age = Range(low=0) dob = Value(datetime.date(1970, 1, 1)) debug = Bool(False) @observe('age') def debug_print(self, change): """ Prints out a debug message whenever the person's age changes. """ if self.debug: templ = "{first} {last} is {age} years old." s = templ.format( first=self.first_name, last=self.last_name, age=self.age, ) print(s) @observe('dob') def update_age(self, change): """ Update the person's age whenever their date of birth changes """ # grab the current date time now = datetime.datetime.utcnow() # estimate the person's age within one year accuracy age = now.year - self.dob.year # check to see if the current date is before their birthday and # subtract a year from their age if it is if ((now.month == self.dob.month and now.day < self.dob.day) or now.month < self.dob.month): age -= 1 # set the persons age self.age = age
class PNASetRFPowerInterface(TaskInterface): """Set the central power to be used for the specified channel. """ #: Id of the channel whose central frequency should be set. channel = Int(1).tag(pref=True) #: Port whose output power should be set. port = Int(1).tag(pref=True) #: Driver for the channel. channel_driver = Value() def prepare(self): """Create the channel driver. """ self.channel_driver = self.task.driver.get_channel(self.channel) def perform(self, power=None): """Set the power for the selected channel and port. """ task = self.task task.driver.owner = task.name self.channel_driver.owner = task.name if power is None: power = task.format_and_eval_string(task.power) self.channel_driver.port = self.port self.channel_driver.power = power task.write_in_database('power', power) def check(self, *args, **kwargs): """Ensure the presence of the requested channel. """ test, tb = super(PNASetRFPowerInterface, self).check(*args, **kwargs) task = self.task res = check_channels_presence(task, [self.channel], *args, **kwargs) tb.update(res[1]) return test and res[0], tb
class GzipDecompressor(Atom): """Streaming gzip decompressor. The interface is like that of `zlib.decompressobj` (without some of the optional arguments, but it understands gzip headers and checksums. """ decompressobj = Value() def __init__(self): import zlib # Magic parameter makes zlib module understand gzip header # http://stackoverflow.com/questions/1838699/how-can-i-decompress-a-gzip-stream-with-zlib # This works on cpython and pypy, but not jython. self.decompressobj = zlib.decompressobj(16 + zlib.MAX_WBITS) def decompress(self, value, max_length=None): # type: (bytes, Optional[int]) -> bytes """Decompress a chunk, returning newly-available data. Some data may be buffered for later processing; `flush` must be called when there is no more input data to ensure that all data was processed. If ``max_length`` is given, some input data may be left over in ``unconsumed_tail``; you must retrieve this value and pass it back to a future call to `decompress` if it is not empty. """ return self.decompressobj.decompress(value, max_length) @property def unconsumed_tail(self): # type: () -> bytes """Returns the unconsumed portion left over """ return self.decompressobj.unconsumed_tail def flush(self): # type: () -> bytes """Return any remaining buffered data not yet returned by decompress. Also checks for errors such as truncated input. No other methods may be called on this object after `flush`. """ return self.decompressobj.flush()
class Image(Atom): """ An object representing an image. Once an image is created it should be treated as read only. User code should create a new image object if the parameters need to be changed. """ #: The format of the image. By default, the consumer of the image #: will probe the header to automatically infer a type. format = Enum( 'auto', # Automatically determine the image format 'png', # Portable Network Graphics 'jpg', # Joint Photographic Experts Group 'gif', # Graphics Interchange Format 'bmp', # Windows Bitmap 'xpm', # X11 Pixmap 'xbm', # X11 Bitmap 'pbm', # Portable Bitmap 'pgm', # Portable Graymap 'ppm', # Portable Pixmap 'tiff', # Tagged Image File Format # 'array', # A numpy array with an appropriate image dtype. ) #: The (width, height) size of the image. An invalid size indicates #: that the size of the image should be automatically inferred. A #: valid size indicates that the toolkit image should be scaled to #: the specified size. size = Coerced(Size, (-1, -1)) #: The aspect ratio mode to use when the toolkit scales the image. aspect_ratio_mode = Enum('ignore', 'keep', 'keep_by_expanding') #: The transform mode to use when the toolkit scales the image. transform_mode = Enum('smooth', 'fast') # XXX this needs to be augmented to support arrays. #: The bytestring holding the data for the image. data = Str() #: Storage space for use by a toolkit backend to use as needed. #: This should not typically be manipulated by user code. _tkdata = Value()
def test_using_call_object_object_name_mode(): """Test using call_object_object_name mode.""" def getter(object, name): object.count += 1 return object.count, name m = Value() m.set_getattr_mode(GetAttr.CallObject_ObjectName, getter) class CustomGetAtom(Atom): val = m count = Int() a = CustomGetAtom() assert a.val == (1, "val") assert a.val == (2, "val") with pytest.raises(TypeError): m.set_getattr_mode(GetAttr.CallObject_ObjectName, 1)
def test_using_object_method_name_mode(): """Test using object_method mode.""" m = Value() m.set_getattr_mode(GetAttr.ObjectMethod_Name, "getter") class CustomGetAtom(Atom): val = m count = Int() def getter(self, name): self.count += 1 return (self.count, name) a = CustomGetAtom() assert a.val == (1, "val") assert a.val == (2, "val") with pytest.raises(TypeError): m.set_getattr_mode(GetAttr.CallObject_Object, 1)
class ListItem(ToolkitObject): """ A holder for a View within a ListItem. """ #: The item this view should render item = d_(Value(), writable=False) #: The position of this item within the ListView index = d_(Int(), writable=False) #: Triggered when this item is clicked clicked = d_(Event()) #: Triggered when this item is long clicked long_clicked = d_(Event()) #: A reference to the ProxyLabel object. proxy = Typed(ProxyListItem)
class ChangingAtom(Atom): val = Int() counter1 = Int() counter2 = Int() observer = Value() def react1(self, change): self.counter1 += 1 self.observer.active = False self.unobserve("val", self.react1) self.observe("val", self.react2) def react2(self, change): self.counter2 += 1 self.unobserve("val") self.observe("val", self.react1)
def _default_connector_class(self): attrs = {} names = self.processor.output_fieldnames for k in names: attrs[k] = Value() attrs["names"] = List(default=names) def update_data(s, ds): for key in names: value = getattr(ds, key) if hasattr(s, key): setattr(s, key, value) attrs['__call__'] = update_data return new.classobj( "DataConnector_%s_%s" % (self.name, self.processor.name), (Atom, ), attrs)
class SplitItem(Widget): """ A widget which can be used as an item in a Splitter. A SplitItem is a widget which can be used as a child of a Splitter widget. It can have at most a single child widget which is an instance of Container. """ #: The stretch factor for this item. The stretch factor determines #: how much an item is resized relative to its neighbors when the #: splitter space is allocated. stretch = d_(Range(low=0, value=1)) #: Whether or not the item can be collapsed to zero width by the #: user. This holds regardless of the minimum size of the item. collapsible = d_(Bool(True)) #: This is a deprecated attribute. It should no longer be used. preferred_size = d_(Value()) #: A reference to the ProxySplitItem object. proxy = Typed(ProxySplitItem) def split_widget(self): """ Get the split widget defined on the item. The split widget is the last child Container. """ for child in reversed(self.children): if isinstance(child, Container): return child #-------------------------------------------------------------------------- # Observers #-------------------------------------------------------------------------- @observe('stretch', 'collapsible') def _update_proxy(self, change): """ An observer which sends state change to the proxy. """ # The superclass handler implementation is sufficient. super(SplitItem, self)._update_proxy(change)
class FalseEntryPoint(Atom): """False entry whose behavior can be customized. """ #: Name of this entry point name = Unicode() #: Flag indicating whether the require method should raise an error. missing_require = Bool() #: List of manifest to return when load method is called. manifests = Value() def require(self): if self.missing_require: raise Exception() return True def load(self): return lambda: self.manifests
class SingleChannelPNATask(InstrumentTask): """ Helper class managing the notion of channel in the PNA. """ # Id of the channel to use. channel = Int(1).tag(pref=True) channel_driver = Value() def check(self, *args, **kwargs): """ Add checking for channels to the base tests. """ test, traceback = super(SingleChannelPNATask, self).check(*args, **kwargs) c_test, c_trace = check_channels_presence(self, [self.channel], *args, **kwargs) traceback.update(c_trace) return test and c_test, traceback
class CustomEntryPoint(Atom): name = Str() module_name = Value() attrs = List() def load(self): entry = __import__(self.module_name, globals(), globals(), ['__name__']) for attr in self.attrs: try: entry = getattr(entry, attr) except AttributeError: raise ImportError("%r has no %r attribute" % (entry, attr)) return entry @classmethod def parse(cls, key, value): """Parse a single entry point from string `src` key: some.module:some.attr The entry key and module name are required, but the ``:attrs`` part is optional """ try: attrs = [] if ':' in value: value, attrs = value.split(':', 1) if not MODULE(attrs.rstrip()): raise ValueError attrs = attrs.rstrip().split('.') except ValueError: msg = "CustomEntryPoint must be in 'name=module:attrs' format" raise ValueError(msg, "%s=%s" % (key, value)) else: return cls(name=key.strip(), module_name=value.strip(), attrs=attrs) @classmethod def instances_from_items(cls, items): result = {} for key, value in items: result[key] = cls.parse(key, value).load() return result
class PNASetRFPowerInterface(InstrTaskInterface): """Set the central power to be used for the specified channel. """ # Id of the channel whose central frequency should be set. channel = Int(1).tag(pref=True) # Driver for the channel. channel_driver = Value() # Port whose output power should be set. port = Int(1).tag(pref=True) driver_list = ['AgilentPNA'] has_view = True def perform(self, power=None): """ """ task = self.task if not task.driver: task.start_driver() self.channel_driver = task.driver.get_channel(self.channel) task.driver.owner = task.task_name self.channel_driver.owner = task.task_name if power is None: power = task.format_and_eval_string(task.power) self.channel_driver.port = self.port self.channel_driver.power = power task.write_in_database('power', power) def check(self, *args, **kwargs): """ """ task = self.task return check_channels_presence(task, [self.channel], *args, **kwargs)
class MetadataTaskFilter(TaskFilter): """Filter keeping only the python tasks with the right class attribute. """ #: Metadata key to match. meta_key = d_(Unicode()) #: Metadata value to match. meta_value = d_(Value()) @d_func def filter_tasks(self, tasks, templates): """Keep only the task with the right class attribute. """ tasks = [ name for name, infos in tasks.items() if infos.metadata.get(self.meta_key) == self.meta_value ] return tasks
def _build_state(self, state_id): """Create a custom _StateHolder class at runtime and instantiate it. Parameters ---------- state_id : unicode Id of the state to return. Returns ------- state : _StateHolder State reflecting the sync_members of the plugin to which it is linked. """ state = self._states.contributions[state_id] # Explicit casting required as Python 2 does not like Unicode for class # name class_name = str(''.join([s.capitalize() for s in state_id.split('.')])) members = {} # Explicit casting required as Python 2 does not like Unicode for # members name for m in state.sync_members: members[str(m)] = Value() state_class = type(class_name, (_StateHolder, ), members) # Instantiation , initialisation, and binding of the state object to # the plugin declaring it. state_object = state_class() extension = self._states.contributed_by(state_id) plugin = self.workbench.get_plugin(extension.plugin_id) with state_object.setting_allowed(): for m in state.sync_members: setattr(state_object, m, getattr(plugin, m)) plugin.observe(m, state_object.updater) return state_object
class WaitingTask(SimpleTask): """Simple Task whose execution can be controlled using events. """ check_flag = Bool(True).tag(pref=True) sync_port = Value(()).tag(pref=True) sock_id = Str().tag(pref=True) def check(self, *args, **kwargs): super(WaitingTask, self).check(*args, **kwargs) return self.check_flag, {'test': 1} def perform(self): with socket.socket() as s: while True: if s.connect_ex(('localhost', self.sync_port)) == 0: break sleep(0.01) s.sendall(self.sock_id.encode('utf-8')) s.recv(4096) s.sendall('Waiting'.encode('utf-8')) s.recv(4096)
class Pen(Atom): #: Color color = ColorMember() #: Width width = Float(1.0, strict=False) #: Line Style line_style = Enum('solid', 'dash', 'dot', 'dash_dot', 'dash_dot_dot', 'custom', 'none') #: Cap Style cap_style = Enum('square', 'flat', 'round') #: Join Style join_style = Enum('bevel', 'miter', 'round') #: Dash pattern used when line_style is 'custom' dash_pattern = List(Float(strict=False)) #: Internal data _tkdata = Value()
class BaseRecordSource(Atom): name = Str() title = Str() schema = Typed(RecordSchema) output_fieldnames = List() max_record_count = Int(0) reference_timestamps = List() reference_interval = Float(1.0) record_class = Value() cached_records = List() def _default_output_fieldnames(self): return ['timestamp'] + [f.name for f in self.schema.fields] def _default_record_class(self): attrs = dict(timestamp=Coerced(np.int64), ) for field in self.schema.fields: if field.name in attrs: log.warn( "Duplicate key: %s in field specification for record source: %s - skipping" % (field.name, self.name)) continue attrs[field.name] = Value() return new.classobj("RecordClass_%s" % self.name, (Atom, ), attrs) def clear_cache(self): self.cached_records = [] def __iter__(self): if len(self.cached_records) > 0: for cached_record in self.cached_records: yield cached_record return raise NotImplemented()
class PNASetRFFrequencyInterface(TaskInterface): """Set the central frequency to be used for the specified channel. """ #: Id of the channel whose central frequency should be set. channel = Int(1).tag(pref=True) #: Driver for the channel. channel_driver = Value() def perform(self, frequency=None): """Set the central frequency of the specified channel. """ task = self.task if not self.channel_driver: self.channel_driver = task.driver.get_channel(self.channel) task.driver.owner = task.name self.channel_driver.owner = task.name if frequency is None: frequency = task.format_and_eval_string(task.frequency) frequency = task.convert(frequency, 'Hz') self.channel_driver.frequency = frequency task.write_in_database('frequency', frequency) def check(self, *args, **kwargs): """Make sure the specified channel does exists on the instrument. """ test, tb = super(PNASetRFFrequencyInterface, self).check(*args, **kwargs) task = self.task res = check_channels_presence(task, [self.channel], *args, **kwargs) tb.update(res[1]) return test and res[0], tb
class PNASetRFFrequencyInterface(InstrTaskInterface): """Set the central frequecny to be used for the specified channel. """ # Id of the channel whose central frequency should be set. channel = Int(1).tag(pref=True) # Driver for the channel. channel_driver = Value() driver_list = ['AgilentPNA'] has_view = True def perform(self, frequency=None): """ """ task = self.task if not task.driver: task.start_driver() self.channel_driver = task.driver.get_channel(self.channel) task.driver.owner = task.task_name self.channel_driver.owner = task.task_name if frequency is None: frequency = task.format_and_eval_string(task.frequency) frequency = task.convert(frequency, 'Hz') self.channel_driver.frequency = frequency task.write_in_database('frequency', frequency) def check(self, *args, **kwargs): """ """ task = self.task return check_channels_presence(task, [self.channel], *args, **kwargs)
class Pen(Atom): #: Color color = ColorMember() #: Width width = Float(1.0, strict=False) #: Line Style line_style = Enum( "solid", "dash", "dot", "dash_dot", "dash_dot_dot", "custom", "none" ) #: Cap Style cap_style = Enum("square", "flat", "round") #: Join Style join_style = Enum("bevel", "miter", "round") #: Dash pattern used when line_style is 'custom' dash_pattern = List(Float(strict=False)) #: Internal data _tkdata = Value()
class MetadataSequenceFilter(SequenceFilter): """ Filter keeping only the items with the right class attribute. """ #: Metadata key on which the filtering is performed. meta_key = d_(Unicode()) #: Metadata value on which the filtering is performed. meta_value = d_(Value()) @d_func def filter_sequences(self, py_sequences, template_sequences): """Filter keeping only the items whose metadata fit the provided key/value pair. """ sequences = [] for name, s_infos in py_sequences.items(): if (self.meta_key in s_infos.metadata and s_infos.metadata[self.meta_key] == self.meta_value): sequences.append(name) return sequences
class SharedCounter(Atom): """ Thread-safe counter object. """ #: Current count of the counter. User should not manipulate this directly. count = Int() def increment(self): """Increment the counter by one. """ with self._lock: self.count += 1 def decrement(self): """Decrement the counter by one. """ with self._lock: self.count += -1 #: Simple lock to ensure the thread safety of operations. _lock = Value(factory=Lock)
class CheckTask(SimpleTask): """ """ check_called = Bool() perform_called = Int() perform_value = Value() time = Float(0.01) def check(self, *args, **kwargs): self.check_called = True return True, {} def perform(self, value=None): self.perform_called += 1 self.perform_value = value # Simply allow thread switching sleep(self.time)
class Parameter(ContextItem): ''' A context item that can be evaluated dynamically, but cannot be included as part of a selector. This is typically used for settings that must be determined before values are drawn from the selectors (e.g., probability of a go trial). ''' # Default value of the context item when used as part of a selector. default = d_(Value()) expression = d_(Str()).tag(preference=True) # Defines the span over which the item's value does not change: # * experiment - the value cannot change once the experiment begins # * trial - The value cannot change once a trial begins. This is the only # type of item that can be roved using a selector. # * arbitrary - The value can be changd at any time but it does not make # sense for it to be a roving item. scope = d_(Enum('trial', 'experiment', 'arbitrary')) # Is the value of this item managed by a selector? rove = d_(Bool()).tag(preference=True) def _default_expression(self): return str(self.default) def _default_dtype(self): return np.array(self.default).dtype.str def _default_label(self): return self.name def to_expression(self, value): return str(value) def set_value(self, value): self.expression = self.to_expression(value)
class Person(Atom): """A simple class representing a person object.""" last_name = Str() first_name = Str() age = Range(low=0) dob = Value(datetime.date(1970, 1, 1)) debug = Bool(False) @observe("age") def debug_print(self, change): """Prints out a debug message whenever the person's age changes.""" if self.debug: templ = "{first} {last} is {age} years old." s = templ.format( first=self.first_name, last=self.last_name, age=self.age, ) print(s)