@@ -70,6 +70,12 @@ The resulting value from an option will always be one of the originally passed c
7070regardless of `case_sensitive`.
7171```
7272
73+ ``` {versionchanged} 8.4.0
74+ {class}`Choice` is now generic. Parameterize it with the choice value type
75+ ({class}`!Choice[HashType]` for an enum, {class}`!Choice[str]` for plain
76+ strings) to enable type-checked consumers.
77+ ```
78+
7379(ranges)=
7480
7581### Int and Float Ranges
@@ -153,16 +159,21 @@ To implement a custom type, you need to subclass the {class}`ParamType` class. F
153159function that fails with a ` ValueError ` is also supported, though discouraged. Override the {meth}` ~ParamType.convert `
154160method to convert the value from a string to the correct type.
155161
162+ {class}` ParamType ` is generic in the converted value type: parameterize it with
163+ the type returned by ` convert ` so that consumers (and type checkers) can rely
164+ on the narrowed return type.
165+
156166The following code implements an integer type that accepts hex and octal numbers in addition to normal integers, and
157167converts them into regular integers.
158168
159169``` python
160170import click
161171
162- class BasedIntParamType (click .ParamType ):
172+
173+ class BasedIntParamType (click .ParamType[int ]):
163174 name = " integer"
164175
165- def convert (self , value , param , ctx ):
176+ def convert (self , value , param , ctx ) -> int :
166177 if isinstance (value, int ):
167178 return value
168179
@@ -175,6 +186,7 @@ class BasedIntParamType(click.ParamType):
175186 except ValueError :
176187 self .fail(f " { value!r } is not a valid integer " , param, ctx)
177188
189+
178190BASED_INT = BasedIntParamType()
179191```
180192
@@ -184,3 +196,10 @@ conversion fails. The `param` and `ctx` arguments may be `None` in some cases su
184196Values from user input or the command line will be strings, but default values and Python arguments may already be the
185197correct type. The custom type should check at the top if the value is already valid and pass it through to support those
186198cases.
199+
200+ ``` {versionchanged} 8.4.0
201+ {class}`ParamType` is now a generic abstract base class. Parameterize it with
202+ the converted value type ({class}`!ParamType[int]` for an integer-returning
203+ type) so that {meth}`~ParamType.convert` and downstream consumers carry the
204+ narrowed type.
205+ ```
0 commit comments