@@ -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 ""
@@ -3304,7 +3317,7 @@ def consume_value(
33043317 self .is_flag
33053318 and value is True
33063319 and not self .is_bool_flag
3307- and source not in ( ParameterSource .DEFAULT , ParameterSource . DEFAULT_MAP )
3320+ and source < ParameterSource .DEFAULT_MAP
33083321 ):
33093322 value = self .flag_value
33103323
@@ -3314,7 +3327,7 @@ def consume_value(
33143327 elif (
33153328 self .multiple
33163329 and value is not UNSET
3317- and source not in ( ParameterSource .DEFAULT , ParameterSource . DEFAULT_MAP )
3330+ and source < ParameterSource .DEFAULT_MAP
33183331 and any (v is FLAG_NEEDS_VALUE for v in value )
33193332 ):
33203333 value = [self .flag_value if v is FLAG_NEEDS_VALUE else v for v in value ]
@@ -3323,10 +3336,7 @@ def consume_value(
33233336 # The value wasn't set, or used the param's default, prompt for one to the user
33243337 # if prompting is enabled.
33253338 elif (
3326- (
3327- value is UNSET
3328- or source in (ParameterSource .DEFAULT , ParameterSource .DEFAULT_MAP )
3329- )
3339+ (value is UNSET or source >= ParameterSource .DEFAULT_MAP )
33303340 and self .prompt is not None
33313341 and (self .required or self .prompt_required )
33323342 and not ctx .resilient_parsing
0 commit comments