Skip to content

thanks4opensource_aconnect_py - #31

Open
thanks4opensource wants to merge 6 commits into
Jajcus:mainfrom
thanks4opensource:thanks4opensource_aconnect_py
Open

thanks4opensource wants to merge 6 commits into
Jajcus:mainfrom
thanks4opensource:thanks4opensource_aconnect_py

Conversation

@thanks4opensource

Copy link
Copy Markdown
Contributor

This pull request adds a new utils subdirectory with aconnect.py.

aconnect.py is intended as an improved replacement for aconnect (compiled from https://github.com/alsa-project/alsa-utils/blob/master/seq/aconnect/aconnect.c). Its main feature is the use of the new SequencerClientBase.resolve_address() method allowing specification of client:port addresses by name, numeric ID, or any combination thereof. The UI was designed with usability as its first priority, strict adherence to orthogonality second, and backwards compatibility with aconnect third, although no changes were made unless in support of the first two goals.

The first and most obvious change is that aconnect.py without any options outputs a default listing of clients, ports, and connections:

$ aconnect.py 
128: 'controlbox' USER pid=2322694 ports=MIDI_GENERIC|SOFTWARE
    0: 'buttons'                       OUTPUT
        connected to 'keyboard:octaveshift'(129:9)
    1: 'dials'                         OUTPUT
        connected to 'FLUID Synth (2322705):Synth input port
                     (2322705:0)'(130:0) real queue=2
        connected to 'aseqdump:aseqdump'(131:0)
    2: 'pedals'                        OUTPUT
        connected to 'keyboard:sustain'(129:8)
129: 'keyboard' USER pid=2322696 ports=MIDI_GENERIC|SOFTWARE
    0: 'out'                           OUTPUT
        connected to 'FLUID Synth (2322705):Synth input port
                     (2322705:0)'(130:0) real queue=0
        connected to 'aseqdump:aseqdump'(131:0)
    8: 'sustain'                       INPUT
        connected from 'controlbox:pedals'(128:2)
    9: 'octaveshift'                   BIDIR
        connected from 'controlbox:buttons'(128:0)
130: 'FLUID Synth (2322705)' USER pid=2322705
                             ports=MIDI_GENERIC|MIDI_GM|SYNTHESIZER|APPLICATION
    0: 'Synth input port (2322705:0)'  INPUT
        connected from 'keyboard:out'(129:0) real queue=0
        connected from 'controlbox:dials'(128:1) real queue=2
131: 'aseqdump' USER pid=2322731 ports=MIDI_GENERIC|APPLICATION
    0: 'aseqdump'                      INPUT
        connected from 'keyboard:out'(129:0)
        connected from 'controlbox:dials'(128:1)

This differs from aconnect which prints its help message by default, but matches most other UNIX utilities such as ls, etc. Any user of the shell commandline will certainly know to use -h, --help, etc., and aconnect.py not only prints the canonical Python argparse usage message if given bad options but also "'aconnect.py -h' for help and options" after any error (thus aconnect.py somerandomjunk will provide that information).

The help message itself, listing the program's many features, is:

$ aconnect.py -h
usage: aconnect.py [-h] [-d] [-D] [-e] [-u] [-r] [-q QUEUE] [-l] [-c] [-i]
                   [-o] [-k] [-p] [-a] [-f] [-w WIDTH]
                   [CLIENT[:PORT] ... ...]

List, connect, disconnect ALSA ports. Specify 'client:port' or 'client.port'
by numeric IDs or names, or 'client' for no port or implicit port 0. List
clients with ports (or without if -c,--clients) if 0, 1, or 3+ clients:ports.
Connect two client:ports unless -d,--delete or -D,--DELETE.

positional arguments:
  CLIENT[:PORT] ...  Clients or client:ports

options:
  -h, --help         show this help message and exit
  -d, --disconnect   Disconnect one existing connection ('clientA:portA
                     clientB:PortB'), all connections to/from a port
                     ('client:port'), all connections to/from a client's ports
                     ('client'), or all connections (no clients,ports
                     specified)
  -D, --DISCONNECT   Same as -d,--delete without listing connections to be
                     disconnected and requiring 'n/Y' response. Implicit if
                     -d,--delete with two clients:ports.
  -e, --exclusive    Add exclusive to connect.
  -u, --update       Add time_update to connect.
  -r, --real         Add time_real to connect.
  -q, --queue QUEUE  Specify queue ID to connect.
  -l, --list         List clients (implicit if 0, 1, or 3+ clients).
  -c, --clients      List only clients (no ports)
  -i, --inputs       List only input (readable) ports
  -o, --outputs      List only output (writable) ports
  -k, --kernel       Include kernel/system clients
  -p, --pipewire     Include pipewire clients
  -a, --all          Include all (-k,-p) clients
  -f, --full         Full client and port info
  -w, --width WIDTH  Override terminal width (or provide if not tty) if not 0

A few of these will be described here, but first note in the default output:

  1. Clients, ports, and connections are listed with both names and numeric IDs
  2. The alignment/padding of names does not include whitespace (which is significant to the ALSA library) inside the single quotes as with aconnect.
  3. The labels read "connected to", not aconnect's misleading `Connecting To". (The connection has been made and exists, not "is in the process of connecting but not finished yet".)
  4. Linewrapping is terminal width aware, and indentation adjusts to the widths of the port names, etc.

The various options provide enhanced control of the output listing. For example, only the clients themselves without their ports/connections (but reports number of ports for each client):

$ aconnect.py -c                 
128: 'controlbox'             USER  ports=3   pid=2320459
129: 'keyboard'               USER  ports=3   pid=2320461
130: 'FLUID Synth (2320471)'  USER  ports=1   pid=2320471
131: 'aseqdump'               USER  ports=1   pid=2320500

Include kernel ("system") and/or PipeWire clients (illustrated here with --clients but works equally well with normal clients+ports+connections display):

$ aconnect.py -c -a              
  0: 'System'                 KERNEL  ports=2   pid=None
 14: 'Midi Through'           KERNEL  ports=1   pid=None
128: 'controlbox'             USER    ports=3   pid=2320459
129: 'keyboard'               USER    ports=3   pid=2320461
130: 'FLUID Synth (2320471)'  USER    ports=1   pid=2320471
131: 'aseqdump'               USER    ports=1   pid=2320500
142: 'PipeWire-System'        USER    ports=1   pid=2807
143: 'PipeWire-RT-Event'      USER    ports=1   pid=2807

Also -f,--full for extra information:

$ aconnect.py -f   
128: 'controlbox' USER pid=2322694 ports=MIDI_GENERIC|SOFTWARE
                  event_filter=None broadcast_filter=False
                  error_bounce=False event_lost=0 card_id=None num_ports=3
    0: 'buttons'                       OUTPUT capability=READ|SUBS_READ
                                       client_id=128 midi_channels=16
                                       midi_voices=64 read_use=1
                                       synth_voices=0 timestamp_queue_id= 0
                                       timestamp_real=False
                                       timestamping=False write_use=0
        connected to 'keyboard:octaveshift'(129:9) root=128:0 index=0
                     num_subs=1 addr=129:9 queue_id=0 exclusive=False
                     time_update=False time_real=False
    1: 'dials'                         OUTPUT capability=READ|SUBS_READ
                                       client_id=128 midi_channels=16
                                       midi_voices=64 read_use=2
                                       synth_voices=0 timestamp_queue_id= 0
                                       timestamp_real=False
                                       timestamping=False write_use=0
        connected to 'FLUID Synth (2322705):Synth input port
                     (2322705:0)'(130:0) real queue=2 root=128:1 index=0
                     num_subs=2 addr=130:0 queue_id=2 exclusive=False
                     time_update=True time_real=True
        connected to 'aseqdump:aseqdump'(131:0) root=128:1 index=1
                     num_subs=2 addr=131:0 queue_id=0 exclusive=False
                     time_update=False time_real=False
    2: 'pedals'                        OUTPUT capability=READ|SUBS_READ
                                       client_id=128 midi_channels=16
                                       midi_voices=64 read_use=1
                                       synth_voices=0 timestamp_queue_id= 0
                                       timestamp_real=False
                                       timestamping=False write_use=0
        connected to 'keyboard:sustain'(129:8) root=128:2 index=0
                     num_subs=1 addr=129:8 queue_id=0 exclusive=True
                     time_update=False time_real=False
129: 'keyboard' USER pid=2322696 ports=MIDI_GENERIC|SOFTWARE
                event_filter=None broadcast_filter=False error_bounce=False
                event_lost=0 card_id=None num_ports=3
    0: 'out'                           OUTPUT capability=READ|SUBS_READ
                                       client_id=129 midi_channels=16
                                       midi_voices=64 read_use=2
                                       synth_voices=0 timestamp_queue_id= 0
                                       timestamp_real=False
                                       timestamping=False write_use=0
        connected to 'FLUID Synth (2322705):Synth input port
                     (2322705:0)'(130:0) real queue=0 root=129:0 index=0
                     num_subs=2 addr=130:0 queue_id=0 exclusive=False
                     time_update=True time_real=True
        connected to 'aseqdump:aseqdump'(131:0) root=129:0 index=1
                     num_subs=2 addr=131:0 queue_id=0 exclusive=False
                     time_update=False time_real=False
    8: 'sustain'                       INPUT capability=WRITE|SUBS_WRITE
                                       client_id=129 midi_channels=0
                                       midi_voices=0 read_use=0
                                       synth_voices=0 timestamp_queue_id= 0
                                       timestamp_real=False
                                       timestamping=False write_use=1
        connected from 'controlbox:pedals'(128:2) root=129:8 index=0
                       num_subs=1 addr=128:2 queue_id=0 exclusive=True
                       time_update=False time_real=False
    9: 'octaveshift'                   BIDIR
                                       capability=READ|WRITE|SUBS_READ|SUBS_WRITE
                                       client_id=129 midi_channels=0
                                       midi_voices=0 read_use=0
                                       synth_voices=0 timestamp_queue_id= 0
                                       timestamp_real=False
                                       timestamping=False write_use=1
        connected from 'controlbox:buttons'(128:0) root=129:9 index=0
                       num_subs=1 addr=128:0 queue_id=0 exclusive=False
                       time_update=False time_real=False
130: 'FLUID Synth (2322705)' USER pid=2322705
                             ports=MIDI_GENERIC|MIDI_GM|SYNTHESIZER|APPLICATION
                             event_filter=None broadcast_filter=False
                             error_bounce=False event_lost=0 card_id=None
                             num_ports=1
    0: 'Synth input port (2322705:0)'  INPUT capability=WRITE|SUBS_WRITE
                                       client_id=130 midi_channels=16
                                       midi_voices=0 read_use=0
                                       synth_voices=0 timestamp_queue_id= 0
                                       timestamp_real=False
                                       timestamping=False write_use=2
        connected from 'keyboard:out'(129:0) real queue=0 root=130:0
                       index=0 num_subs=2 addr=129:0 queue_id=0
                       exclusive=False time_update=True time_real=True
        connected from 'controlbox:dials'(128:1) real queue=2 root=130:0
                       index=1 num_subs=2 addr=128:1 queue_id=2
                       exclusive=False time_update=True time_real=True
131: 'aseqdump' USER pid=2322731 ports=MIDI_GENERIC|APPLICATION
                event_filter=None broadcast_filter=False error_bounce=False
                event_lost=0 card_id=None num_ports=1
    0: 'aseqdump'                      INPUT capability=WRITE|SUBS_WRITE
                                       client_id=131 midi_channels=16
                                       midi_voices=64 read_use=0
                                       synth_voices=0 timestamp_queue_id= 0
                                       timestamp_real=False
                                       timestamping=False write_use=2
        connected from 'keyboard:out'(129:0) root=131:0 index=0 num_subs=2
                       addr=129:0 queue_id=0 exclusive=False
                       time_update=False time_real=False
        connected from 'controlbox:dials'(128:1) root=131:0 index=1
                       num_subs=2 addr=128:1 queue_id=0 exclusive=False
                       time_update=False time_real=False

Of course the second most frequent use of the utility is likely connecting ports together, thus no --connect or similar is required (as per aconnect). But any combination of client:port names or numeric IDs is accepted, along with the convention that a client without ":port" (or ".port") implies port 0, and is accepted (as long as the client has a port 0, and its input, output, or bidirectional gender is appropriate for the connection being made). All of the following (any many other variations) produce the same result:

$ aconnect.py keyboard:out FLUID   
$ aconnect.py keyboard FLUID:0  
$ aconnect.py key F        
$ aconnect.py 129 130
$ aconnect.py 129.out 130.0

Removing (deleting) connections is another departure from aconnect, although the most canonical case of removing a single connection between two ports remains the same (except for the additional name-instead-of-numerical-port capability).

The -d,--delete option behaves polymorphically depending on the number and types of arguments given. Again, all name/ID/abbreviation/implicit0 variations produce the same result:

$ aconnect.py -d keyboard:out FLUID   
$ aconnect.py -d keyboard FLUID:0  
$ aconnect.py -d key F        
$ aconnect.py -d 129 130
$ aconnect.py -d 129.out 130.0

The differences arise with the other -d modes. Given a single client:port address it will delete all connections to/from the port. However it first reports the existing connections, and asks for user confirmation before deleting them. This is not implemented in the explicit aconnect.py -d clientA:portB clientC:portD case because that can easily be "undone" by repeating without the -d option. The report/confirmation happens in the following cases because the user may not remember the existing connections or have done a plain aconnect.py before deleting them, thus recreating them if a mistake was made might be difficult. (But the -D,--DELETE options, intended for non-interactive shell scripts, override this behavior.)

$ aconnect.py -d keyboard:out
129: 'keyboard'USER  ports=3   pid=2323199 ports=MIDI_GENERIC|SOFTWARE
    0: 'out'          OUTPUT
        connected to 'aseqdump:aseqdump'(131:0)
        connected to 'FLUID Synth (2323208):Synth input port
                     (2323208:0)'(130:0)
Remove 2 connection(s)? n/Y: 

The same is implemented for removing all connections to/from all of a single client's ports:

$ aconnect.py -d keyboard    
129: 'keyboard' USER pid=2323199 ports=MIDI_GENERIC|SOFTWARE
    0: 'out'          OUTPUT
        connected to 'aseqdump:aseqdump'(131:0)
        connected to 'FLUID Synth (2323208):Synth input port
                     (2323208:0)'(130:0)
    8: 'sustain'      INPUT
        connected from 'controlbox:pedals'(128:2)
    9: 'octaveshift'  BIDIR
        connected from 'controlbox:buttons'(128:0)
Remove all 4 connection(s)? n/Y:

And all connections between all clients' ports (completely removing the need for aconnect's specific -x,--removall option):

$ aconnect.py -d
128: 'controlbox' USER pid=2323457 ports=MIDI_GENERIC|SOFTWARE
    0: 'buttons'                       OUTPUT
        connected to 'keyboard:octaveshift'(129:9)
    1: 'dials'                         OUTPUT
        connected to 'FLUID Synth (2323468):Synth input port
                     (2323468:0)'(130:0) real queue=2
        connected to 'aseqdump:aseqdump'(131:0)
    2: 'pedals'                        OUTPUT
        connected to 'keyboard:sustain'(129:8)
129: 'keyboard' USER pid=2323459 ports=MIDI_GENERIC|SOFTWARE
    0: 'out'                           OUTPUT
        connected to 'FLUID Synth (2323468):Synth input port
                     (2323468:0)'(130:0) real queue=0
        connected to 'aseqdump:aseqdump'(131:0)
    8: 'sustain'                       INPUT
        connected from 'controlbox:pedals'(128:2)
    9: 'octaveshift'                   BIDIR
        connected from 'controlbox:buttons'(128:0)
130: 'FLUID Synth (2323468)' USER pid=2323468
                             ports=MIDI_GENERIC|MIDI_GM|SYNTHESIZER|APPLICATION
    0: 'Synth input port (2323468:0)'  INPUT
        connected from 'keyboard:out'(129:0) real queue=0
        connected from 'controlbox:dials'(128:1) real queue=2
131: 'aseqdump' USER pid=2323497 ports=MIDI_GENERIC|APPLICATION
    0: 'aseqdump'                      INPUT
        connected from 'keyboard:out'(129:0)
        connected from 'controlbox:dials'(128:1)
Remove all 12 connection(s)? n/Y: 

Finally, any subset of existing clients/ports/connections can be listed:

$ aconnect.py aseq
131: 'aseqdump' USER pid=2323497 ports=MIDI_GENERIC|APPLICATION
    0: 'aseqdump'  INPUT
        connected from 'keyboard:out'(129:0)
        connected from 'controlbox:dials'(128:1)

although if exactly two clients are requested an explicit -l,--list flag must be provided to distinguish the command from connecting two client's ports (including use of implicit port 0):

$ aconnect.py -l FLU aseq
130: 'FLUID Synth (2323468)' USER pid=2323468
                             ports=MIDI_GENERIC|MIDI_GM|SYNTHESIZER|APPLICATION
    0: 'Synth input port (2323468:0)'  INPUT
        connected from 'keyboard:out'(129:0) real queue=0
        connected from 'controlbox:dials'(128:1) real queue=2
131: 'aseqdump' USER pid=2323497 ports=MIDI_GENERIC|APPLICATION
    0: 'aseqdump'                      INPUT
        connected from 'keyboard:out'(129:0)
        connected from 'controlbox:dials'(128:1)

Notes on the code:

  • I cannot provide a unittest for aconnect.py at this time. Unittests for interactive programs are notoriously hard and time consuming to write. I have tested the code continuously during a long period of incremental development, and will be using it extensively in my own day-to-day work. I'll attempt to fix any bugs I find and/or ones that are reported to me.

  • The large changes from commit 716751 were manually merged here to ease merging this into main if and when desired.

  • tox still runs tests/* without errors, despite the small additions and changes made in alsa_util/port.py and tests/test_port_query.py. See the commit message.

  • aconnect.py was formatted via autopep8 to meet approved standards.

  • mypy utils/aconnect.py reports "Success: no issues found in 1 source file". mypy utils/aconnect.py alsa_midi (which showed some issues in aconnect.py, now fixed) reports "Found 86 errors in 7 files (checked 12 source files)", none of them in aconnect.py.

  • I am fairly sure the aconnect.py --update and --real options are implemented and call SequencerClientBase.subscribe_port() and _subunsub_port() correctly, and that the latter calls alsa.snd_seq_port_subscribe_set_time_update() and alsa.snd_seq_port_subscribe_set_time_real() correctly. Nevertheless, --real has no effect, and --update sets the time_update and time_real in the connection both to True. I'm convinced this is a bug or mis-feature in the ALSA util library. Note that aconnect.c has some strange code implementing its own analogous options.

thanks4opensource and others added 4 commits October 7, 2026 22:09
Parses various input overloads such as 'client-name:port_name',
('client-name','port-name), etc., returns Address. Raises exception
if Address(client_id, port_id) doesn't exist. Added new fd() public
accessor. Added tests/test_sequencer_address.py. Modified
examples/connect.py to accept 'client-name:port-name'.
New aconnect.py, improved replacement for alsa-utils aconnect
(aconnect.c). New SequencerClientBase.list_clients() and modified
.list_ports() with include_kernel parameter. SequencerClientBase.fd
property and .get_address() changed to .resolve_address(). Code
formatting changes to pass flake8 checks. Added port.py
PortDirection. Revert examples/connect.py to accept client/port by id
only. Modified tests/test_sequencer_address() to run under pytest,
and excluded from flake8.
Adds new aconnect.py, full replacement for alsa-utils/.../aconnect.c,
including SequencerClientBase.resolve_address(), and output and
usability improvments. New SequencerClientBase::list_clients(),
port.py class PortDirection, and other additions to support
aconnect.py functionality. Small updates to tests/test_port_query.py
for new SequencerClientBase::list_clients() parameter. Incorporates
large Jajcus commit 716751 (typing modernizations). Reverted
examples/connect.py to original without resolve_address().
@Jajcus

Jajcus commented Nov 2, 2026

Copy link
Copy Markdown
Owner

Looks good.

There are just a few problems:

Some unused variables, as reported by the pre-commit hook:

$ prek run -a
flake8...................................................................Failed
- hook id: flake8
- description: `flake8` is a command-line utility for enforcing style consistency across Python projects
- exit code: 1

  utils/aconnect.py:43:5: F824 `global program_name` is unused: name is never assigned in scope
  utils/aconnect.py:68:5: F824 `global aconnect` is unused: name is never assigned in scope
  utils/aconnect.py:68:5: F824 `global ports` is unused: name is never assigned in scope
  utils/aconnect.py:106:5: F824 `global ports` is unused: name is never assigned in scope
  utils/aconnect.py:190:5: F824 `global indenter` is unused: name is never assigned in scope
  utils/aconnect.py:247:5: F824 `global aconnect` is unused: name is never assigned in scope
  utils/aconnect.py:247:5: F824 `global clients` is unused: name is never assigned in scope
  utils/aconnect.py:247:5: F824 `global ports` is unused: name is never assigned in scope
  utils/aconnect.py:324:5: F824 `global aconnect` is unused: name is never assigned in scope
  utils/aconnect.py:335:5: F841 local variable 'e' is assigned to but never used
  utils/aconnect.py:345:5: F841 local variable 'e' is assigned to but never used
  utils/aconnect.py:381:5: F824 `global aconnect` is unused: name is never assigned in scope
  utils/aconnect.py:386:5: F841 local variable 'e' is assigned to but never used
  utils/aconnect.py:391:5: F841 local variable 'e' is assigned to but never used
  utils/aconnect.py:406:5: F824 `global aconnect` is unused: name is never assigned in scope
  utils/aconnect.py:406:5: F824 `global clients` is unused: name is never assigned in scope
  utils/aconnect.py:406:5: F824 `global ports` is unused: name is never assigned in scope
  utils/aconnect.py:410:5: F841 local variable 'e' is assigned to but never used
  utils/aconnect.py:464:5: F824 `global aconnect` is unused: name is never assigned in scope
  utils/aconnect.py:464:5: F824 `global clients` is unused: name is never assigned in scope
  utils/aconnect.py:464:5: F824 `global ports` is unused: name is never assigned in scope
  utils/aconnect.py:542:5: F824 `global aconnect` is unused: name is never assigned in scope
  utils/aconnect.py:542:5: F824 `global program_name` is unused: name is never assigned in scope
isort (python)...........................................................Passed

The package won't build with alsa-lib < v1.2.10 any more, as the SND_SEQ_PORT_DIR_* constants and the snd_seq_port_info_set_direction and snd_seq_port_info_get_direction methods when only added recently with the MIDI 2.0 support. Before that only SND_SEQ_PORT_CAP_WRITE and SND_SEQ_PORT_CAP_READ were available for determining port direction. I would rather not rise required ALSA library version at this point. Usage of the new symbols could be made optional, but I think it would be easier to just rely on the old READ/WRITE capabilities.

I have not tried it with actual MIDI devices and software – will do that when I am around the hardware.

I have merged changes for main – there was one conflict to resolve (proper handling of all AddressType objects).

@Jajcus

Jajcus commented Nov 2, 2026

Copy link
Copy Markdown
Owner

One more thing: I really appreciate your work here. This seems to fix everything I didn't like in the original aconnect.

This should be listed as an installed script in pyproject.toml, so it is properly installed. Just not at the aconnect name not to conflict with alsa-utils. aconnect.py is probably good enough, by '.py' extension in $PATH may be frowned upon.

Adds new aconnect.py, full replacement for alsa-utils/.../aconnect.c,
including SequencerClientBase.resolve_address(), and output and
usability improvments. New SequencerClientBase::list_clients(),
port.py class PortDirection, and other additions to support
aconnect.py functionality. Small updates to tests/test_port_query.py
for new SequencerClientBase::list_clients() parameter. Incorporates
large Jajcus commit 716751 (typing modernizations). Reverted
examples/connect.py to original without resolve_address().
Update:
- Reverted additions of PortDirection, direction,
  snd_seq_port_info_get_direction(), PortDirection(),
  snd_seq_port_info_set_direction(), SND_SEQ_PORT_DIR_*,
  "PortDirection" as per request to allow building with
  alsa-lib < v1.2.10.
- Replaced with `PortCaps.READ` and `.WRITE` for determining port
  input/output/bidirectional.
- Removed redundant `global` declarations and unused `Exception as e`
  variables.
- Improved error messages in aconnect.py
…connect_py' into thanks4opensource_aconnect_py
@thanks4opensource

Copy link
Copy Markdown
Contributor Author

Glad you like aconnect.py. "Great minds think alike" ;)

I removed the dependencies on alsa_lib < v1.2.10's `PortDirection", etc. As much as I think that alsa-lib has many problems (likely due to its long history and incremental changes) and that PortDirection is a step towards cleaning up that one small part of the API, you are right: PortCaps.READ and .WRITE are sufficient for my needs in aconnect.py for determining port direction. and backwards-compatibility is probably more important than cleaner code. I have tested several code paths between the old PortDirection and new PortCaps versions and confirmed they produce the same results.

I don't understand the syntax and semantics of pyproject.toml, and as opposed to several previous changes you've requested it's not clear how to cut-and-paste one section into another to accomplish installing aconnect.py. Please feel free to add the correct magic if it will improve installing via pypy.

I too am not completely happy with the aconnect.py name, including having the ".py" extension on an executable utility. I had considered something like aseqctl (with or without ".py") but thought "aconnect" was safer. Please feel free to change the name to anything you think would be better.

I think I fixed many of the prek/flake8 complaints. (I tend to use redundant global declarations, similar to typing hints, even though they're not needed due to LEGB name resolution.) I don't know how to run the checks locally, pre-commit/push, and I expect there will still be one or two remaining "errors" where it doesn't seem to understand that program_name is set during the standard Python if __name__ == '__main__': pattern that allows a single source file to be used both as a standalone utility and as a module to be integrated into a larger Python program. If there's a way to silence this incorrect error reporting with a commandline option please add it, or even with a line-by-line escape comments. I don't have the tools available to do so.

Related, the commit still passes the tox tests, and mypy is still clean for aconnect.py yet still has 90 errors in alsa_midi/*.py files that I have not touched.

Finally: I ran into many problems that were beyond my "git knowledge" when trying to push these changes. I had to do a sequence of git "remote add", "fetch", "pull", and "merge" commands before git push finally worked. I think the new code survived but I'm not 100% convinced it did.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants