@@ -1226,6 +1226,19 @@ def parse_args(self, ctx: Context, args: list[str]) -> list[str]:
12261226 for param in iter_params_for_processing (param_order , self .get_params (ctx )):
12271227 _ , args = param .handle_parse_result (ctx , opts , args )
12281228
1229+ # We now have all parameters' values into `ctx.params`, but the data may contain
1230+ # the `UNSET` sentinel.
1231+ # Convert `UNSET` to `None` to ensure that the user doesn't see `UNSET`.
1232+ #
1233+ # Waiting until after the initial parse to convert allows us to treat `UNSET`
1234+ # more like a missing value when multiple params use the same name.
1235+ # Refs:
1236+ # https://github.com/pallets/click/issues/3071
1237+ # https://github.com/pallets/click/pull/3079
1238+ for name , value in ctx .params .items ():
1239+ if value is UNSET :
1240+ ctx .params [name ] = None
1241+
12291242 if args and not ctx .allow_extra_args and not ctx .resilient_parsing :
12301243 ctx .fail (
12311244 ngettext (
@@ -2538,17 +2551,14 @@ def handle_parse_result(
25382551 # We skip adding the value if it was previously set by another parameter
25392552 # targeting the same variable name. This prevents parameters competing for
25402553 # the same name to override each other.
2541- and self .name not in ctx .params
2554+ and ( self .name not in ctx .params or ctx . params [ self . name ] is UNSET )
25422555 ):
25432556 # Click is logically enforcing that the name is None if the parameter is
25442557 # not to be exposed. We still assert it here to please the type checker.
25452558 assert self .name is not None , (
25462559 f"{ self !r} parameter's name should not be None when exposing value."
25472560 )
2548- # Normalize UNSET values to None, as we're about to pass them to the
2549- # command function and move them to the pure-Python realm of user-written
2550- # code.
2551- ctx .params [self .name ] = value if value is not UNSET else None
2561+ ctx .params [self .name ] = value
25522562
25532563 return value , args
25542564
0 commit comments