Breaking change with click dependency >= 8.2.0 / miiocli unusable with latest update
The pyproject.toml just constraints click to be >=8. However starting with click 8.2.0 the miiocli is unusable throwing dozens of errors.
The pyproject.toml should constraint to the maximum version of 8.1.8
(.venv) daubsi@t14:/tmp/.venv$ pip install click==8.2.0
Collecting click==8.2.0
Using cached click-8.2.0-py3-none-any.whl.metadata (2.5 kB)
Using cached click-8.2.0-py3-none-any.whl (102 kB)
Installing collected packages: click
Attempting uninstall: click
Found existing installation: click 8.1.8
Uninstalling click-8.1.8:
Successfully uninstalled click-8.1.8
Successfully installed click-8.2.0
(.venv) daubsi@t14:/tmp/.venv$ ./bin/miiocli fan
ERROR:miio.click_common:Exception: sequence item 1: expected str instance, bool found
Traceback (most recent call last):
File "/tmp/.venv/lib/python3.12/site-packages/miio/click_common.py", line 55, in __call__
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/.venv/lib/python3.12/site-packages/click/core.py", line 1363, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "/tmp/.venv/lib/python3.12/site-packages/click/core.py", line 1828, in invoke
sub_ctx = cmd.make_context(cmd_name, args, parent=ctx)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/.venv/lib/python3.12/site-packages/click/core.py", line 1186, in make_context
self.parse_args(ctx, args)
File "/tmp/.venv/lib/python3.12/site-packages/click/core.py", line 1784, in parse_args
raise NoArgsIsHelpError(ctx)
^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/.venv/lib/python3.12/site-packages/click/exceptions.py", line 271, in __init__
super().__init__(ctx.get_help(), ctx=ctx)
^^^^^^^^^^^^^^
File "/tmp/.venv/lib/python3.12/site-packages/click/core.py", line 730, in get_help
return self.command.get_help(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/.venv/lib/python3.12/site-packages/click/core.py", line 1064, in get_help
self.format_help(ctx, formatter)
File "/tmp/.venv/lib/python3.12/site-packages/click/core.py", line 1102, in format_help
self.format_usage(ctx, formatter)
File "/tmp/.venv/lib/python3.12/site-packages/click/core.py", line 1003, in format_usage
formatter.write_usage(ctx.command_path, " ".join(pieces))
^^^^^^^^^^^^^^^^
TypeError: sequence item 1: expected str instance, bool found
(.venv) daubsi@t14:/tmp/.venv$ pip install click==8.1.8
Collecting click==8.1.8
Using cached click-8.1.8-py3-none-any.whl.metadata (2.3 kB)
Using cached click-8.1.8-py3-none-any.whl (98 kB)
Installing collected packages: click
Attempting uninstall: click
Found existing installation: click 8.2.0
Uninstalling click-8.2.0:
Successfully uninstalled click-8.2.0
Successfully installed click-8.1.8
(.venv) daubsi@t14:/tmp/.venv$ ./bin/miiocli fan
Usage: miiocli fan [OPTIONS] COMMAND [ARGS]...
Options:
--ip TEXT [required]
--token TEXT [required]
--model TEXT
--help Show this message and exit.
Commands:
actions Return device actions.
call Call action by name.
delay_off Set delay off seconds.
descriptors Return a collection containing all descriptors for...
info Get (and cache) miIO protocol information from the...
off Power off.
on Power on.
raw_command Send a raw command to the device.
sensors Return read-only properties.
set Change setting value.
set_angle Set the oscillation angle.
set_buzzer Set buzzer on/off.
set_child_lock Set child lock on/off.
set_direct_speed Set speed of the direct mode.
set_led Turn led on/off.
set_led_brightness Set led brightness.
set_natural_speed Set natural level.
set_oscillate Set oscillate on/off.
set_power Turn device on or off.
set_rotate Rotate the fan by -5/+5 degrees left/right.
settings Return settable properties.
status Retrieve properties.
The dependency pin is left on purpose quite broad, as this is used as a library. I'm wondering if this is a regression in click, or if it's something that can be fixed in this project.
Alas, I'm not sure when I will find some time to contribute to this project, so it might take some time to figure out a solution. If you or anyone reading this wants to help, I can do code reviews and merge PRs, though.
Spend a couple of hours today (without prior knowledge about click or python-miio) trying to understand how this all interrelates with the decorations etc. The actual exception is raised in click's core.py as one can see in the stacktrace above, where one argument (subcommand_metavar) which is expected to always only be a str or None all of a sudden is a bool. I was not yet able to trace when or how this happens.
However trying to understand how all those @click decorations are build I stumbled over click_common.py in python-miio which as far as I understand dynamically builds all the relevant structures for click? I can only suspect that something in here is not 100% clean and causes the glitch from a str to a bool.
I noticed there was also a TODO in the code in click_common.py
# TODO HACK to make the command visible to cli
_wrap._device_group_command = func._device_group_command
which might be related...
Apart from that I don´t see any change in click's version changelog (https://click.palletsprojects.com/en/stable/changes/) which might be fitting to what can be seen as a result of the different behavior between 8.1.8 and 8.2.0 of the library.
My attempt of getting some ideas from click's devs was not fruitful so far.
P.S. Manually changing the subcommand_metavar during a debugsession from bool to a string was not successfull. The particular:
File "/tmp/.venv/lib/python3.12/site-packages/click/core.py", line 1003, in format_usage
formatter.write_usage(ctx.command_path, " ".join(pieces))
did no longer throw an exception but another one followed basically saying that no commands were found which let me assume it might be related to the dynamic building of all the annotations.
确实,click降到8.1.8能够正常使用了,感谢。
Thanks @zhu258258669 - in english, downgrade click to 8.1.8
pip install click==8.1.8