fix: Fix compatibility with Click 8.2.0+

Closes https://github.com/espressif/esptool/issues/1105
Closes https://github.com/espressif/esptool/pull/1104
This commit is contained in:
Peter Dragun
2025-07-25 11:10:27 +02:00
parent 0f32306551
commit 524825e25f
4 changed files with 33 additions and 16 deletions

View File

@@ -23,12 +23,22 @@ from . import util
from .emulate_efuse_controller_base import EmulateEfuseControllerBase
class EfuseValuePairArg(click.Argument):
class EfuseArgument(click.Argument):
def make_metavar(self, ctx: click.Context | None = None) -> str:
"""Compatibility layer for Click 8.2.0+; which now requires a ctx parameter."""
try:
return super().make_metavar(ctx) # type: ignore
except TypeError:
# Fall back to the old signature (pre-Click 8.2.0)
return super().make_metavar() # type: ignore
class EfuseValuePairArg(EfuseArgument):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def make_metavar(self) -> str:
return f"[{super().make_metavar()}] ..."
def make_metavar(self, ctx=None) -> str:
return f"[{super().make_metavar(ctx)}] ..."
def type_cast_value(self, ctx: click.Context, value: list[str]):
return self.type.convert(value, None, ctx)
@@ -84,17 +94,17 @@ class CustomMACType(click.ParamType):
return base_fields.CheckArgValue(ctx.obj["efuses"], "CUSTOM_MAC")(value)
class TupleParameter(click.Argument):
class TupleParameter(EfuseArgument):
def __init__(self, *args, **kwargs):
self.max_arity = kwargs.pop("max_arity", None)
super().__init__(*args, **kwargs)
def make_metavar(self) -> str:
def make_metavar(self, ctx=None) -> str:
if self.nargs == 1:
return super().make_metavar() # type: ignore
return super().make_metavar(ctx) # type: ignore
if self.max_arity is None:
return f"[{super().make_metavar()}] ..."
return f"[{super().make_metavar()}] ... (max {self.max_arity} groups)"
return f"[{super().make_metavar(ctx)}] ..."
return f"[{super().make_metavar(ctx)}] ... (max {self.max_arity} groups)"
def type_cast_value(self, ctx: click.Context, value: list[str]) -> tuple[Any, ...]:
# This is by default eating all options, so we need to check for help option

View File

@@ -930,11 +930,6 @@ def erase_flash_cli(ctx, force, **kwargs):
)
@click.argument("address", type=AnyIntType())
@click.argument("size", type=AutoSizeType())
@click.option(
"--force",
is_flag=True,
help="Erase region even if security features are enabled. Use with caution!",
)
@add_spi_connection_arg
@click.pass_context
def erase_region_cli(ctx, address, size, force, **kwargs):

View File

@@ -155,7 +155,9 @@ class AddrFilenamePairType(click.Path):
name = "addr-filename-pair"
def get_metavar(self, param):
def get_metavar(
self, param: click.Parameter | None, ctx: click.Context | None = None
):
return "<address> <filename>"
def convert(
@@ -294,7 +296,17 @@ class OptionEatAll(click.Option):
self._eat_all_parser = None
# Set the metavar dynamically based on the type's metavar
if self.type and hasattr(self.type, "name"):
self.metavar = f"[{self.type.get_metavar(None) or self.type.name.upper()}]"
self.metavar = f"[{self._get_metavar() or self.type.name.upper()}]"
def _get_metavar(self):
"""Get the metavar for the option. Wrapper for compatibility reasons.
In Click 8.2.0+, the `get_metavar` requires new parameter `ctx`.
"""
try:
ctx = click.get_current_context(silent=True)
return self.type.get_metavar(None, ctx)
except TypeError:
return self.type.get_metavar(None)
def add_to_parser(self, parser, ctx):
def parser_process(value, state):

View File

@@ -38,7 +38,7 @@
"PyYAML>=5.1",
"intelhex",
"rich_click",
"click<8.2.0",
"click<9",
]
[project.urls]