Ejemplo n.º 1
0
    def validate(self, obj, value):
        """ Determine if :obj:`value` is a valid value

        Args:
            obj (:obj:`Model`): class being validated
            value (:obj:`numpy.array`): value of attribute to validate

        Returns:
            :obj:`core.InvalidAttribute` or None: None if attribute is valid, other return
                list of errors as an instance of :obj:`core.InvalidAttribute`
        """
        errors = []

        if value is not None and not isinstance(
                value, Bio.SeqFeature.FeatureLocation):
            errors.append(
                'Value must be an instance of `Bio.SeqFeature.FeatureLocation`'
            )

        if self.primary and value is None:
            errors.append(
                '{} value for primary attribute cannot be empty'.format(
                    self.__class__.__name__))

        if errors:
            return core.InvalidAttribute(self, errors)
        return None
Ejemplo n.º 2
0
    def deserialize(self, value):
        """ Deserialize value

        Args:
            value (:obj:`str`): semantically equivalent representation

        Returns:
            :obj:`tuple` of :obj:`numpy.array`, :obj:`core.InvalidAttribute` or :obj:`None`: tuple of cleaned value and cleaning error
        """
        if value is None or value == '':
            value = None
            error = None
        elif isinstance(value, str):
            start, end, strand = map(int, value.split(','))
            value = Bio.SeqFeature.FeatureLocation(start, end, strand)
            error = None
        elif isinstance(value, (list, tuple)):
            stand, end, strand = value
            value = Bio.SeqFeature.FeatureLocation(stand, end, strand)
            error = None
        elif isinstance(value, Bio.SeqFeature.FeatureLocation):
            error = None
        else:
            value = None
            error = core.InvalidAttribute(self, [(
                'FeatureLocAttribute must be None, an empty string, '
                'a comma-separated string representation of a tuple, a tuple, a list, '
                'or a Bio.SeqFeature.FeatureLocation')])
        return (value, error)
Ejemplo n.º 3
0
    def test_SymbolicBasicAttribute(self):
        class Node(core.Model):
            value = obj_tables.math.symbolic.SymbolicBasicAttribute()

        attr = Node.Meta.attributes['value']

        # constructor
        attr2 = obj_tables.math.symbolic.SymbolicBasicAttribute(default=None)
        self.assertEqual(attr2.get_default(), None)

        attr2 = obj_tables.math.symbolic.SymbolicBasicAttribute(default=sympy.Basic('x'))
        self.assertEqual(attr2.get_default(), sympy.Basic('x'))

        with self.assertRaisesRegex(ValueError, 'Default must be a '):
            obj_tables.math.symbolic.SymbolicBasicAttribute(default='x')

        # deserialize
        self.assertEqual(attr.deserialize(''), (None, None))
        self.assertEqual(attr.deserialize(None), (None, None))
        self.assertEqual(attr.deserialize('x'), (sympy.Basic('x'), None))

        # serialize
        self.assertEqual(attr.serialize(''), '')
        self.assertEqual(attr.serialize(None), '')
        self.assertEqual(attr.serialize(sympy.Basic('x')), 'x')

        # deserialize + serialize
        self.assertEqual(attr.serialize(attr.deserialize('')[0]), '')
        self.assertEqual(attr.serialize(attr.deserialize(None)[0]), '')
        self.assertEqual(attr.serialize(attr.deserialize('x')[0]), 'x')

        # validate
        node = Node()
        self.assertEqual(attr.validate(node, ''), None)
        self.assertEqual(attr.validate(node, None), None)
        self.assertEqual(attr.validate(node, sympy.Basic('x')), None)
        self.assertNotEqual(attr.validate(node, 'x'), None)

        with mock.patch.object(core.Attribute, 'validate', return_value=core.InvalidAttribute(None, [])):
            obj = None
            attr2 = obj_tables.math.symbolic.SymbolicBasicAttribute()
            self.assertEqual(attr2.validate(obj, None), None)

        attr2 = obj_tables.math.symbolic.SymbolicBasicAttribute(primary=True)
        self.assertNotEqual(attr2.validate(node, ''), None)
        self.assertNotEqual(attr2.validate(node, None), None)

        # validate_unique
        nodes = [Node(), Node()]
        self.assertEqual(attr.validate_unique(nodes, [sympy.Basic('x'), sympy.Basic('y')]), None)
        self.assertNotEqual(attr.validate_unique(nodes, [sympy.Basic('x'), sympy.Basic('x')]), None)

        # to/from JSON
        self.assertEqual(attr.to_builtin(None), None)
        self.assertEqual(attr.to_builtin(sympy.Basic('x')), 'x')
        self.assertEqual(attr.from_builtin(None), None)
        self.assertEqual(attr.from_builtin('x'), sympy.Basic('x'))
        self.assertEqual(attr.from_builtin(attr.to_builtin(sympy.Basic('x'))), sympy.Basic('x'))
Ejemplo n.º 4
0
    def validate(self, obj, value):
        """ Determine if :obj:`value` is a valid value

        Args:
            obj (:obj:`Model`): class being validated
            value (:obj:`Bio.motifs.matrix.FrequencyPositionMatrix`): value of attribute to validate

        Returns:
            :obj:`core.InvalidAttribute` or :obj:`None`: None if attribute is valid, otherwise return list
                of errors as an instance of :obj:`core.InvalidAttribute`
        """
        if value is not None and not isinstance(
                value, Bio.motifs.matrix.FrequencyPositionMatrix):
            return core.InvalidAttribute(self, [
                'Value must be an instance of `Bio.motifs.matrix.FrequencyPositionMatrix`'
            ])
        return None
Ejemplo n.º 5
0
    def validate(self, obj, value):
        """ Determine if :obj:`value` is a valid value

        Args:
            obj (:obj:`Model`): class being validated
            value (:obj:`Bio.Seq.Seq`): value of attribute to validate

        Returns:
            :obj:`core.InvalidAttribute` or None: None if attribute is valid, other return
                list of errors as an instance of :obj:`core.InvalidAttribute`
        """
        errors = []

        if value is not None:
            if not isinstance(value, Bio.Seq.Seq):
                errors.append('Value must be an instance of `Bio.Seq.Seq`')
            elif self.alphabet and (
                    value.alphabet.__class__ != self.alphabet.__class__
                    or value.alphabet.letters != self.alphabet.letters
                    or value.alphabet.size != self.alphabet.size):
                errors.append(
                    'The alphabet of value must be an instance of `{}`'.format(
                        self.alphabet.__class__.__name__))

        if self.min_length and (not value or len(value) < self.min_length):
            errors.append('Value must be at least {:d} characters'.format(
                self.min_length))

        if self.max_length and value and len(value) > self.max_length:
            errors.append('Value must be less than {:d} characters'.format(
                self.max_length))

        if self.primary and (not value or len(value) == 0):
            errors.append(
                '{} value for primary attribute cannot be empty'.format(
                    self.__class__.__name__))

        if errors:
            return core.InvalidAttribute(self, errors)
        return None
Ejemplo n.º 6
0
    def deserialize(self, values, objects, decoded=None):
        """ Deserialize value

        Args:
            values (:obj:`object`): String representation of related objects
            objects (:obj:`dict`): dictionary of objects, grouped by model
            decoded (:obj:`dict`, optional): dictionary of objects that have already been decoded

        Returns:
            :obj:`tuple` of :obj:`object`, :obj:`core.InvalidAttribute` or :obj:`None`: tuple of cleaned value and cleaning error
        """
        if values in [None, '']:
            return ([], None)

        try:
            tree = self.parser.parse(values)
            self.Transformer = self.Transformer or self.gen_transformer(self.related_class)
            transformer = self.Transformer(objects)
            result = transformer.transform(tree)
            return (result, None)
        except lark.exceptions.LarkError as err:
            return (None, core.InvalidAttribute(self, [str(err)]))
Ejemplo n.º 7
0
    def deserialize(self, value):
        """ Deserialize value

        Args:
            value (:obj:`str`): string representation

        Returns:
            :obj:`tuple` of :obj:`Bio.motifs.matrix.FrequencyPositionMatrix`, :obj:`core.InvalidAttribute` or :obj:`None`:
                tuple of cleaned value and cleaning error
        """
        if value:
            try:
                dict_value = json.loads(value)

                alphabet = dict_value['_alphabet']
                dict_value.pop('_alphabet')

                return (Bio.motifs.matrix.FrequencyPositionMatrix(
                    alphabet, dict_value), None)
            except Exception as error:
                return (None, core.InvalidAttribute(self, [str(error)]))
        else:
            return (None, None)
Ejemplo n.º 8
0
    def test(self):
        # constructor
        attr = obj_tables.math.numeric.ArrayAttribute()
        self.assertEqual(attr.get_default(), None)

        attr = obj_tables.math.numeric.ArrayAttribute(
            default=numpy.array([1, 2]))
        numpy.testing.assert_equal(attr.get_default(), numpy.array([1, 2]))

        with self.assertRaisesRegex(
                ValueError, '`default` must be a `numpy.array` or `None`'):
            obj_tables.math.numeric.ArrayAttribute(default=[1, 2])

        with self.assertRaisesRegex(
                ValueError, '`min_length` must be a non-negative integer'):
            obj_tables.math.numeric.ArrayAttribute(min_length=-1)

        with self.assertRaisesRegex(
                ValueError,
                '`max_length` must be an integer greater than or equal to `min_length`'
        ):
            obj_tables.math.numeric.ArrayAttribute(min_length=10, max_length=5)

        # deserialize
        attr = obj_tables.math.numeric.ArrayAttribute()
        self.assertEqual(attr.deserialize(None), (None, None))
        self.assertEqual(attr.deserialize(''), (None, None))
        numpy.testing.assert_equal(attr.deserialize('[1, 2, 3]'),
                                   (numpy.array([1, 2, 3]), None))
        numpy.testing.assert_equal(attr.deserialize((1, 2, 3)),
                                   (numpy.array([1, 2, 3]), None))
        numpy.testing.assert_equal(attr.deserialize([1., 2., 3.]),
                                   (numpy.array([1., 2., 3.]), None))
        numpy.testing.assert_equal(attr.deserialize(numpy.array([1., 2., 3.])),
                                   (numpy.array([1., 2., 3.]), None))

        attr = obj_tables.math.numeric.ArrayAttribute(default=numpy.ones((1,
                                                                          1)))
        self.assertEqual(attr.deserialize(None), (None, None))
        self.assertEqual(attr.deserialize(''), (None, None))
        numpy.testing.assert_equal(
            attr.deserialize('[1, 2, 3]'),
            (numpy.array([1, 2, 3], numpy.float64), None))
        numpy.testing.assert_equal(attr.deserialize(
            (1, 2, 3)), (numpy.array([1, 2, 3], numpy.float64), None))
        numpy.testing.assert_equal(attr.deserialize(
            [1, 2, 3]), (numpy.array([1, 2, 3], numpy.float64), None))
        numpy.testing.assert_equal(attr.deserialize(numpy.array(
            [1, 2, 3])), (numpy.array([1., 2., 3.], numpy.float64), None))

        self.assertNotEqual(attr.deserialize('x')[1], None)
        self.assertNotEqual(attr.deserialize(1.)[1], None)

        # validate
        attr = obj_tables.math.numeric.ArrayAttribute()
        self.assertEqual(attr.validate(None, None), None)
        self.assertNotEqual(attr.validate(None, []), None)

        attr = obj_tables.math.numeric.ArrayAttribute(
            default=numpy.array([1., 2.], numpy.float64))
        self.assertNotEqual(
            attr.validate(None, numpy.array([1, 2], numpy.int64)), None)

        attr = obj_tables.math.numeric.ArrayAttribute(min_length=2,
                                                      max_length=5)
        self.assertEqual(attr.validate(None, numpy.array([1, 2])), None)
        self.assertNotEqual(attr.validate(None, numpy.array([1])), None)
        self.assertNotEqual(
            attr.validate(None, numpy.array([1, 2, 3, 4, 5, 6])), None)

        attr = obj_tables.math.numeric.ArrayAttribute(primary=True)
        self.assertNotEqual(attr.validate(None, None), None)

        with mock.patch.object(core.Attribute,
                               'validate',
                               return_value=core.InvalidAttribute(None, [])):
            obj = None
            attr = obj_tables.math.numeric.ArrayAttribute()
            self.assertEqual(attr.validate(obj, None), None)

        # validate unique
        attr = obj_tables.math.numeric.ArrayAttribute()
        self.assertEqual(
            attr.validate_unique(
                [],
                [numpy.array([1, 2]), numpy.array([2, 3])]), None)
        self.assertEqual(attr.validate_unique([], [numpy.array([1, 2]), None]),
                         None)
        self.assertNotEqual(
            attr.validate_unique(
                [],
                [numpy.array([1, 2]), numpy.array([1, 2])]), None)
        self.assertNotEqual(attr.validate_unique([], [None, None]), None)

        # serialize
        attr = obj_tables.math.numeric.ArrayAttribute()
        numpy.testing.assert_equal(
            attr.deserialize(attr.serialize(numpy.array([1, 2])))[0],
            numpy.array([1, 2]))
        numpy.testing.assert_equal(
            attr.deserialize(attr.serialize(numpy.array([1., 2.])))[0],
            numpy.array([1., 2.]))

        # to/from JSON
        self.assertEqual(attr.to_builtin(None), None)
        self.assertEqual(attr.to_builtin(numpy.array([1, 2])), [1, 2])
        self.assertEqual(attr.from_builtin(None), None)
        numpy.testing.assert_equal(attr.from_builtin([1, 2]),
                                   numpy.array([1, 2]))
        numpy.testing.assert_equal(
            attr.from_builtin(attr.to_builtin(numpy.array([1, 2]))),
            numpy.array([1, 2]))

        attr = obj_tables.math.numeric.ArrayAttribute(primary=True,
                                                      default=numpy.array(
                                                          [1.1, 2.2]))
        numpy.testing.assert_equal(attr.from_builtin([1, 2]),
                                   numpy.array([1, 2]))
Ejemplo n.º 9
0
    def test_FeatureLocAttribute(self):
        # construction
        attr = obj_tables.bio.seq.FeatureLocAttribute()
        self.assertEqual(attr.get_default(), None)

        attr = obj_tables.bio.seq.FeatureLocAttribute(
            default=Bio.SeqFeature.FeatureLocation(10, 10, 1))
        self.assertEqual(attr.get_default(),
                         Bio.SeqFeature.FeatureLocation(10, 10, 1))

        with self.assertRaisesRegex(
                ValueError,
                '`default` must be a `Bio.SeqFeature.FeatureLocation`'):
            obj_tables.bio.seq.FeatureLocAttribute(default='')

        # deserialize
        attr = obj_tables.bio.seq.FeatureLocAttribute()
        self.assertEqual(attr.deserialize(None), (None, None))
        self.assertEqual(attr.deserialize(''), (None, None))
        self.assertEqual(attr.deserialize('10,10,1'),
                         (Bio.SeqFeature.FeatureLocation(10, 10, 1), None))
        self.assertEqual(attr.deserialize((10, 10, 1)),
                         (Bio.SeqFeature.FeatureLocation(10, 10, 1), None))
        self.assertEqual(attr.deserialize([10, 10, 1]),
                         (Bio.SeqFeature.FeatureLocation(10, 10, 1), None))
        self.assertEqual(
            attr.deserialize(Bio.SeqFeature.FeatureLocation(10, 10, 1)),
            (Bio.SeqFeature.FeatureLocation(10, 10, 1), None))
        self.assertEqual(attr.deserialize(1)[0], None)
        self.assertNotEqual(attr.deserialize(1)[1], None)

        # validate
        obj = None
        attr = obj_tables.bio.seq.FeatureLocAttribute()
        self.assertEqual(attr.validate(obj, None), None)
        self.assertEqual(
            attr.validate(obj, Bio.SeqFeature.FeatureLocation(10, 10, 1)),
            None)
        self.assertNotEqual(attr.validate(obj, 1), None)

        attr = obj_tables.bio.seq.FeatureLocAttribute(primary=True)
        self.assertNotEqual(attr.validate(obj, None), None)

        with mock.patch.object(core.Attribute,
                               'validate',
                               return_value=core.InvalidAttribute(None, [])):
            obj = None
            attr = obj_tables.bio.seq.FeatureLocAttribute()
            self.assertEqual(attr.validate(obj, None), None)

        # validate unique
        attr = obj_tables.bio.seq.FeatureLocAttribute()
        self.assertEqual(
            attr.validate_unique([], [
                Bio.SeqFeature.FeatureLocation(10, 10, 1),
                None,
            ]), None)
        self.assertEqual(
            attr.validate_unique([], [
                Bio.SeqFeature.FeatureLocation(10, 10, 1),
                Bio.SeqFeature.FeatureLocation(1, 10, 1),
            ]), None)
        self.assertNotEqual(
            attr.validate_unique([], [
                Bio.SeqFeature.FeatureLocation(10, 10, 1),
                Bio.SeqFeature.FeatureLocation(10, 10, 1),
            ]), None)
        self.assertNotEqual(attr.validate_unique([], [
            None,
            None,
        ]), None)

        # serialize
        attr = obj_tables.bio.seq.FeatureLocAttribute()
        self.assertEqual(attr.serialize(None), '')
        self.assertEqual(
            attr.serialize(Bio.SeqFeature.FeatureLocation(10, 10, 1)),
            '10,10,1')

        self.assertEqual(attr.serialize(attr.deserialize('10,10,1')[0]),
                         '10,10,1')
        self.assertEqual(attr.serialize(attr.deserialize('')[0]), '')

        # to/from JSON
        ft = Bio.SeqFeature.FeatureLocation(100, 200, 1)
        ft2 = {
            'start': 100,
            'end': 200,
            'strand': 1,
        }
        self.assertEqual(attr.to_builtin(None), None)
        self.assertEqual(attr.to_builtin(ft), ft2)
        self.assertEqual(attr.from_builtin(None), None)
        self.assertEqual(attr.from_builtin(ft2), ft)
        self.assertEqual(attr.from_builtin(attr.to_builtin(ft)), ft)
Ejemplo n.º 10
0
    def test_SeqAttribute(self):
        class Node(core.Model):
            value = obj_tables.bio.seq.SeqAttribute()

        attr = Node.Meta.attributes['value']

        # constructor
        attr2 = obj_tables.bio.seq.SeqAttribute(default=None)
        self.assertEqual(attr2.get_default(), None)

        attr2 = obj_tables.bio.seq.SeqAttribute(default=Bio.Seq.Seq('acgt'))
        self.assertEqual(attr2.get_default(), Bio.Seq.Seq('acgt'))

        with self.assertRaisesRegex(
                ValueError, '`default` must be a `Bio.Seq.Seq` or `None`'):
            obj_tables.bio.seq.SeqAttribute(default='acgt')

        with self.assertRaisesRegex(
                ValueError, '`min_length` must be a non-negative integer'):
            obj_tables.bio.seq.SeqAttribute(min_length=-1)

        with self.assertRaisesRegex(
                ValueError,
                '`max_length` must be an integer greater than or equal to `min_length`'
        ):
            obj_tables.bio.seq.SeqAttribute(min_length=10, max_length=5)

        # deserialize
        self.assertEqual(attr.deserialize(''), (None, None))
        self.assertEqual(attr.deserialize(None), (None, None))

        alphabet = Bio.Alphabet.Alphabet()
        alphabet.letters = None
        alphabet.size = None
        self.assertEqual(
            attr.deserialize(
                '{"seq": "ATCG", "alphabet": {"type": "Alphabet", "letters": "", "size": ""}}'
            ), (Bio.Seq.Seq('ATCG', alphabet), None))

        alphabet = Bio.Alphabet.Alphabet()
        alphabet.letters = 'ACGT'
        alphabet.size = 1
        self.assertEqual(
            attr.deserialize(
                '{"seq": "ATCG", "alphabet": {"type": "Alphabet", "letters": "ACGT", "size": 1}}'
            ), (Bio.Seq.Seq('ATCG', alphabet), None))

        alphabet = Bio.Alphabet.Alphabet()
        alphabet.letters = ['AC', 'GT']
        alphabet.size = 2
        self.assertEqual(
            attr.deserialize(
                '{"seq": "ATCG", "alphabet": {"type": "Alphabet", "letters": ["AC", "GT"], "size": 2}}'
            ), (Bio.Seq.Seq('ATCG', alphabet), None))

        alphabet = Bio.Alphabet.ProteinAlphabet()
        alphabet.letters = None
        alphabet.size = 1
        self.assertEqual(
            attr.deserialize(
                '{"seq": "ATCG", "alphabet": {"type": "ProteinAlphabet", "letters": "", "size": 1}}'
            ), (Bio.Seq.Seq('ATCG', alphabet), None))

        alphabet = Bio.Alphabet.ProteinAlphabet()
        alphabet.letters = 'ARG'
        alphabet.size = 1
        self.assertEqual(
            attr.deserialize(
                '{"seq": "ATCG", "alphabet": {"type": "ProteinAlphabet", "letters": "ARG", "size": 1}}'
            ), (Bio.Seq.Seq('ATCG', alphabet), None))

        # serialize
        self.assertEqual(attr.serialize(None), '')
        self.assertEqual(
            json.loads(attr.serialize(Bio.Seq.Seq(''))), {
                "seq": "",
                "alphabet": {
                    "type": "Alphabet",
                    "letters": None,
                    "size": None
                }
            })
        self.assertEqual(
            json.loads(attr.serialize(Bio.Seq.Seq('ACGT'))), {
                "seq": "ACGT",
                "alphabet": {
                    "type": "Alphabet",
                    "letters": None,
                    "size": None
                }
            })

        alphabet = Bio.Alphabet.Alphabet()
        alphabet.letters = 'ACGT'
        alphabet.size = 1
        self.assertEqual(
            json.loads(attr.serialize(Bio.Seq.Seq('ACGT', alphabet))), {
                "seq": "ACGT",
                "alphabet": {
                    "type": "Alphabet",
                    "letters": "ACGT",
                    "size": 1
                }
            })

        alphabet = Bio.Alphabet.Alphabet()
        alphabet.letters = ['AC', 'GT']
        alphabet.size = 2
        self.assertEqual(
            json.loads(attr.serialize(Bio.Seq.Seq('ACGT', alphabet))), {
                "seq": "ACGT",
                "alphabet": {
                    "type": "Alphabet",
                    "letters": ["AC", "GT"],
                    "size": 2
                }
            })

        alphabet = Bio.Alphabet.ProteinAlphabet()
        alphabet.letters = ['AC', 'GT']
        alphabet.size = 2
        self.assertEqual(
            json.loads(attr.serialize(Bio.Seq.Seq('ACGT', alphabet))), {
                "seq": "ACGT",
                "alphabet": {
                    "type": "ProteinAlphabet",
                    "letters": ["AC", "GT"],
                    "size": 2
                }
            })

        # validate
        node = Node()
        self.assertEqual(attr.validate(node, None), None)
        self.assertNotEqual(attr.validate(node, ''), None)
        self.assertEqual(attr.validate(node, Bio.Seq.Seq('')), None)
        self.assertEqual(attr.validate(node, Bio.Seq.Seq('acgt')), None)

        attr.min_length = 2
        attr.max_length = 4
        self.assertNotEqual(attr.validate(node, Bio.Seq.Seq('A')), None)
        self.assertEqual(attr.validate(node, Bio.Seq.Seq('ACG')), None)
        self.assertNotEqual(attr.validate(node, Bio.Seq.Seq('ACGTA')), None)

        with mock.patch.object(core.Attribute,
                               'validate',
                               return_value=core.InvalidAttribute(None, [])):
            self.assertEqual(attr.validate(node, Bio.Seq.Seq('acgt')), None)

        attr2 = obj_tables.bio.seq.SeqAttribute(primary=True)
        self.assertNotEqual(attr2.validate(None, None), None)

        # validate_unique
        nodes = [Node(), Node()]
        values = [Bio.Seq.Seq('AA'), Bio.Seq.Seq('CC')]
        self.assertEqual(attr.validate_unique(nodes, values), None)

        nodes = [Node(), Node()]
        values = [Bio.Seq.Seq('AA'), Bio.Seq.Seq('AA')]
        self.assertNotEqual(attr.validate_unique(nodes, values), None)

        # to/from JSON
        seq = Bio.Seq.Seq('AA')
        seq2 = {
            'seq': 'AA',
            'alphabet': {
                'type': 'Alphabet',
                'letters': None,
                'size': None,
            }
        }
        self.assertEqual(attr.to_builtin(None), None)
        self.assertEqual(attr.to_builtin(seq), seq2)
        self.assertEqual(attr.from_builtin(None), None)
        self.assertEqual(attr.from_builtin(seq2), seq)
        self.assertEqual(attr.from_builtin(attr.to_builtin(seq)), seq)