Mic92 / python-mpd2

Python library which provides a client interface for the Music Player Daemon.
GNU Lesser General Public License v3.0
352 stars 119 forks source link

Add docstring-and-signature style commands #143

Open chrysn opened 3 years ago

chrysn commented 3 years ago

It Would Be Nice If (ie. wishlist-level issue here) mpd commands came with argument and doc strings; mock example in ipython3 syntax:

In [5]: mpc.albumart?
Signature: mpc.albumart(url: str)
Docstring: Returns the album art image for the given song.

*URI* is always a single file or URL.

The returned value is [...]
File:      ~/git/python-mpd2/mpd/base.py
Type:      method

In [6]:

Right now that information is only in the docs, and easily gets out of sync.

The tricky part is obviously to find a place for this in the code; right now, lots of commands (those with the same structure) share a single line. Moving the commands in here would blow code up, but may still be good readability, provided it's grouped well.

Comparison (without having a plan yet on how to make it work in detail):

    @mpd_commands(
        "find",
        "listplaylistinfo",
        "playlistfind",
        "playlistid",
        "playlistinfo",
        "playlistsearch",
        "plchanges",
        "search",
        "sticker find",
        is_direct=True,
    )
    def _parse_songs(self, lines):
        return self._parse_objects_direct(lines, ["file"])

(taking the annotation from the current documentation) to

    @mpd_commands_type(is_direct=True)
    def _parse_songs(self, lines):
        return self._parse_objects_direct(lines, ["file"])

    @mpd_command(_parse_songs)
   def listplaylistinfo(name: str):
        """Returns a list of the songs with metadata in the playlist. Playlist plugins are supported"""

    @mpd_command(_parse_songs)
    def sticker_find(type: Type, uri: str, name: str, relation: Optional[str] = None, value: Optional[str]):
        """Searches the sticker database for stickers with the specified[...]"""

    [...]

The actual function would never be called, but works as a convenient syntax to specify arguments and documentation. Where previously the command was given and the function name was derived (s/ /_/g), this happens in reverse here. Things like __qualname__, __doc__, __annotations__ and __defaults__ could be made available.

(Inspired by #141 where I didn't even notice that that documentation existed when changing the code.)