File: checks.py

package info (click to toggle)
python-mido 1.3.3-0.2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 920 kB
  • sloc: python: 4,006; makefile: 127; sh: 4
file content (107 lines) | stat: -rw-r--r-- 2,904 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# SPDX-FileCopyrightText: 2016 Ole Martin Bjorndalen <ombdalen@gmail.com>
#
# SPDX-License-Identifier: MIT

from numbers import Integral, Real

from .specs import (
    MAX_PITCHWHEEL,
    MAX_SONGPOS,
    MIN_PITCHWHEEL,
    MIN_SONGPOS,
    SPEC_BY_TYPE,
)


def check_type(type_):
    if type_ not in SPEC_BY_TYPE:
        raise ValueError(f'invalid message type {type_!r}')


def check_channel(channel):
    if not isinstance(channel, Integral):
        raise TypeError('channel must be int')
    elif not 0 <= channel <= 15:
        raise ValueError('channel must be in range 0..15')


def check_pos(pos):
    if not isinstance(pos, Integral):
        raise TypeError('song pos must be int')
    elif not MIN_SONGPOS <= pos <= MAX_SONGPOS:
        raise ValueError('song pos must be in range {}..{}'.format(
                         MIN_SONGPOS, MAX_SONGPOS))


def check_pitch(pitch):
    if not isinstance(pitch, Integral):
        raise TypeError('pichwheel value must be int')
    elif not MIN_PITCHWHEEL <= pitch <= MAX_PITCHWHEEL:
        raise ValueError('pitchwheel value must be in range {}..{}'.format(
                         MIN_PITCHWHEEL, MAX_PITCHWHEEL))


def check_data(data_bytes):
    for byte in data_bytes:
        check_data_byte(byte)


def check_frame_type(value):
    if not isinstance(value, Integral):
        raise TypeError('frame_type must be int')
    elif not 0 <= value <= 7:
        raise ValueError('frame_type must be in range 0..7')


def check_frame_value(value):
    if not isinstance(value, Integral):
        raise TypeError('frame_value must be int')
    elif not 0 <= value <= 15:
        raise ValueError('frame_value must be in range 0..15')


def check_data_byte(value):
    if not isinstance(value, Integral):
        raise TypeError('data byte must be int')
    elif not 0 <= value <= 127:
        raise ValueError('data byte must be in range 0..127')


def check_time(time):
    if not isinstance(time, Real):
        raise TypeError('time must be int or float')


_CHECKS = {
    'channel': check_channel,
    'control': check_data_byte,
    'data': check_data,
    'frame_type': check_frame_type,
    'frame_value': check_frame_value,
    'note': check_data_byte,
    'pitch': check_pitch,
    'pos': check_pos,
    'program': check_data_byte,
    'song': check_data_byte,
    'time': check_time,
    'type': check_type,
    'value': check_data_byte,
    'velocity': check_data_byte,
}


def check_value(name, value):
    _CHECKS[name](value)


def check_msgdict(msgdict):
    spec = SPEC_BY_TYPE.get(msgdict['type'])
    if spec is None:
        raise ValueError('unknown message type {!r}'.format(msgdict['type']))

    for name, value in msgdict.items():
        if name not in spec['attribute_names']:
            raise ValueError(
                '{} message has no attribute {}'.format(spec['type'], name))

        check_value(name, value)