9009a7c5bc
- Created type stubs for various modules in the mido library including messages, midifiles, parser, ports, sockets, syx, tokenizer, and version. - Implemented type hints for functions and classes to improve type checking and code clarity. - Added support for MIDI over TCP/IP in sockets module. - Included methods for reading and writing SYX files in syx module. - Enhanced the parser functionality with a dedicated Parser class for MIDI byte streams. - Established a structure for MIDI file handling with MidiFile and MidiTrack classes.
147 lines
4.5 KiB
Python
147 lines
4.5 KiB
Python
from abc import ABCMeta, abstractmethod
|
|
from collections.abc import Generator, Iterable
|
|
from typing import Literal, Never, Self, Unpack, override
|
|
|
|
from mido.messages.specs import MsgDict, MsgDictOverride
|
|
|
|
class BaseMessage(metaclass=ABCMeta):
|
|
"""Abstract base class for messages."""
|
|
|
|
@property
|
|
@abstractmethod
|
|
def is_meta(self) -> bool: ... # a normal attribute in runtime
|
|
@abstractmethod
|
|
def copy(self) -> Self: ...
|
|
@abstractmethod
|
|
def bytes(self) -> list[int]: ...
|
|
def bin(self) -> bytearray:
|
|
"""Encode message and return as a bytearray.
|
|
|
|
This can be used to write the message to a file.
|
|
"""
|
|
|
|
def hex(self, sep: str = " ") -> str:
|
|
"""Encode message and return as a string of hex numbers,
|
|
|
|
Each number is separated by the string sep.
|
|
"""
|
|
|
|
def dict(self) -> MsgDict:
|
|
"""Returns a dictionary containing the attributes of the message.
|
|
|
|
Example: `{'type': 'sysex', 'data': [1, 2], 'time': 0}`
|
|
|
|
Sysex data will be returned as a list.
|
|
"""
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: MsgDict) -> Self:
|
|
"""Create a message from a dictionary.
|
|
|
|
Only "type" is required. The other will be set to default
|
|
values.
|
|
"""
|
|
|
|
@property
|
|
def is_realtime(self) -> bool:
|
|
"""True if the message is a system realtime message."""
|
|
|
|
def is_cc(self, control: int | None = ...) -> bool:
|
|
"""Return True if the message is of type 'control_change'.
|
|
|
|
The optional control argument can be used to test for a specific
|
|
control number, for example:
|
|
|
|
>>> if msg.is_cc(7):
|
|
... # Message is control change 7 (channel volume).
|
|
"""
|
|
|
|
@override
|
|
def __delattr__(self, name: str) -> Never: ...
|
|
@override
|
|
def __setattr__(self, name: str, value: object) -> None: ...
|
|
@override
|
|
def __eq__(self, other: object) -> bool: ...
|
|
|
|
class SysexData(tuple[int, ...]):
|
|
"""Special kind of tuple accepts and converts any sequence in `+=`."""
|
|
def __iadd__(self, other: SysexData) -> Self: ...
|
|
|
|
class Message(BaseMessage):
|
|
type: str
|
|
time: int
|
|
|
|
@property
|
|
@override
|
|
def is_meta(self) -> Literal[False]: ... # a normal attribute in runtime
|
|
def __init__(self, type: str, skip_checks: bool = False, **args: Unpack[MsgDictOverride]) -> None: ...
|
|
@override
|
|
def copy(self, skip_checks: bool = False, **overrides: Unpack[MsgDictOverride]) -> Self:
|
|
"""Return a copy of the message.
|
|
|
|
Attributes will be overridden by the passed keyword arguments.
|
|
Only message specific attributes can be overridden. The message
|
|
type can not be changed.
|
|
|
|
The `skip_checks` arg can be used to bypass validation of message
|
|
attributes and should be used cautiously.
|
|
"""
|
|
|
|
@classmethod
|
|
def from_bytes(cls, data: Iterable[int], time: int = 0) -> Self:
|
|
"""Parse a byte encoded message.
|
|
|
|
Accepts a byte string or any iterable of integers.
|
|
|
|
This is the reverse of `msg.bytes()` or `msg.bin()`.
|
|
"""
|
|
|
|
@classmethod
|
|
def from_hex(cls, text: str, time: int = 0, sep: str | None = ...) -> Self:
|
|
"""Parse a hex encoded message.
|
|
|
|
This is the reverse of `msg.hex()`.
|
|
"""
|
|
|
|
@classmethod
|
|
def from_str(cls, text: str) -> Self:
|
|
"""Parse a string encoded message.
|
|
|
|
This is the reverse of `str(msg)`.
|
|
"""
|
|
|
|
def __len__(self) -> int: ...
|
|
@override
|
|
def __setattr__(self, name: str, value: object) -> None: ...
|
|
@override
|
|
def bytes(self) -> list[int]:
|
|
"""Encode message and return as a list of integers."""
|
|
|
|
def parse_string(text: str) -> Message:
|
|
"""Parse a string of text and return a message.
|
|
|
|
The string can span multiple lines, but must contain
|
|
one full message.
|
|
|
|
Raises ValueError if the string could not be parsed.
|
|
"""
|
|
|
|
def parse_string_stream(stream: Iterable[str]) -> Generator[tuple[Message, None] | tuple[None, str], Never]:
|
|
"""Parse a stream of messages and yield `(message, error_message)`
|
|
|
|
stream can be any iterable that generates text strings, where each
|
|
string is a string encoded message.
|
|
|
|
If a string can be parsed, `(message, None)` is returned. If it
|
|
can't be parsed, `(None, error_message)` is returned. The error
|
|
message contains the line number where the error occurred.
|
|
"""
|
|
|
|
def format_as_string(msg: Message, include_time: bool = True) -> str:
|
|
"""Format a message and return as a string.
|
|
|
|
This is equivalent to `str(message)`.
|
|
|
|
To leave out the time attribute, pass `include_time=False`.
|
|
"""
|