Repository navigation
client: add get_address() and fd() - #27
thanks4opensource wants to merge 4 commits into
Conversation
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'.
|
Thank you for your merge requests. A few comments...
And now about the actual changes: For the fd() method... I don't like it being a method. Maybe, if it was .fileno(), as in IOBase (with the same semantic), it could be argued for, but fd()? Not even get_fd()? But get_* functions here are usually direct interfaces to the underlying ALSA API, so it would be also confusing. To me the most reasonable would be to make this a read-only property. client.fd, typed 'int | None'. For the get_address(). I think the name is confusing, sounds like it is getting address of the client. Maybe resolve_address()? Sounds more like what the function is doing. |
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
getter. Added tests/test_sequencer_address.py. Modified
examples/connect.py to accept 'client-name:port-name'
Update:
- Changed get_address() to resolve_address()
- Added @Property to fd() to make read-only fd
- Fixed test_sequencer_address.py to run under tox/pytest
- Changed whitespace,etc to pass tox style/flake8, except
in test_sequencer_address.py
|
Thanks for reviewing the pull request. I've made changes as per your comments. Continuing the discussion ... I have no strong preferences regarding the Is this acceptable? It mandates use as I apologize for the tests issue. I had little prior exposure to which worked for my new I'm a huge believer in unittests but have no love for test frameworks like pytest/tor/etc. IMO they add many layers of complexity and rigorous demands while providing little benefit in return. Let me write whatever form of test I want as long as it runs silently returning With one exception: I strongly object to tor's style checker. As a tiny, poor example: Is inarguably more readable than: The human visual system (really that of all animals) has evolved to rapidly recognize patterns. You can glance at the first form and immediately see that some method is being called twice, with different members from the same object, and the result is being assigned to two different variables. You can look more closely if you're interested in the details, but in the second form you have to do that to understand what's going on. I'll stop lecturing here, but the bottom line is it's been my policy to try to match the style of code I'm modifying and use my own for entirely new code. It's a gray area when I'm adding a large block of new code to an existing source file, and I erred on the side of "mine" in what I added to But for now I've left And more generally, I have to ask what your level of interest is in receiving this kind of unsolicited new feature merge request? This is an old project for you and I'm sure you've moved on to other things and have little time to devote to it. You've been very responsive here, especially compared to https://github.com/alsa-project/alsa-lib where the backlog of pull requests (yes, I'm aware of the issue with mine) convinces me that it's effectively a dead/abandoned project. (And aren't people saying that ALSA itself has been deprecated, first by For myself, I had a window of time to work on this, and it's rapidly closing. I had for years wanted to consolidate my usage of ALSA, So again, the bottom line: If you'll give me a clear indication that you'll merge this pull request -- and the next, final one (a full-featured, improved Python replacement for Please tell me how I should proceed, and again thanks for this repo and the time you've spent on it. |
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
getter. Added tests/test_sequencer_address.py. Modified
examples/connect.py to accept 'client-name:port-name'
Update:
- Changed get_address() to resolve_address()
- Added @Property to fd() to make read-only fd
- Fixed test_sequencer_address.py to run under tox/pytest
- Changed whitespace,etc to pass tox style/flake8, except
in test_sequencer_address.py
Update:
- Whitespace/indentation changes, directives, and exclusions
for for tox/pytest/isort.
- All tests pass without error.
|
Update:
|
| The result is sorted in a way that the first returned entry should be the 'most usable' | ||
| one for the selected purpose. E.g. when `output` = `True` then the first entry will be | ||
| a synthesizer input port rather than the dummy 'Midi Through' port. This is still a guess, | ||
| a synthesizer input port rather than the dummy 'Midi Through' port. Thisa is still a guess, |
| @@ -0,0 +1,501 @@ | |||
| # flake8: noqa | |||
|
|
||
|
|
||
|
|
||
| """Tests SequencerClientBase.resolve_address() |
There was a problem hiding this comment.
docstring should go before the imports - it should be the first statement in the module
| self._fd = pfds[0].fd | ||
|
|
||
| @property | ||
| def fd(self): |
There was a problem hiding this comment.
I will implement this differently (as a .fileno() method), you can drop it.
There was a problem hiding this comment.
Still does not match the way other tests are written.
Single test function instead of actual unit tests and pytest framework is not fully used as it could be here.
But this does some thorough testing and works under pytest, so I can accept it.
| client_name = arg2.client_id # int will be converted below | ||
| port_name = arg2.port_id # same |
There was a problem hiding this comment.
Should be 'arg1' here, not 'arg2' (arg2 is None)
|
|
||
| [flake8] | ||
| max-line-length=99 | ||
| exclude = tests/test_sequencer_address.py |
|
For the fd – I think we should implement fileno() method instead, as that is what select() and poll() support natively. I will do that. For the tests and coding standard. The tool is 'tox' not 'tor' and your style checking preferences are irrelevant here: there there is a well defined coding style for Python (PEP 8) and it should be followed. Consistency is more important than personal preferences, which will always differ. Inconsistent formatting can cause serious objective problems when merging or reviewing code. And yes, the tests are no exceptions here. There are tools handle the formatting for you – either built-in in the code editor (probably via a language server) or stand-alone command-line ones. Your tests still fail when ALSA is not available in kernel (which may be the case in many CI platforms, like here on GitHub). Test functions that require actual kernel functionality and not just the ALSA library should be guarded with a In the
I am very happy someone is interested in my project (which seemed ignored most of the time) and wants to contribute. I still plan to maintain this and even add more functionality (like MIDI 2.0), but I was not able to give this much of my time recently. I will implement the fileno() function myself (similar to you original fd(), but compatible with IOBase semantics) and I can merge your The improved aconnect implementation seems interesting too, but I would need to see the details to say if it can be included here. |
client: add resolve_address() and fileno()
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 fileno()
public accessor. Added tests/test_sequencer_address.py. Modified
examples/connect.py to accept 'client-name:port-name'
Update:
- Changed get_address() to resolve_address()
- Added @Property to fd() to make read-only fd
- Fixed test_sequencer_address.py to run under tox/pytest
- Changed whitespace,etc to pass tox style/flake8, except
in test_sequencer_address.py
Update:
- Whitespace/indentation changes, directives, and exclusions
for for tox/pytest/isort.
- All tests pass without error.
Update:
client.py:
- Removed "@Property\ndef fd(self):"
- Replaced with Jajcus-provided "fileno(self)"
- Removed typo/bug, redesigned/rewrote argument validation in resolve_address()
- Fixed typo introduced in docstring
test_sequencer_address.py
- Fixed bug, use of non-existent variable
- Removed unused variable
- Removed "# flake8: noqa"
- Reformatted code with autopep8
- Moved file-level docstring to top of file
- Added "import pytest" and "@pytest.mark.require_alsa_seq"
- Added more "# isort: skip" (imports in correct order, still produce errors)
- Added "# noqua: F824" (global variables *are* used, flake8 flags incorrectly)
tox.ini
- Removed "-exclude = tests/test_sequencer_address.py"
|
commit message: Parses various input overloads such as 'client-name:port_name',
Comments:
My apologies. Fixed.
Thanks for catching this typo. There were several others, and the entire logic of argument validation was messy, although it worked because this error was caught later, and
I question whether an exception would be made for modules that have a
I "merged" your code into this commit.
Thank you. I ran the file through Because it's still not 100% pytest-approved there were still a few specific BTW, did you notice the "time.sleep(2)" I had to add? Sometimes the individual tests would run before the clients/ports were actually ready in ALSA -- mostly when other errors occurred and/or because the tests are run in parallel -- and then everything would error out instantly.
I can't keep these systems I never use straight.
This was completely opaque to me. I've added the guard and of course it passes my local
I rate myself about 3 out of 10 in You obviously know far more Unless there are some more actual bugs -- which I'll attempt to address -- I intend this to be my last push of this branch. I've found another piece of functionality (actual useful code for the end user) that I want to add to |
I had to use similar constructs in my own tests too. It sucks, but we cannot control kernel timings. If the value is long enough for the tests to reliably pass and short enough not to increase test duration too much it is ok. I have rebased the code, added two minor commits and pushed as a new branch, so this MR is now superseded by #30 Thank you for your contribution! |
This pull request adds new
SequencerClientBase.get_address()andSequencerClientBase.fd()methods, andtests/test_sequencer_address.pyfor the former. Also a modifiedexamples/connect.pydemonstrating the new.get_address()capabilities.SequencerClientBase.fd()is a public wrapper for._fd. Access to the ALSA file descriptor is needed for programs doingselect()(e.g. with stdin), and ones that use GUI toolkits withgui.add_fd(); gui.run()semantics. I have successfully usedSequencerClientBase._fdis both cases, in addition tosnd_seq_poll_descriptors()in C/C++ programs. Do you see any problem with doing this? The new.fd()method makes it "official", as well as future-proofing in case of ALSA library changes.SequencerClientBase.get_address()returns anAddressgiven various forms of client and port inputs such as "client-name:port-name" strings, separate "client" and "port" strings,intclient and port IDs, tuples of these,Addressobjects, and mixes/combinations of them. It returns anAddressonly if the specified client/port exists, raising an exception if not. It accepts prefixes/abbreviations/substrings of client and port names, and matches currentAddress()-- and the underlying ALSA C library'ssnd_seq_parse_address()-- semantics of returningAddress(client_id, 0)if given a client without a port, but only if the client exists and has a port 0 (almost universal, but not enforced by the library).An irony is that I have submitted alsa-project/alsa-lib#528 which includes much (but not all) of this functionality directly in the ALSA C library. See that pull request for the reasoning that motivated these proposed enhancements. I originally experimented with including the "name-or-numeric-ID" capability of the enhanced
snd_seq_parse_address()directly intoAddressby adding an optionalSequencerClientBaseparameter to anAddress.__new__()overload. But I am unsure when (if ever) the alsa-lib pull request will be merged, I didn't want python-alsa-midi to depend on an updated release of the ALSA library, and it seemed cleaner and more Pythonic to implement it as aSequencerClientBasemethod anyway. GivenSequencerClientBase.list_ports()this was fairly easy to do, although overload input validation and checking for port/client existence required significant additional code. I also considered merely returningNonefor non-existing client/ports but again felt exceptions better matched the rest of python-alsa-midi's semantics.Included is a unittest program,
tests/test_sequencer_address.pywhich extensively checks many (currently 4179) permutations of input types and expected successful returns or exception failures. Both the new and all existing tests run without error in this branch. A modifiedexamples/connect.pydemonstrates connecting clients/port by name instead of by numeric IDs.Please consider merging this pull request. Feel free to modify/re-architect it as you see fit, hopefully retaining all of the current capabilities. Thank you.