Exemplo n.º 1
0
 def testCanFlattenFlatData(self):
     x = ('this is a test', -42, [False, True])
     flat = T.flatten(x)
     self.assertEquals(T.parseTypeTag(flat.tag), T.parseTypeTag('si*b'))
     flat2 = T.flatten(x)
     self.assertEquals(flat2, flat)
     flat3 = T.flatten(x, 'si*b')
     self.assertEquals(flat3, flat)
     with self.assertRaises(T.FlatteningError):
         T.flatten(x, 'sv')
Exemplo n.º 2
0
 def testCanFlattenFlatData(self):
     x = ('this is a test', -42, [False, True])
     flat = T.flatten(x)
     self.assertEquals(T.parseTypeTag(flat.tag), T.parseTypeTag('si*b'))
     flat2 = T.flatten(x)
     self.assertEquals(flat2, flat)
     flat3 = T.flatten(x, 'si*b')
     self.assertEquals(flat3, flat)
     with self.assertRaises(T.FlatteningError):
         T.flatten(x, 'sv')
Exemplo n.º 3
0
def test_create_extended_dataset(dv):
    """Create an extended dataset, add some data and read it back"""
    _path, _name = dv.new_ex('test', [('t', [1], 'v', 'ns'),
                                      ('x', [2,2], 'c', 'V')],
                             [('clicks', 'I', [1], 'i', ''),
                              ('clicks', 'Q', [1], 'i', '')])

    t_data = 3.3
    x = np.array([[3.2+4j, 1.0], [15.8+11j, 2j]])
    I = 3
    Q = 7
    row  = (t_data, x, I, Q)
    dv.add_ex([row, row])
    dv.add_ex_t(([3.3, 3.3], np.array([x, x]), [3,3], [7,7]))

    dv.add_parameter('foo', 32.1)
    dv.add_parameter('bar', 'x')
    dv.add_parameter('baz', [1, 2, 3, 4])

    dv.open(_name)
    assert dv.get_version() == "3.0.0"

    (indep_ex, dep_ex) = dv.variables_ex()
    assert len(indep_ex) == 2
    assert indep_ex[0] == ('t', [1], 'v', 'ns')
    assert indep_ex[1][0] == 'x'
    assert np.all(indep_ex[1][1] == [2,2])
    assert indep_ex[1][2:4] == ('c', 'V')
    assert len(dep_ex) == 2
    assert dep_ex[0] == ('clicks', 'I', [1], 'i', '')
    assert dep_ex[1] == ('clicks', 'Q', [1], 'i', '')

    (indep, dep) = dv.variables()
    assert indep[0] == ('t', 'ns')
    assert indep[1] == ('x', 'V')
    assert dep[0] == ('clicks', 'I', '')
    assert dep[1] == ('clicks', 'Q', '')

    row_type = dv.row_type()
    tt = T.parseTypeTag(row_type)
    assert tt == T.parseTypeTag('*(v[ns]*2c,ii)')

    stored = dv.get_ex()
    for j in range(4):
        for k in range(4):
            assert np.all(stored[k][j] == row[j])

    stored = dv.get_ex_t(100, True)
    for j in range(4):
        for j in range(4):
            assert np.all(stored[j][k] == row[j])
Exemplo n.º 4
0
def test_create_extended_dataset(dv):
    """Create an extended dataset, add some data and read it back"""
    _path, _name = dv.new_ex('test', [('t', [1], 'v', 'ns'),
                                      ('x', [2, 2], 'c', 'V')],
                             [('clicks', 'I', [1], 'i', ''),
                              ('clicks', 'Q', [1], 'i', '')])

    t_data = 3.3
    x = np.array([[3.2 + 4j, 1.0], [15.8 + 11j, 2j]])
    I = 3
    Q = 7
    row = (t_data, x, I, Q)
    dv.add_ex([row, row])
    dv.add_ex_t(([3.3, 3.3], np.array([x, x]), [3, 3], [7, 7]))

    dv.add_parameter('foo', 32.1)
    dv.add_parameter('bar', 'x')
    dv.add_parameter('baz', [1, 2, 3, 4])

    dv.open(_name)
    assert dv.get_version() == "3.0.0"

    (indep_ex, dep_ex) = dv.variables_ex()
    assert len(indep_ex) == 2
    assert indep_ex[0] == ('t', [1], 'v', 'ns')
    assert indep_ex[1][0] == 'x'
    assert np.all(indep_ex[1][1] == [2, 2])
    assert indep_ex[1][2:4] == ('c', 'V')
    assert len(dep_ex) == 2
    assert dep_ex[0] == ('clicks', 'I', [1], 'i', '')
    assert dep_ex[1] == ('clicks', 'Q', [1], 'i', '')

    (indep, dep) = dv.variables()
    assert indep[0] == ('t', 'ns')
    assert indep[1] == ('x', 'V')
    assert dep[0] == ('clicks', 'I', '')
    assert dep[1] == ('clicks', 'Q', '')

    row_type = dv.row_type()
    tt = T.parseTypeTag(row_type)
    assert tt == T.parseTypeTag('*(v[ns]*2c,ii)')

    stored = dv.get_ex()
    for j in range(4):
        for k in range(4):
            assert np.all(stored[k][j] == row[j])

    stored = dv.get_ex_t(100, True)
    for j in range(4):
        for j in range(4):
            assert np.all(stored[j][k] == row[j])
Exemplo n.º 5
0
    def testTypeHints(self):
        """Test conversion to specified allowed types."""
        passingTests = [
            # convert to default type
            (1, [], 'i'),

            # convert to first compatible type
            (1, ['s', 'w'], 'w'),
            (1, ['s', 'v'], 'v'),
            (1, ['s', 'v[m]'], 'v[m]'),

            # empty list gets type from hint
            ([], ['s', '*(ww)'], '*(ww)'),

            # handle unknown pieces inside clusters and lists
            (['a', 'b'], ['*?'], '*s'),
            ((1, 2, 'a'), ['ww?'], 'wws'),
            ((1, 1L), ['??'], 'iw'),
        ]
        failingTests = [
            # no compatible types
            (5.0, ['s', 'b', 't', 'w', 'i'], 'v'),
        ]
        for data, hints, tag in passingTests:
            self.assertEquals(T.flatten(data, hints)[1], T.parseTypeTag(tag))
        for data, hints, tag in failingTests:
            self.assertRaises(T.FlatteningError, T.flatten, data, hints)
Exemplo n.º 6
0
    def testUnitTypes(self):
        """Test flattening with units.

        The flattening code should not do unit conversion,
        but should leave that up to the LabRAD manager to handle.
        Basically, for purposes of flattening, a unit is a unit.
        """
        tests = [
            (Value(5.0, 'ft'), ['v[m]'], 'v[ft]'),

            # real value array
            (U.ValueArray([1, 2, 3], ''), [], '*v[]'),
            (U.ValueArray([1, 2, 3], 'm'), ['*v[m]'], '*v[m]'),

            # complex value array
            (U.ValueArray([1j, 2j, 3j], ''), [], '*c[]'),
            (U.ValueArray([1j, 2j, 3j], 'm'), [], '*c[m]')
        ]
        for data, hints, tag in tests:
            self.assertEqual(T.flatten(data, hints)[1], T.parseTypeTag(tag))

        # we disallow flattening a float to a value with units,
        # as this is a major source of bugs
        try:
            T.flatten(5.0, 'v[m]')
        except Exception:
            pass
        else:
            raise Exception('Cannot flatten float to value with units')
Exemplo n.º 7
0
 def get_random_data(self, c, tag=None):
     """Get a random bit of data conforming to the specified type tag."""
     if tag is None:
         t = hydrant.randType()
     else:
         t = T.parseTypeTag(tag)
     return hydrant.randValue(t)
Exemplo n.º 8
0
 def get_random_data(self, c, tag=None):
     """Get a random bit of data conforming to the specified type tag."""
     if tag is None:
         t = hydrant.randType()
     else:
         t = T.parseTypeTag(tag)
     return hydrant.randValue(t)
Exemplo n.º 9
0
    def testTypeHints(self):
        """Test conversion to specified allowed types."""
        passingTests = [
            # convert to default type
            (1, [], 'i'),

            # convert to first compatible type
            (1, ['s', 'w'], 'w'),
            (1, ['s', 'v'], 'v'),
            (1*U.m, ['s', 'v[m]'], 'v[m]'),

            # empty list gets type from hint
            ([], ['s', '*(ww)'], '*(ww)'),
            
            # handle unknown pieces inside clusters and lists
            (['a', 'b'], ['*?'], '*s'),
            ((1, 2, 'a'), ['ww?'], 'wws'),
            ((1, 1L), ['??'], 'iw'),
        ]
        failingTests = [
            # no compatible types
            (5.0, ['s', 'b', 't', 'w', 'i'], 'v'),
        ]
        for data, hints, tag in passingTests:
            self.assertEqual(T.flatten(data, hints)[1], T.parseTypeTag(tag))
        for data, hints, tag in failingTests:
            self.assertRaises(T.FlatteningError, T.flatten, data, hints)
Exemplo n.º 10
0
 def getInfo(self):
     parsed = parseTypeTag(self.acceptInfo)
     if type(parsed) is LRNone:
         pars = []
     else:
         if type(parsed) is not LRCluster:
             parsed = (parsed, )
         pars = [str(par) for par in parsed]
     self.parameters = pars
     try:
         c = Client.connection
         c.refresh()
         ser = c[self.serverName]
         set = ser.settings[self.settingName]
         self.__name__ = '%s (%s)' % (set.name, ser.name)
         docList = [set.description]
         docList.append('Accepts:')
         docList.append(self.acceptInfo)
         self.returns = list(set.returns)
         docList.append('Returns:')
         docList.append('\n'.join(self.returns))
         self.__doc__ = '\n\n'.join(docList)
     except TypeError:
         self.__name__ = '%s (%s)' % (self.settingName, self.serverName)
         self.__doc__ = 'labRAD setting: Server ID #%s, Setting ID #%s' % (
             self.serverName, self.settingName)
         self.returns = 'Not available'
Exemplo n.º 11
0
 def getInfo( self ):
     parsed = parseTypeTag( self.acceptInfo )
     if type( parsed ) is LRNone:
         pars = []
     else:
         if type( parsed ) is not LRCluster:
             parsed = ( parsed, )
         pars = [str( par ) for par in parsed]
     self.parameters = pars
     try:
         c = Client.connection
         c.refresh()
         ser = c[self.serverName]
         set = ser.settings[self.settingName]
         self.__name__ = '%s (%s)' % ( set.name, ser.name )
         docList = [ set.description ]
         docList.append( 'Accepts:' )
         docList.append( self.acceptInfo )
         self.returns = list( set.returns )
         docList.append( 'Returns:' )
         docList.append( '\n'.join( self.returns ) )
         self.__doc__ = '\n\n'.join( docList )
     except TypeError:
         self.__name__ = '%s (%s)' % ( self.settingName, self.serverName )
         self.__doc__ = 'labRAD setting: Server ID #%s, Setting ID #%s' % ( self.serverName, self.settingName )
         self.returns = 'Not available'
Exemplo n.º 12
0
    def testUnitTypes(self):
        """Test flattening with units.

        The flattening code should not do unit conversion,
        but should leave that up to the LabRAD manager to handle.
        Basically, for purposes of flattening, a unit is a unit.
        """
        tests = [
            (Value(5.0, 'ft'), ['v[m]'], 'v[ft]'),

            # real value array
            (U.ValueArray([1, 2, 3], ''), [], '*v[]'),
            (U.ValueArray([1, 2, 3], 'm'), ['*v[m]'], '*v[m]'),

            # complex value array
            (U.ValueArray([1j, 2j, 3j], ''), [], '*c[]'),
            (U.ValueArray([1j, 2j, 3j], 'm'), [], '*c[m]')
        ]
        for data, hints, tag in tests:
            self.assertEqual(T.flatten(data, hints)[1], T.parseTypeTag(tag))

        # we disallow flattening a float to a value with units,
        # as this is a major source of bugs
        try:
            T.flatten(5.0, 'v[m]')
        except Exception:
            pass
        else:
            raise Exception('Cannot flatten float to value with units')
Exemplo n.º 13
0
 def testTypeSpecialization(self):
     """Test specialization of the type during flattening."""
     tests = [
         # specialization without hints
         ([([],), ([5.0],), ([T.Value(5, 'm')],)], '*(*v[m])'),
     ]
     for data, tag in tests:
         self.assertEquals(T.flatten(data)[1], T.parseTypeTag(tag))
Exemplo n.º 14
0
 def testTypeSpecialization(self):
     """Test specialization of the type during flattening."""
     tests = [
         # specialization without hints
         ([([], ), ([5.0], ), ([T.Value(5, 'm')], )], '*(*v[m])'),
     ]
     for data, tag in tests:
         self.assertEquals(T.flatten(data)[1], T.parseTypeTag(tag))
Exemplo n.º 15
0
def unflattenRecords(data, endianness='>'):
    """Unflatten a list of records from the data segment of a packet"""
    records = []
    s = T.Buffer(data)
    while len(s):
        ID, tag, data = T.unflatten(s, RECORD_TYPE, endianness)
        rec = ID, T.FlatData(data, T.parseTypeTag(tag), endianness)
        records.append(rec)
    return records
Exemplo n.º 16
0
def unflattenRecords(data, endianness='>'):
    """Unflatten a list of records from the data segment of a packet"""
    records = []
    s = T.Buffer(data)
    while len(s):
        ID, tag, data = T.unflatten(s, RECORD_TYPE, endianness)
        rec = ID, T.FlatData(data, T.parseTypeTag(tag), endianness)
        records.append(rec)
    return records
Exemplo n.º 17
0
 def parseOverload( overload ):
     parsed = parseTypeTag( overload )
     if type( parsed ) is LRNone:
         pars = []
     else:
         if type( parsed ) is not LRCluster:
             parsed = ( parsed, )
         pars = [str( par ) for par in parsed]
     return pars
Exemplo n.º 18
0
def convert_units(data, allowed_types):
    '''
    Convert a data object to one of the allowed labrad typetags.
    We first check to see if any of the candidates are acceptable, and we find out
    whether the the match is exact or whether we need to do unit conversions.
    '''
    if not allowed_types:
        if data:
            print "No types found, but non-zero data. "
        return data, T.getType(data)
    objtype = T.parseTypeTag(T.getType(data))
    for candidate in allowed_types:
        compatible, output_type = check_types(objtype, T.parseTypeTag(candidate))
        #print "compat: %s, output_type: %s" % ( compatible, output_type)
        if compatible == 0:
            continue
        if compatible == 2:
            return data, output_type
        if compatible == 1:
            return do_conversion(data, output_type), output_type
    raise RuntimeError("Unable to convert %s to any allowed type (%s)" % (data, allowed_types))
Exemplo n.º 19
0
    def testTags(self):
        """Test the parsing of type tags into LRType objects."""
        tests = {
            '_': T.LRNone(),
            'b': T.LRBool(),
            'i': T.LRInt(),
            'w': T.LRWord(),
            's': T.LRStr(),
            't': T.LRTime(),
            'y': T.LRBytes(),

            # clusters
            'ii': T.LRCluster(T.LRInt(), T.LRInt()),
            'b(t)': T.LRCluster(T.LRBool(), T.LRCluster(T.LRTime())),
            '(ss)': T.LRCluster(T.LRStr(), T.LRStr()),
            '(s)': T.LRCluster(T.LRStr()),
            '((siw))': T.LRCluster(T.LRCluster(T.LRStr(), T.LRInt(),
                                               T.LRWord())),

            # lists
            '*b': T.LRList(T.LRBool()),
            '*_': T.LRList(),
            '*2b': T.LRList(T.LRBool(), depth=2),
            '*2_': T.LRList(depth=2),
            '*2v[Hz]': T.LRList(T.LRValue('Hz'), depth=2),
            '*3v': T.LRList(T.LRValue(), depth=3),
            '*v[]': T.LRList(T.LRValue(''), depth=1),

            # unit types
            'v': T.LRValue(),
            'v[]': T.LRValue(''),
            'v[m/s]': T.LRValue('m/s'),
            'c': T.LRComplex(),
            'c[]': T.LRComplex(''),
            'c[m/s]': T.LRComplex('m/s'),

            # errors
            'E': T.LRError(),
            'Ew': T.LRError(T.LRWord()),
            'E(w)': T.LRError(T.LRCluster(T.LRWord())),

            # more complex stuff
            '*b*i': T.LRCluster(T.LRList(T.LRBool()), T.LRList(T.LRInt())),
        }
        for tag, type_ in tests.items():
            self.assertEqual(T.parseTypeTag(tag), type_)
            newtag = str(type_)
            if isinstance(type_, T.LRCluster) and tag[0] + tag[-1] != '()':
                # just added parentheses in this case
                self.assertEqual(newtag, '(%s)' % tag)
            else:
                self.assertEqual(newtag, tag)
Exemplo n.º 20
0
    def testTags(self):
        """Test the parsing of type tags into LRType objects."""
        tests = {
            '_': T.LRNone(),
            'b': T.LRBool(),
            'i': T.LRInt(),
            'w': T.LRWord(),
            's': T.LRStr(),
            't': T.LRTime(),
            'y': T.LRBytes(),

            # clusters
            'ii': T.LRCluster(T.LRInt(), T.LRInt()),
            'b(t)': T.LRCluster(T.LRBool(), T.LRCluster(T.LRTime())),
            '(ss)': T.LRCluster(T.LRStr(), T.LRStr()),
            '(s)': T.LRCluster(T.LRStr()),
            '((siw))':
            T.LRCluster(T.LRCluster(T.LRStr(), T.LRInt(), T.LRWord())),

            # lists
            '*b': T.LRList(T.LRBool()),
            '*_': T.LRList(),
            '*2b': T.LRList(T.LRBool(), depth=2),
            '*2_': T.LRList(depth=2),
            '*2v[Hz]': T.LRList(T.LRValue('Hz'), depth=2),
            '*3v': T.LRList(T.LRValue(), depth=3),
            '*v[]': T.LRList(T.LRValue(''), depth=1),

            # unit types
            'v': T.LRValue(),
            'v[]': T.LRValue(''),
            'v[m/s]': T.LRValue('m/s'),
            'c': T.LRComplex(),
            'c[]': T.LRComplex(''),
            'c[m/s]': T.LRComplex('m/s'),

            # errors
            'E': T.LRError(),
            'Ew': T.LRError(T.LRWord()),
            'E(w)': T.LRError(T.LRCluster(T.LRWord())),

            # more complex stuff
            '*b*i': T.LRCluster(T.LRList(T.LRBool()), T.LRList(T.LRInt())),
        }
        for tag, type_ in tests.items():
            self.assertEqual(T.parseTypeTag(tag), type_)
            newtag = str(type_)
            if isinstance(type_, T.LRCluster) and tag[0] + tag[-1] != '()':
                # just added parentheses in this case
                self.assertEqual(newtag, '(%s)' % tag)
            else:
                self.assertEqual(newtag, tag)
Exemplo n.º 21
0
 def testTagComments(self):
     """Test the parsing of type tags with comments and whitespace."""
     tests = {
         '': T.LRNone(),
         ' ': T.LRNone(),
         ': this is a test': T.LRNone(),
         '  : this is a test': T.LRNone(),
         '   i  ': T.LRInt(),
         '   i  :': T.LRInt(),
         '   i  : blah': T.LRInt(),
     }
     for tag, type_ in tests.items():
         self.assertEqual(T.parseTypeTag(tag), type_)
Exemplo n.º 22
0
 def testUnitTypes(self):
     """Test flattening with units.
     
     The flattening code should not do unit conversion,
     but should leave that up to the LabRAD manager to handle.
     Basically, for purposes of flattening, a unit is a unit.
     """
     tests = [
         (5.0, ['v[m]'], 'v[m]'),
         (T.Value(5.0, 'ft'), ['v[m]'], 'v[ft]'),
     ]
     for data, hints, tag in tests:
         self.assertEquals(T.flatten(data, hints)[1], T.parseTypeTag(tag))
Exemplo n.º 23
0
 def testTagComments(self):
     """Test the parsing of type tags with comments and whitespace."""
     tests = {
         '': T.LRNone(),
         ' ': T.LRNone(),
         ': this is a test': T.LRNone(),
         '  : this is a test': T.LRNone(),
         '   i  ': T.LRInt(),
         '   i  :': T.LRInt(),
         '   i  : blah': T.LRInt(),
     }
     for tag, type_ in tests.items():
         self.assertEqual(T.parseTypeTag(tag), type_)
Exemplo n.º 24
0
 def testUnitTypes(self):
     """Test flattening with units.
     
     The flattening code should not do unit conversion,
     but should leave that up to the LabRAD manager to handle.
     Basically, for purposes of flattening, a unit is a unit.
     """
     tests = [
         (5.0, ['v[m]'], 'v[m]'),
         (T.Value(5.0, 'ft'), ['v[m]'], 'v[ft]'),
     ]
     for data, hints, tag in tests:
         self.assertEquals(T.flatten(data, hints)[1], T.parseTypeTag(tag))
Exemplo n.º 25
0
 def testTags(self):
     """Test the parsing of type tags into LRType objects."""
     tests = {
         "_": T.LRNone(),
         "b": T.LRBool(),
         "i": T.LRInt(),
         "w": T.LRWord(),
         "s": T.LRStr(),
         "t": T.LRTime(),
         "y": T.LRBytes(),
         # clusters
         "ii": T.LRCluster(T.LRInt(), T.LRInt()),
         "b(t)": T.LRCluster(T.LRBool(), T.LRCluster(T.LRTime())),
         "(ss)": T.LRCluster(T.LRStr(), T.LRStr()),
         "(s)": T.LRCluster(T.LRStr()),
         "((siw))": T.LRCluster(T.LRCluster(T.LRStr(), T.LRInt(), T.LRWord())),
         # lists
         "*b": T.LRList(T.LRBool()),
         "*_": T.LRList(),
         "*2b": T.LRList(T.LRBool(), depth=2),
         "*2_": T.LRList(depth=2),
         "*2v[Hz]": T.LRList(T.LRValue("Hz"), depth=2),
         "*3v": T.LRList(T.LRValue(), depth=3),
         "*v[]": T.LRList(T.LRValue(""), depth=1),
         # unit types
         "v": T.LRValue(),
         "v[]": T.LRValue(""),
         "v[m/s]": T.LRValue("m/s"),
         "c": T.LRComplex(),
         "c[]": T.LRComplex(""),
         "c[m/s]": T.LRComplex("m/s"),
         # errors
         "E": T.LRError(),
         "Ew": T.LRError(T.LRWord()),
         "E(w)": T.LRError(T.LRCluster(T.LRWord())),
         # more complex stuff
         "*b*i": T.LRCluster(T.LRList(T.LRBool()), T.LRList(T.LRInt())),
     }
     for tag, type_ in tests.items():
         self.assertEqual(T.parseTypeTag(tag), type_)
         newtag = str(type_)
         if isinstance(type_, T.LRCluster) and tag[0] + tag[-1] != "()":
             # just added parentheses in this case
             self.assertEqual(newtag, "(%s)" % tag)
         else:
             self.assertEqual(newtag, tag)
Exemplo n.º 26
0
def combine_type_tags(tags):
    """Combine one or more type tag strings into a single type tag.

    We cannot simply concatenate the tag strings because some of the input tags
    may have trailing comments.

    Args:
        tags (iterable[str]): The type tags to be combined into one type.

    Returns:
        (string): A tag representing a cluster of the given tags.
    """
    if len(tags) == 1:
        return tags[0]

    types = [T.parseTypeTag(tag) for tag in tags]
    return str(T.LRCluster(*types))
Exemplo n.º 27
0
def combine_type_tags(tags):
    """Combine one or more type tag strings into a single type tag.

    We cannot simply concatenate the tag strings because some of the input tags
    may have trailing comments.

    Args:
        tags (iterable[str]): The type tags to be combined into one type.

    Returns:
        (string): A tag representing a cluster of the given tags.
    """
    if len(tags) == 1:
        return tags[0]

    types = [T.parseTypeTag(tag) for tag in tags]
    return str(T.TCluster(*types))
Exemplo n.º 28
0
 def testTypeHints(self):
     """Test conversion to specified allowed types."""
     passingTests = [
         # convert to default type
         (1, [], "i"),
         # convert to first compatible type
         (1, ["s", "w"], "w"),
         (1, ["s", "v"], "v[]"),
         (1 * U.m, ["s", "v[m]"], "v[m]"),
         # 'v' not allowed on wire
         (3.0, "v", "v[]"),
         (3, "v", "v[]"),
         # empty list gets type from hint
         ([], ["s", "*(ww)"], "*(ww)"),
         # handle unknown pieces inside clusters and lists
         (["a", "b"], ["*?"], "*s"),
         ((1, 2, "a"), ["ww?"], "wws"),
         ((1, 1L), ["??"], "iw"),
     ]
     for data, hints, tag in passingTests:
         self.assertEqual(T.flatten(data, hints)[1], T.parseTypeTag(tag))
Exemplo n.º 29
0
    def testTypeHints(self):
        """Test conversion to specified allowed types."""
        passingTests = [
            # convert to default type
            (1, [], 'i'),

            # convert to first compatible type
            (1, ['s', 'w'], 'w'),
            (1, ['s', 'v'], 'v[]'),
            (1 * U.m, ['s', 'v[m]'], 'v[m]'),
            # 'v' not allowed on wire
            (3.0, 'v', 'v[]'),
            (3, 'v', 'v[]'),

            # empty list gets type from hint
            ([], ['s', '*(ww)'], '*(ww)'),

            # handle unknown pieces inside clusters and lists
            (['a', 'b'], ['*?'], '*s'),
            ((1, 2, 'a'), ['ww?'], 'wws'),
            ((1, 1L), ['??'], 'iw'),
        ]
        for data, hints, tag in passingTests:
            self.assertEqual(T.flatten(data, hints)[1], T.parseTypeTag(tag))
Exemplo n.º 30
0
    def decorated(f):
        args, varargs, varkw, defaults = inspect.getargspec(f)
        args = args[lr_num_params:]

        # handle generators as defer.inlineCallbacks
        if inspect.isgeneratorfunction(f):
            f = defer.inlineCallbacks(f)

        # make sure that defined params are actually accepted by the function.
        # having extra params would not affect the running, but it is
        # unnecessary and hence may indicate other problems with the code
        for p in params:
            if p not in args:
                raise Exception("'%s' is not a valid parameter." % p)
            # turn single string annotations into lists
            if isinstance(params[p], str):
                params[p] = [params[p]]

        Nparams = len(args)
        Noptional = 0 if defaults is None else len(defaults)
        Nrequired = Nparams - Noptional

        if Nparams == 0:
            accepts_s = ['']  # only accept notifier
            accepts_t = [T.parseTypeTag(s) for s in accepts_s]

            @functools.wraps(f)
            def handleRequest(self, c, data):
                return f(self, c)

        elif Nparams == 1:
            accepts_s = params.get(args[0], [])
            accepts_t = [T.parseTypeTag(s) for s in accepts_s]

            if Nrequired == 0:
                # if accepted types were specified, add '' to the list
                # we don't add '' if the list of accepted types is empty,
                # since this would make '' the ONLY accepted type
                if len(accepts_t) and T.TNone() not in accepts_t:
                    accepts_s.append(': defaults [%s=%r]' \
                                     % (args[0], defaults[0]))
                    accepts_t.append(T.TNone())

                @functools.wraps(f)
                def handleRequest(self, c, data):
                    if data is None:
                        return f(self, c)
                    return f(self, c, data)

            else:
                # nothing special to do here
                handleRequest = f

        else:
            # sanity checks to make sure that we'll be able to
            # correctly dispatch to the function when called
            if Nrequired <= 1:
                if args[0] not in params:
                    raise Exception('Must specify types for first argument '
                                    'when fewer than two args are required.')
                for s in params[args[0]]:
                    t = T.parseTypeTag(s)
                    if isinstance(t, (T.TAny, T.TCluster)):
                        raise Exception('Cannot accept cluster or ? in first '
                                        'arg when fewer than two args are '
                                        'required.')

            # '' is not allowed on first arg when Nrequired > 1
            types = [T.parseTypeTag(s) for s in params.get(args[0], [])]
            if Nrequired > 1 and T.TNone() in types:
                raise Exception("'' not allowed when more than "
                                "one arg is required.")

            # '' is never allowed on args after the first.
            for p in args[1:]:
                types = [T.parseTypeTag(s) for s in params.get(p, [])]
                if T.TNone() in types:
                    raise Exception("'' not allowed after first arg.")

            # allowed types are as follows:
            # one type for each parameter, with the number of
            # parameters ranging from the total number down to
            # and including the required number
            # we don't include any zero-length group
            groups = []
            for n in range(Nparams, Nrequired - 1, -1):
                lists = [params.get(a, ['?']) for a in args[:n]]
                if len(lists):
                    groups += _product(lists)
                for i, group in reversed(list(enumerate(groups))):
                    # if there are any TNones in the group, we remove it
                    ts = [T.parseTypeTag(t) for t in group]
                    if T.TNone() in ts:
                        groups.pop(i)

            accepts_t = []
            accepts_s = []
            for group in groups:
                if len(group) > 1:
                    t = T.TCluster(*[T.parseTypeTag(t) for t in group])
                    s = ', '.join('%s{%s}' % (sub_t, arg)
                                  for sub_t, arg in zip(t, args))
                    s = '(%s)' % s
                else:
                    t = T.parseTypeTag(group[0])
                    if isinstance(t, T.TCluster):
                        raise Exception("Can't accept cluster in first param.")
                    s = '%s{%s}' % (group[0], args[0])
                # add information about default values of unused params
                if len(group) < Nparams:
                    defstr = ', '.join('%s=%r' %
                                       (args[n], defaults[n - Nrequired])
                                       for n in range(len(group), Nparams))
                    s = s + ': defaults [%s]' % defstr
                accepts_t.append(t)
                accepts_s.append(s)

            if Nrequired == 0:
                if T.TNone() not in accepts_t:
                    defstr = ', '.join('%s=%r' % (a, d)
                                       for a, d in zip(args, defaults))
                    accepts_s.append(': defaults [%s]' % defstr)
                    accepts_t.append(T.TNone())

                @functools.wraps(f)
                def handleRequest(self, c, data):
                    if isinstance(data, tuple):
                        return f(self, c, *data)
                    elif data is None:
                        return f(self, c)
                    else:
                        return f(self, c, data)
            else:

                @functools.wraps(f)
                def handleRequest(self, c, data):
                    if isinstance(data, tuple):
                        return f(self, c, *data)
                    else:
                        return f(self, c, data)

        f.ID = lr_ID
        f.name = lr_name or f.__name__
        f.accepts = accepts_s
        f.returns = returns
        f.handleRequest = handleRequest

        # this is the data that will be sent to the manager to
        # register this setting to be remotely callable
        f.description, f.notes = util.parseSettingDoc(f.__doc__)

        def getRegistrationInfo():
            return (f.ID, f.name, f.description, f.accepts, f.returns, f.notes)

        f.getRegistrationInfo = getRegistrationInfo

        return f
Exemplo n.º 31
0
def test_setting_types_with_comments():
    accepted_tags = DummyServer.dummy_setting.accepts
    accepted_types = [types.parseTypeTag(s) for s in accepted_tags]
    assert len(accepted_types) == 1
    assert accepted_types[0] == types.parseTypeTag('sb')
Exemplo n.º 32
0
    def __init__(self, func, lr_ID, lr_name, returns, unflatten, **params):
        """Setting constructor
        Args:

            func (callable):   Function to implement the setting.
            lr_ID (int):       The ID number of the setting used in the labrad
                               protocol
            lr_name (str):     The setting name.  By default, this is derived
                               from the function name.
            returns:           The labrad type tag or list of tags the setting
                               returns
            unflatten (bool):  Request automatic unflattening of incoming data.
                               (default True)
            **params:          Additional keyword arguments indicate arguments
                               to the setting.  Each keyword should be a string
                               matching one of the formal parameters of func,
                               while the value is the type tag or list of tags
                               accepted by that parameter.

        If unflattening is requested, pylabrad will use the default unflattening
        for the data.  Otherwise, arguments will receive FlatData objects.  If
        there are multiple arguments, the top-level tuple will still be
        unpacked."""

        self.func = func
        self.ID = lr_ID
        self.name = lr_name or func.__name__
        self.returns = [returns] if isinstance(returns,
                                               basestring) else returns
        self.unflatten = unflatten
        self.description, self.notes = util.parseSettingDoc(func.__doc__)
        self.__doc__ = "Setting wrapper for {}\n\n{}".format(
            func.__name__, func.__doc__)

        ###
        # We need to validate the arguments.  Things we need to checks:
        #
        # 1) All parameters must match function arguments
        # 2) Function arguments with no specified parameter default to '?'
        # 3) The empty tag '' is only allowd on the first argument, and only
        #    if all other arguments are optional.
        # 4) If more than one argument are required, we expect to always receive
        #    a tuple and unpack it
        # 5) If only a single argument is allowed, we never unpack tuples
        # 6) If both =1 and >1 arguments are allowed, it is ambiguous whether to
        #    unpack tuples, so this case is not allowed:  The first argument
        #    cannot be a tuple or '?' tag if the second argument is optional.

        argspec = inspect.getargspec(self.func)
        args = argspec.args[2:]  # Skip 'self' and context data arguments.

        if inspect.isgeneratorfunction(func):
            self.func = defer.inlineCallbacks(func)

        for arg in args:
            if arg not in params:
                params[arg] = ['?']

        for p in params.keys():
            if p not in args:
                raise ValueError(
                    "Setting parameter {} not accepted by function".format(p))
            if isinstance(params[p], basestring):
                params[p] = [params[p]]

        Nparams = len(args)
        Noptional = len(argspec.defaults) if argspec.defaults else 0
        Nrequired = Nparams - Noptional

        if Nrequired > 1:
            self.expand_cluster = "always"
        elif Nparams > 1:
            self.expand_cluster = "optional"
        else:  # one or fewer arguments
            self.expand_cluster = "never"

        self.allow_none = Nrequired == 0

        if Nparams:
            for tag in params[args[0]]:
                tt = T.parseTypeTag(tag)
                if isinstance(tt, T.TNone) and Nrequired > 1:
                    raise ValueError(
                        "First argument {} cannot accept '' "
                        "unless other arguments are optional".format(args[0]))
                if isinstance(
                        tt,
                    (T.TAny,
                     T.TCluster)) and self.expand_cluster == "optional":
                    raise ValueError(
                        "First argument {} cannot accept type {} "
                        "because other arguments are optional".format(
                            args[0], tt))
            for arg in args[1:]:
                for tag in params[arg]:
                    if isinstance(T.parseTypeTag(tag), T.TNone):
                        raise ValueError(
                            "Argument {} cannot accept ''".format(arg))

        # Build list of accepted data types.
        # This is basically every combination of accepted types for each agrument,
        # including omitting any number of trailing optional arguments.

        accepted_types = []
        for i in range(Nrequired, Nparams + 1):
            if i == 0:
                accepted_types.append('_')
            else:
                accept_tuples = itertools.product(
                    *[params[arg] for arg in args[:i]])
                accepted_types.extend(
                    combine_type_tags(x) for x in accept_tuples)
        self.accepts = accepted_types
Exemplo n.º 33
0
 def type_list(strs):
     return [T.parseTypeTag(s) for s in strs]
Exemplo n.º 34
0
from labrad import types as T

HEADER_TYPE = T.parseTypeTag('(ww)iww')
PACKET_TYPE = T.parseTypeTag('(ww)iws')
RECORD_TYPE = T.parseTypeTag('wss')

def packetStream(packetHandler, endianness='>'):
    """A generator that assembles packets.

    Accepts a function packetHandler that will be called with four arguments
    whenever a packet is completed: source, context, request, records.
    """
    buf = ''
    while True:
        # get packet header (20 bytes)
        while len(buf) < 20:
            buf += yield 0
        hdr, buf = buf[:20], buf[20:]
        context, request, source, length = T.unflatten(hdr, HEADER_TYPE, endianness=endianness)

        # get packet data
        while len(buf) < length:
            buf += yield 0
        s, buf = buf[:length], buf[length:]

        # unflatten the data
        records = unflattenRecords(s, endianness=endianness)

        packetHandler(source, context, request, records)

def unflattenPacket(data, endianness='>'):
Exemplo n.º 35
0
def test_setting_types_with_comments():
    accepted_tags = DummyServer.dummy_setting.accepts
    accepted_types = [types.parseTypeTag(s) for s in accepted_tags]
    assert len(accepted_types) == 1
    assert accepted_types[0] == types.parseTypeTag('sb')
Exemplo n.º 36
0
 def _refresh(self):
     if not self._refreshed:
         info = self._mgr.getSettingInfoByName(self._server.ID, self.name)
         self.__doc__, self._accepts, self._returns, self._notes, self.ID = info
         self._refreshed = True
         self._accepts_type = [T.parseTypeTag(s) for s in self._accepts]
Exemplo n.º 37
0
    def __init__(self, func, lr_ID, lr_name, returns, unflatten, **params):
        """Setting constructor
        Args:

            func (callable):   Function to implement the setting.
            lr_ID (int):       The ID number of the setting used in the labrad
                               protocol
            lr_name (str):     The setting name.  By default, this is derived
                               from the function name.
            returns:           The labrad type tag or list of tags the setting
                               returns
            unflatten (bool):  Request automatic unflattening of incoming data.
                               (default True)
            **params:          Additional keyword arguments indicate arguments
                               to the setting.  Each keyword should be a string
                               matching one of the formal parameters of func,
                               while the value is the type tag or list of tags
                               accepted by that parameter.

        If unflattening is requested, pylabrad will use the default unflattening
        for the data.  Otherwise, arguments will receive FlatData objects.  If
        there are multiple arguments, the top-level tuple will still be
        unpacked."""

        self.func = func
        self.ID = lr_ID
        self.name = lr_name or func.__name__
        self.returns = [returns] if isinstance(returns, basestring) else returns
        self.unflatten = unflatten
        self.description, self.notes = util.parseSettingDoc(func.__doc__)
        self.__doc__ = "Setting wrapper for {}\n\n{}".format(func.__name__, func.__doc__)
        
        ###
        # We need to validate the arguments.  Things we need to checks:
        #
        # 1) All parameters must match function arguments
        # 2) Function arguments with no specified parameter default to '?'
        # 3) The empty tag '' is only allowd on the first argument, and only
        #    if all other arguments are optional.
        # 4) If more than one argument are required, we expect to always receive
        #    a tuple and unpack it
        # 5) If only a single argument is allowed, we never unpack tuples
        # 6) If both =1 and >1 arguments are allowed, it is ambiguous whether to
        #    unpack tuples, so this case is not allowed:  The first argument
        #    cannot be a tuple or '?' tag if the second argument is optional.
        
        argspec = inspect.getargspec(self.func)
        args = argspec.args[2:] # Skip 'self' and context data arguments.

        if inspect.isgeneratorfunction(func):
            self.func = defer.inlineCallbacks(func)

        for arg in args:
            if arg not in params:
                params[arg] = ['?']

        for p in params.keys():
            if p not in args:
                raise ValueError("Setting parameter {} not accepted by function".format(p))
            if isinstance(params[p], basestring):
                params[p] = [params[p]]

        Nparams = len(args)
        Noptional = len(argspec.defaults) if argspec.defaults else 0
        Nrequired = Nparams - Noptional

        if Nrequired > 1:
            self.expand_cluster = "always"
        elif Nparams > 1:
            self.expand_cluster = "optional"
        else: # one or fewer arguments
            self.expand_cluster = "never"

        self.allow_none = Nrequired == 0

        if Nparams:
            for tag in params[args[0]]:
                tt = T.parseTypeTag(tag)
                if isinstance(tt, T.LRNone) and Nrequired > 1:
                    raise ValueError("First argument {} cannot accept '' "
                          "unless other arguments are optional".format(args[0]))
                if isinstance(tt, (T.LRAny, T.LRCluster)) and self.expand_cluster=="optional":
                    raise ValueError("First argument {} cannot accept type {} "
                          "because other arguments are optional".format(args[0], tt))
            for arg in args[1:]:
                for tag in params[arg]:
                    if isinstance(T.parseTypeTag(tag), T.LRNone):
                        raise ValueError("Argument {} cannot accept ''".format(arg))

        # Build list of accepted data types.
        # This is basically every combination of accepted types for each agrument,
        # including omitting any number of trailing optional arguments.

        accepted_types = []
        for i in range(Nrequired, Nparams+1):
            if i == 0:
                accepted_types.append('_')
            else:
                accept_tuples = itertools.product(*[params[arg] for arg in args[:i]])
                accepted_types.extend(combine_type_tags(x) for x in accept_tuples)
        self.accepts = accepted_types
Exemplo n.º 38
0
    def decorated(f):
        args, varargs, varkw, defaults = inspect.getargspec(f)
        args = args[lr_num_params:]

        # handle generators as defer.inlineCallbacks
        if inspect.isgeneratorfunction(f):
            f = defer.inlineCallbacks(f)

        # make sure that defined params are actually accepted by the function.
        # having extra params would not affect the running, but it is
        # unnecessary and hence may indicate other problems with the code
        for p in params:
            if p not in args:
                raise Exception("'%s' is not a valid parameter." % p)
            # turn single string annotations into lists
            if isinstance(params[p], str):
                params[p] = [params[p]]

        Nparams = len(args)
        Noptional = 0 if defaults is None else len(defaults)
        Nrequired = Nparams - Noptional

        if Nparams == 0:
            accepts_s = [''] # only accept notifier
            accepts_t = [T.parseTypeTag(s) for s in accepts_s]

            @functools.wraps(f)
            def handleRequest(self, c, data):
                return f(self, c)

        elif Nparams == 1:
            accepts_s = params.get(args[0], [])
            accepts_t = [T.parseTypeTag(s) for s in accepts_s]

            if Nrequired == 0:
                # if accepted types were specified, add '' to the list
                # we don't add '' if the list of accepted types is empty,
                # since this would make '' the ONLY accepted type
                if len(accepts_t) and T.LRNone() not in accepts_t:
                    accepts_s.append(': defaults [%s=%r]' \
                                     % (args[0], defaults[0]))
                    accepts_t.append(T.LRNone())

                @functools.wraps(f)
                def handleRequest(self, c, data):
                    if data is None:
                        return f(self, c)
                    return f(self, c, data)

            else:
                # nothing special to do here
                handleRequest = f

        else:
            # sanity checks to make sure that we'll be able to
            # correctly dispatch to the function when called
            if Nrequired <= 1:
                if args[0] not in params:
                    raise Exception('Must specify types for first argument '
                                    'when fewer than two args are required.')
                for s in params[args[0]]:
                    t = T.parseTypeTag(s)
                    if isinstance(t, (T.LRAny, T.LRCluster)):
                        raise Exception('Cannot accept cluster or ? in first '
                                        'arg when fewer than two args are '
                                        'required.')

            # '' is not allowed on first arg when Nrequired > 1
            types = [T.parseTypeTag(s) for s in params.get(args[0], [])]
            if Nrequired > 1 and T.LRNone() in types:
                raise Exception("'' not allowed when more than "
                                "one arg is required.")

            # '' is never allowed on args after the first.
            for p in args[1:]:
                types = [T.parseTypeTag(s) for s in params.get(p, [])]
                if T.LRNone() in types:
                    raise Exception("'' not allowed after first arg.")

            # allowed types are as follows:
            # one type for each parameter, with the number of
            # parameters ranging from the total number down to
            # and including the required number
            # we don't include any zero-length group
            groups = []
            for n in range(Nparams, Nrequired-1, -1):
                lists = [params.get(a, ['?']) for a in args[:n]]
                if len(lists):
                    groups += _product(lists)
                for i, group in reversed(list(enumerate(groups))):
                    # if there are any LRNones in the group, we remove it
                    ts = [T.parseTypeTag(t) for t in group]
                    if T.LRNone() in ts:
                        groups.pop(i)

            accepts_t = []
            accepts_s = []
            for group in groups:
                if len(group) > 1:
                    t = T.LRCluster(*[T.parseTypeTag(t) for t in group])
                    s = ', '.join('%s{%s}' % (sub_t, arg)
                                  for sub_t, arg in zip(t, args))
                    s = '(%s)' % s
                else:
                    t = T.parseTypeTag(group[0])
                    if isinstance(t, T.LRCluster):
                        raise Exception("Can't accept cluster in first param.")
                    s = '%s{%s}' % (group[0], args[0])
                # add information about default values of unused params
                if len(group) < Nparams:
                    defstr = ', '.join('%s=%r' % (args[n], defaults[n-Nrequired])
                                       for n in range(len(group), Nparams))
                    s = s + ': defaults [%s]' % defstr
                accepts_t.append(t)
                accepts_s.append(s)

            if Nrequired == 0:
                if T.LRNone() not in accepts_t:
                    defstr = ', '.join('%s=%r' % (a, d)
                                       for a, d in zip(args, defaults))
                    accepts_s.append(': defaults [%s]' % defstr)
                    accepts_t.append(T.LRNone())

                @functools.wraps(f)
                def handleRequest(self, c, data):
                    if isinstance(data, tuple):
                        return f(self, c, *data)
                    elif data is None:
                        return f(self, c)
                    else:
                        return f(self, c, data)
            else:
                @functools.wraps(f)
                def handleRequest(self, c, data):
                    if isinstance(data, tuple):
                        return f(self, c, *data)
                    else:
                        return f(self, c, data)

        f.ID = lr_ID
        f.name = lr_name or f.__name__
        f.accepts = accepts_s
        f.returns = returns
        f.handleRequest = handleRequest

        # this is the data that will be sent to the manager to
        # register this setting to be remotely callable
        f.description, f.notes = util.parseSettingDoc(f.__doc__)
        def getRegistrationInfo():
            return (f.ID, f.name, f.description,
                    f.accepts, f.returns, f.notes)
        f.getRegistrationInfo = getRegistrationInfo

        return f
Exemplo n.º 39
0
 def type_list(strs):
     return [T.parseTypeTag(s) for s in strs]
Exemplo n.º 40
0
 def _refresh(self):
     if not self._refreshed:
         info = self._mgr.getSettingInfoByName(self._server.ID, self.name)
         self.__doc__, self._accepts, self._returns, self._notes, self.ID = info
         self._refreshed = True
         self._accepts_type = [T.parseTypeTag(s) for s in self._accepts]