Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -110,10 +110,10 @@ jobs:
with:
fetch-depth: 0

- name: Set up Python 3.8
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.8
python-version: 3.9

- name: Install dependencies
run: |
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
repos:
- repo: https://github.com/pycqa/flake8
rev: '7.0.0'
rev: '7.3.0'
hooks:
- id: flake8
exclude: pbx_api_client/v1
- repo: https://github.com/pycqa/isort
rev: 5.13.2
rev: '7.0.0'
hooks:
- id: isort
name: isort (python)
7 changes: 3 additions & 4 deletions alsa_midi/address.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@

from collections import namedtuple
from typing import TYPE_CHECKING, Any, Tuple, Union, overload
from typing import TYPE_CHECKING, Any, Union, overload

from ._ffi import alsa, ffi
from .util import _check_alsa_error
Expand All @@ -10,7 +9,7 @@
from .port import Port, PortInfo


AddressType = Union['Address', 'Port', 'PortInfo', Tuple[int, int]]
AddressType = Union['Address', 'Port', 'PortInfo', tuple[int, int]]


class Address(namedtuple("Address", "client_id port_id")):
Expand Down Expand Up @@ -79,7 +78,7 @@ def __new__(cls,
return tuple.__new__(cls, tple)

@staticmethod
def _parse(arg: str) -> Tuple[int, int]:
def _parse(arg: str) -> tuple[int, int]:
addr_p = ffi.new("snd_seq_addr_t *")
result = alsa.snd_seq_parse_address(ffi.NULL, addr_p, arg.encode())
_check_alsa_error(result)
Expand Down
21 changes: 10 additions & 11 deletions alsa_midi/client.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@

import asyncio
import errno
import select
import time
from collections.abc import MutableMapping
from dataclasses import dataclass, field
from enum import IntEnum, IntFlag
from functools import partial
from typing import (Any, Callable, List, MutableMapping, NewType, Optional, Set, Tuple, Union,
overload)
from typing import Any, Callable, NewType, Optional, Union, overload
from weakref import WeakValueDictionary

from ._ffi import alsa, ffi
Expand All @@ -21,7 +20,7 @@
from .util import _check_alsa_error

_snd_seq_t = NewType("_snd_seq_t", object)
_snd_seq_t_p = NewType("_snd_seq_t_p", Tuple[_snd_seq_t])
_snd_seq_t_p = NewType("_snd_seq_t_p", tuple[_snd_seq_t])
_snd_midi_event_t = NewType("_snd_midi_event_t", object)


Expand Down Expand Up @@ -90,7 +89,7 @@ class ClientInfo:
pid: Optional[int] = None
num_ports: int = 0
event_lost: int = 0
event_filter: Optional[Set[EventType]] = None
event_filter: Optional[set[EventType]] = None

@classmethod
def _from_alsa(cls, info: _snd_seq_client_info_t):
Expand Down Expand Up @@ -661,7 +660,7 @@ def drop_output_buffer(self):
err = alsa.snd_seq_drop_output_buffer(self.handle)
_check_alsa_error(err)

def _event_input(self, prefer_bytes: bool = False) -> Tuple[int, Optional[Event]]:
def _event_input(self, prefer_bytes: bool = False) -> tuple[int, Optional[Event]]:
buf = ffi.new("snd_seq_event_t**", ffi.NULL)
result = alsa.snd_seq_event_input(self.handle, buf)
if result < 0:
Expand Down Expand Up @@ -730,7 +729,7 @@ def _prepare_event(self,
queue: Union['Queue', int] = None,
port: Union['Port', int] = None,
dest: AddressType = None,
remainder: Optional[Any] = None) -> Tuple[_snd_seq_event_t, Any]:
remainder: Optional[Any] = None) -> tuple[_snd_seq_event_t, Any]:
"""Prepare ALSA :alsa:`snd_seq_event_t` for given `event` object for output.

For :class:`alsa_midi.MidiBytesEvent` may need to be called more than
Expand Down Expand Up @@ -780,7 +779,7 @@ def _event_output(self,
queue: Union['Queue', int] = None,
port: Union['Port', int] = None,
dest: AddressType = None,
remainder: Optional[Any] = None) -> Tuple[int, Any]:
remainder: Optional[Any] = None) -> tuple[int, Any]:
alsa_event, remainder = self._prepare_event(event,
queue=queue, port=port, dest=dest,
remainder=remainder)
Expand Down Expand Up @@ -864,7 +863,7 @@ def _event_output_direct(self,
queue: Union['Queue', int] = None,
port: Union['Port', int] = None,
dest: AddressType = None,
remainder: Optional[Any] = None) -> Tuple[int, Any]:
remainder: Optional[Any] = None) -> tuple[int, Any]:
alsa_event, remainder = self._prepare_event(event,
queue=queue, port=port, dest=dest,
remainder=remainder)
Expand Down Expand Up @@ -1114,7 +1113,7 @@ def list_ports(self, *,
include_no_export: bool = True,
only_connectable: bool = True,
sort: Union[bool, Callable[[PortInfo], Any]] = True,
) -> List[PortInfo]:
) -> list[PortInfo]:
"""More friendly interface to list available ports.

Queries ALSA for all clients and ports and returns those matching the selected criteria.
Expand Down Expand Up @@ -1327,7 +1326,7 @@ def query_port_subscribers(self,
def list_port_subscribers(self,
port: AddressType,
type: Optional[SubscriptionQueryType] = None,
) -> List[SubscriptionQuery]:
) -> list[SubscriptionQuery]:
"""Lists subscribers accessing a port.

Wraps :alsa:`snd_seq_query_port_subscribers`.
Expand Down
4 changes: 2 additions & 2 deletions alsa_midi/event.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

from collections.abc import Iterable
from enum import IntEnum, IntFlag
from functools import total_ordering
from typing import TYPE_CHECKING, Any, Iterable, NewType, Optional, Union
from typing import TYPE_CHECKING, Any, NewType, Optional, Union

from ._ffi import alsa, ffi
from .address import Address, AddressType
Expand Down
17 changes: 9 additions & 8 deletions alsa_midi/mido_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
import queue
import sys
import threading
from typing import Any, Callable, List, MutableMapping, Optional
from collections.abc import MutableMapping
from typing import Any, Callable, Optional
from weakref import WeakValueDictionary

from mido.messages import Message
Expand Down Expand Up @@ -92,7 +93,7 @@ def get_devices(*args, **kwargs):
return client.get_devices(*args, **kwargs)


def _find_port(ports: List[alsa_midi.PortInfo], name: str) -> alsa_midi.PortInfo:
def _find_port(ports: list[alsa_midi.PortInfo], name: str) -> alsa_midi.PortInfo:
try:
addr = alsa_midi.Address(name)
except (ValueError, alsa_midi.exceptions.ALSAError):
Expand All @@ -104,7 +105,7 @@ def _find_port(ports: List[alsa_midi.PortInfo], name: str) -> alsa_midi.PortInfo
if addr == alsa_midi.Address(port):
return port
else:
raise IOError(f"unknown port {name!r}")
raise OSError(f"unknown port {name!r}")

# check for exact match with name from get_devices()
for port in ports:
Expand All @@ -128,10 +129,10 @@ def _find_port(ports: List[alsa_midi.PortInfo], name: str) -> alsa_midi.PortInfo
if name == port.name:
return port

raise IOError(f"unknown port {name!r}")
raise OSError(f"unknown port {name!r}")


class PortCommon(object):
class PortCommon:
_last_num = 0
_name_prefix = "inout"
_caps = alsa_midi.PortCaps.READ | alsa_midi.PortCaps.WRITE
Expand Down Expand Up @@ -182,7 +183,7 @@ def _open(self, virtual=False, **kwargs):
ports = client.client.list_ports(input=self._for_input, output=self._for_output)

if not ports:
raise IOError('no ports available')
raise OSError('no ports available')

if self.name is None:
dest_port = ports[0]
Expand All @@ -200,9 +201,9 @@ def _open(self, virtual=False, **kwargs):
self._dest_port = dest_port

api = 'seq'
self._device_type = 'AlsaMidi/{}'.format(api)
self._device_type = f'AlsaMidi/{api}'
if virtual:
self._device_type = 'virtual {}'.format(self._device_type)
self._device_type = f'virtual {self._device_type}'

client.ports[self._port.port_id] = self

Expand Down
7 changes: 3 additions & 4 deletions alsa_midi/port.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

from dataclasses import InitVar, dataclass, field
from enum import IntFlag
from typing import TYPE_CHECKING, Any, Callable, List, NewType, Optional
from typing import TYPE_CHECKING, Any, Callable, NewType, Optional

from ._ffi import alsa, ffi
from .address import Address, AddressType
Expand Down Expand Up @@ -176,7 +175,7 @@ def set_info(self, info: 'PortInfo'):
raise StateError("Already closed")
return self.client.set_port_info(self, info)

def list_subscribers(self, type: 'SubscriptionQueryType' = None) -> List['SubscriptionQuery']:
def list_subscribers(self, type: 'SubscriptionQueryType' = None) -> list['SubscriptionQuery']:
"""Lists subscribers accessing a port.

Wraps :alsa:`snd_seq_query_port_subscribers`.
Expand Down Expand Up @@ -286,7 +285,7 @@ def _to_alsa(self) -> _snd_seq_port_info_t:
return info


def get_port_info_sort_key(preferred_types: List[PortType] = []
def get_port_info_sort_key(preferred_types: list[PortType] = []
) -> Callable[[PortInfo], Any]:
"""Return a :class:`PortInfo` sorting key function for given type
preference."""
Expand Down
1 change: 0 additions & 1 deletion alsa_midi/queue.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

from dataclasses import dataclass, field
from enum import IntEnum
from typing import TYPE_CHECKING, NamedTuple, NewType, Optional, Union
Expand Down
1 change: 0 additions & 1 deletion alsa_midi/util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

from ._ffi import alsa, ffi
from .exceptions import ALSAError

Expand Down
12 changes: 10 additions & 2 deletions build-wheels.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,12 @@ fi
git config --global --add safe.directory "$GITHUB_WORKSPACE"

# Compile wheels
for PYBIN in /opt/python/cp{37,38,39,310,311}*/bin; do
for PYBIN in /opt/python/cp{39,310,311,312,313,314}*/bin; do
[ -d "$PYBIN" ] || continue
if [[ "$PYBIN" =~ 313t ]] ; then
echo "Skipping 313t variant, as it is incompatible with cffi"
continue
fi
"${PYBIN}/pip" install --upgrade pip setuptools
"${PYBIN}/pip" install -r "$GITHUB_WORKSPACE/requirements.txt"

Expand All @@ -76,8 +80,12 @@ rm wheelhouse/*-linux_*.whl

# Install packages and test
cd /
for PYBIN in /opt/python/cp{37,38,39,310,311}*/bin/; do
for PYBIN in /opt/python/cp{39,310,311,312,313,314}*/bin/; do
[ -d "$PYBIN" ] || continue
if [[ "$PYBIN" =~ 313t ]] ; then
echo "Skipping 313t variant, as it is incompatible with cffi"
continue
fi

"${PYBIN}/pip" install pytest pytest-asyncio
"${PYBIN}/pip" install alsa-midi --no-index -f "$GITHUB_WORKSPACE/wheelhouse/"
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cffi==1.15.0
cffi==1.17.1
7 changes: 4 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ license = MIT
classifiers =
License :: OSI Approved :: MIT License
Programming Language :: Python :: 3
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: 3.13
Programming Language :: Python :: 3.14
Development Status :: 5 - Production/Stable
Framework :: AsyncIO
Intended Audience :: Developers
Expand All @@ -27,8 +28,8 @@ packages =
alsa_midi
zip_safe = False
setup_requires =
cffi>=1.14.0
cffi>=1.16.0
install_requires =
cffi>=1.14.0
cffi>=1.16.0
#cffi_modules=
# "alsa_midi/_ffi_defs.py:ffi"
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import os

from setuptools import setup
Expand Down
Loading