示例#1
0
    def test_shape(self):
        good = [
            ([1, 2], int, (2,)),
            ([[1, 2, 3], [4, 5, 6.0]], (int, float), (2, 3)),
            ([[[1]]], int, (1, 1, 1)),
            ([[1], [2]], None, (2, 1)),
            # if you didn't have `list` as a type, the shape of this one
            # would be (2, 2) - that's tested in bad below
            ([[1, 2], [3, 4]], list, (2,)),
            (((0, 1, 2), ((0, 1), (0, 1), (0, 1))), tuple, (2,)),
            (((0, 1, 2), ((0, 1), (0, 1), (0, 1))), (tuple, int), (2, 3))
        ]
        for obj, types, shape in good:
            with self.subTest(obj=obj):
                self.assertTrue(is_sequence_of(obj, types, shape=shape))

        bad = [
            ([1], int, (2,)),
            ([[1]], int, (1,)),
            ([[1, 2], [1]], int, (2, 2)),
            ([[1]], float, (1, 1)),
            ([[1, 2], [3, 4]], int, (2, )),
            (((0, 1, 2), ((0, 1), (0, 1))), (tuple, int), (2, 3))
        ]
        for obj, types, shape in bad:
            with self.subTest(obj=obj):
                self.assertFalse(is_sequence_of(obj, types, shape=shape))
示例#2
0
    def test_shape_depth(self):
        # there's no reason to provide both shape and depth, but
        # we allow it if they are self-consistent
        with self.assertRaises(ValueError):
            is_sequence_of([], int, depth=1, shape=(2, 2))

        self.assertFalse(is_sequence_of([1], int, depth=1, shape=(2, )))
        self.assertTrue(is_sequence_of([1], int, depth=1, shape=(1, )))
示例#3
0
def test_shape_depth():
    # there's no reason to provide both shape and depth, but
    # we allow it if they are self-consistent
    with pytest.raises(ValueError):
        is_sequence_of([], int, depth=1, shape=(2, 2))

    assert not is_sequence_of([1], int, depth=1, shape=(2,))
    assert is_sequence_of([1], int, depth=1, shape=(1,))
示例#4
0
    def test_depth(self):
        good = [([1, 2], int, 1), ([[1, 2], [3, 4]], int, 2),
                ([[1, 2.0], []], (int, float), 2), ([[[1]]], int, 3)]
        for args in good:
            with self.subTest(args=args):
                self.assertTrue(is_sequence_of(*args))

        bad = [([1], int, 2), ([[1]], int, 1), ([[1]], float, 2)]
        for args in bad:
            with self.subTest(args=args):
                self.assertFalse(is_sequence_of(*args))
示例#5
0
def _is_nested_sequence_or_none(obj, types, shapes):
    """Validator for MultiParameter setpoints/names/labels"""
    if obj is None:
        return True

    if not is_sequence_of(obj, tuple, shape=(len(shapes),)):
        return False

    for obji, shapei in zip(obj, shapes):
        if not is_sequence_of(obji, types, shape=(len(shapei),)):
            return False

    return True
示例#6
0
    def test_simple(self):
        good = [
            # empty lists pass without even checking that we provided a
            # valid type spec
            ([], None),
            ((), None),
            ([1, 2, 3], int),
            ((1, 2, 3), int),
            ([1, 2.0], (int, float)),
            ([{}, None], (type(None), dict))
        ]
        for args in good:
            with self.subTest(args=args):
                self.assertTrue(is_sequence_of(*args))

        bad = [(1, int), ([1, 2.0], int), ([1, 2], float),
               ([1, 2], (float, dict))]
        for args in bad:
            with self.subTest(args=args):
                self.assertFalse(is_sequence_of(*args))

        # second arg must be a type or tuple of types - failing this doesn't
        # return False, it raises an error
        with self.assertRaises(TypeError):
            is_sequence_of([1], 1)
        with self.assertRaises(TypeError):
            is_sequence_of([1], (1, 2))
        with self.assertRaises(TypeError):
            is_sequence_of([1])
示例#7
0
    def __init__(self,
                 name=None,
                 names=None,
                 label=None,
                 labels=None,
                 units=None,
                 shape=None,
                 shapes=None,
                 setpoints=None,
                 setpoint_names=None,
                 setpoint_labels=None,
                 vals=None,
                 docstring=None,
                 snapshot_get=True,
                 **kwargs):
        super().__init__(**kwargs)
        self._snapshot_get = snapshot_get

        self.has_get = hasattr(self, 'get')
        self.has_set = hasattr(self, 'set')
        self._meta_attrs = ['setpoint_names', 'setpoint_labels']

        # always let the parameter have a single name (in fact, require this!)
        # even if it has names too
        self.name = str(name)

        if names is not None:
            # check for names first - that way you can provide both name
            # AND names for instrument parameters - name is how you get the
            # object (from the parameters dict or the delegated attributes),
            # and names are the items it returns
            self.names = names
            self.labels = names if labels is None else names
            self.units = units if units is not None else [''] * len(names)

            self.set_validator(vals or Anything())
            self.__doc__ = os.linesep.join(
                ('Parameter class:', '* `names` %s' % ', '.join(self.names),
                 '* `labels` %s' % ', '.join(self.labels),
                 '* `units` %s' % ', '.join(self.units)))
            self._meta_attrs.extend(['names', 'labels', 'units'])

        elif name is not None:
            self.label = name if label is None else label
            self.units = units if units is not None else ''

            # vals / validate only applies to simple single-value parameters
            self.set_validator(vals)

            # generate default docstring
            self.__doc__ = os.linesep.join((
                'Parameter class:',
                '* `name` %s' % self.name,
                '* `label` %s' % self.label,
                # TODO is this unit s a typo? shouldnt that be unit?
                '* `units` %s' % self.units,
                '* `vals` %s' % repr(self._vals)))
            self._meta_attrs.extend(['name', 'label', 'units', 'vals'])

        else:
            raise ValueError('either name or names is required')

        if shape is not None or shapes is not None:
            nt = type(None)

            if shape is not None:
                if not is_sequence_of(shape, int):
                    raise ValueError('shape must be a tuple of ints, not ' +
                                     repr(shape))
                self.shape = shape
                depth = 1
                container_str = 'tuple'
            else:
                if not is_sequence_of(shapes, int, depth=2):
                    raise ValueError('shapes must be a tuple of tuples '
                                     'of ints, not ' + repr(shape))
                self.shapes = shapes
                depth = 2
                container_str = 'tuple of tuples'

            sp_types = (nt, DataArray, collections.Sequence,
                        collections.Iterator)
            if (setpoints is not None
                    and not is_sequence_of(setpoints, sp_types, depth)):
                raise ValueError(
                    'setpoints must be a {} of arrays'.format(container_str))
            if (setpoint_names is not None
                    and not is_sequence_of(setpoint_names, (nt, str), depth)):
                raise ValueError('setpoint_names must be a {} '
                                 'of strings'.format(container_str))
            if (setpoint_labels is not None
                    and not is_sequence_of(setpoint_labels, (nt, str), depth)):
                raise ValueError('setpoint_labels must be a {} '
                                 'of strings'.format(container_str))

            self.setpoints = setpoints
            self.setpoint_names = setpoint_names
            self.setpoint_labels = setpoint_labels

        # record of latest value and when it was set or measured
        # what exactly this means is different for different subclasses
        # but they all use the same attributes so snapshot is consistent.
        self._latest_value = None
        self._latest_ts = None

        if docstring is not None:
            self.__doc__ = docstring + os.linesep + self.__doc__

        self.get_latest = GetLatest(self)
示例#8
0
    def __init__(self, name, names, shapes, instrument=None,
                 labels=None, units=None,
                 setpoints=None, setpoint_names=None, setpoint_labels=None,
                 setpoint_units=None, docstring=None,
                 snapshot_get=True, snapshot_value=True, metadata=None):
        super().__init__(name, instrument, snapshot_get, metadata,
                         snapshot_value=snapshot_value)

        if self.has_set:  # TODO (alexcjohnson): can we support, ala Combine?
            warnings.warn('MultiParameters do not fully support set '
                          'at this time.')

        self._meta_attrs.extend(['setpoint_names', 'setpoint_labels', 'setpoint_units',
                                 'names', 'labels', 'units'])

        if not is_sequence_of(names, str):
            raise ValueError('names must be a tuple of strings, not' +
                             repr(names))

        self.names = names
        self.labels = labels if labels is not None else names
        self.units = units if units is not None else [''] * len(names)

        nt = type(None)

        if (not is_sequence_of(shapes, int, depth=2) or
                len(shapes) != len(names)):
            raise ValueError('shapes must be a tuple of tuples '
                             'of ints, not ' + repr(shapes))
        self.shapes = shapes

        sp_types = (nt, DataArray, collections.Sequence,
                    collections.Iterator)
        if not _is_nested_sequence_or_none(setpoints, sp_types, shapes):
            raise ValueError('setpoints must be a tuple of tuples of arrays')

        if not _is_nested_sequence_or_none(setpoint_names, (nt, str), shapes):
            raise ValueError(
                'setpoint_names must be a tuple of tuples of strings')

        if not _is_nested_sequence_or_none(setpoint_labels, (nt, str), shapes):
            raise ValueError(
                'setpoint_labels must be a tuple of tuples of strings')

        if not _is_nested_sequence_or_none(setpoint_units, (nt, str), shapes):
            raise ValueError(
                'setpoint_units must be a tuple of tuples of strings')

        self.setpoints = setpoints
        self.setpoint_names = setpoint_names
        self.setpoint_labels = setpoint_labels
        self.setpoint_units = setpoint_units

        self.__doc__ = os.linesep.join((
            'MultiParameter class:',
            '',
            '* `name` %s' % self.name,
            '* `names` %s' % ', '.join(self.names),
            '* `labels` %s' % ', '.join(self.labels),
            '* `units` %s' % ', '.join(self.units)))

        if docstring is not None:
            self.__doc__ = os.linesep.join((
                docstring,
                '',
                self.__doc__))
示例#9
0
    def __init__(self, name, shape, instrument=None,
                 label=None, unit=None, units=None,
                 setpoints=None, setpoint_names=None, setpoint_labels=None,
                 setpoint_units=None, docstring=None,
                 snapshot_get=True, snapshot_value=True, metadata=None):
        super().__init__(name, instrument, snapshot_get, metadata,
                         snapshot_value=snapshot_value)

        if self.has_set:  # TODO (alexcjohnson): can we support, ala Combine?
            raise AttributeError('ArrayParameters do not support set '
                                 'at this time.')

        self._meta_attrs.extend(['setpoint_names', 'setpoint_labels', 'setpoint_units',
                                 'label', 'unit'])

        self.label = name if label is None else label

        if units is not None:
            warn_units('ArrayParameter', self)
            if unit is None:
                unit = units
        self.unit = unit if unit is not None else ''

        nt = type(None)

        if not is_sequence_of(shape, int):
            raise ValueError('shapes must be a tuple of ints, not ' +
                             repr(shape))
        self.shape = shape

        # require one setpoint per dimension of shape
        sp_shape = (len(shape),)

        sp_types = (nt, DataArray, collections.Sequence,
                    collections.Iterator)
        if (setpoints is not None and
                not is_sequence_of(setpoints, sp_types, shape=sp_shape)):
            raise ValueError('setpoints must be a tuple of arrays')
        if (setpoint_names is not None and
                not is_sequence_of(setpoint_names, (nt, str), shape=sp_shape)):
            raise ValueError('setpoint_names must be a tuple of strings')
        if (setpoint_labels is not None and
                not is_sequence_of(setpoint_labels, (nt, str),
                                   shape=sp_shape)):
            raise ValueError('setpoint_labels must be a tuple of strings')
        if (setpoint_units is not None and
                not is_sequence_of(setpoint_units, (nt, str),
                                   shape=sp_shape)):
            raise ValueError('setpoint_units must be a tuple of strings')

        self.setpoints = setpoints
        self.setpoint_names = setpoint_names
        self.setpoint_labels = setpoint_labels
        self.setpoint_units = setpoint_units

        self.__doc__ = os.linesep.join((
            'Parameter class:',
            '',
            '* `name` %s' % self.name,
            '* `label` %s' % self.label,
            '* `unit` %s' % self.unit,
            '* `shape` %s' % repr(self.shape)))

        if docstring is not None:
            self.__doc__ = os.linesep.join((
                docstring,
                '',
                self.__doc__))
示例#10
0
def test_shape_good(args):
    obj, types, shape = args
    assert is_sequence_of(obj, types, shape=shape)
示例#11
0
def test_depth_bad(args):
    assert not is_sequence_of(*args)
示例#12
0
def test_depth_good(args):
    assert is_sequence_of(*args)
示例#13
0
def test_examples_raises():
    with pytest.raises(TypeError):
        is_sequence_of([1], 1)
    with pytest.raises(TypeError):
        is_sequence_of([1], (1, 2))
示例#14
0
def test_simple_bad(args):
    assert not is_sequence_of(*args)
示例#15
0
def test_simple_good(args):
    assert is_sequence_of(*args)