@@ -140,30 +140,43 @@ def sort_key(item: Parameter) -> tuple[bool, float]:
140140 return sorted (declaration_order , key = sort_key )
141141
142142
143- class ParameterSource (enum .Enum ):
144- """This is an :class:`~enum.Enum ` that indicates the source of a
143+ class ParameterSource (enum .IntEnum ):
144+ """This is an :class:`~enum.IntEnum ` that indicates the source of a
145145 parameter's value.
146146
147147 Use :meth:`click.Context.get_parameter_source` to get the
148148 source for a parameter by name.
149149
150+ Members are ordered from most explicit to least explicit source.
151+ This allows comparison to check if a value was explicitly provided:
152+
153+ .. code-block:: python
154+
155+ source = ctx.get_parameter_source("port")
156+ if source < click.ParameterSource.DEFAULT_MAP:
157+ ... # value was explicitly set
158+
159+ .. versionchanged:: 8.3.3
160+ Use :class:`~enum.IntEnum` and reorder members from most to
161+ least explicit. Supports comparison operators.
162+
150163 .. versionchanged:: 8.0
151164 Use :class:`~enum.Enum` and drop the ``validate`` method.
152165
153166 .. versionchanged:: 8.0
154167 Added the ``PROMPT`` value.
155168 """
156169
170+ PROMPT = enum .auto ()
171+ """Used a prompt to confirm a default or provide a value."""
157172 COMMANDLINE = enum .auto ()
158173 """The value was provided by the command line args."""
159174 ENVIRONMENT = enum .auto ()
160175 """The value was provided with an environment variable."""
161- DEFAULT = enum .auto ()
162- """Used the default specified by the parameter."""
163176 DEFAULT_MAP = enum .auto ()
164177 """Used a default provided by :attr:`Context.default_map`."""
165- PROMPT = enum .auto ()
166- """Used a prompt to confirm a default or provide a value ."""
178+ DEFAULT = enum .auto ()
179+ """Used the default specified by the parameter ."""
167180
168181
169182class Context :
@@ -2563,7 +2576,7 @@ def handle_parse_result(
25632576 if (
25642577 self .deprecated
25652578 and value is not UNSET
2566- and source not in ( ParameterSource .DEFAULT , ParameterSource . DEFAULT_MAP )
2579+ and source < ParameterSource .DEFAULT_MAP
25672580 ):
25682581 extra_message = (
25692582 f" { self .deprecated } " if isinstance (self .deprecated , str ) else ""
@@ -3285,7 +3298,7 @@ def consume_value(
32853298 self .is_flag
32863299 and value is True
32873300 and not self .is_bool_flag
3288- and source not in ( ParameterSource .DEFAULT , ParameterSource . DEFAULT_MAP )
3301+ and source < ParameterSource .DEFAULT_MAP
32893302 ):
32903303 value = self .flag_value
32913304
@@ -3295,7 +3308,7 @@ def consume_value(
32953308 elif (
32963309 self .multiple
32973310 and value is not UNSET
3298- and source not in ( ParameterSource .DEFAULT , ParameterSource . DEFAULT_MAP )
3311+ and source < ParameterSource .DEFAULT_MAP
32993312 and any (v is FLAG_NEEDS_VALUE for v in value )
33003313 ):
33013314 value = [self .flag_value if v is FLAG_NEEDS_VALUE else v for v in value ]
@@ -3304,10 +3317,7 @@ def consume_value(
33043317 # The value wasn't set, or used the param's default, prompt for one to the user
33053318 # if prompting is enabled.
33063319 elif (
3307- (
3308- value is UNSET
3309- or source in (ParameterSource .DEFAULT , ParameterSource .DEFAULT_MAP )
3310- )
3320+ (value is UNSET or source >= ParameterSource .DEFAULT_MAP )
33113321 and self .prompt is not None
33123322 and (self .required or self .prompt_required )
33133323 and not ctx .resilient_parsing
0 commit comments