44import  traceback 
55import  typing  as  ty 
66import  warnings 
7+ from  __future__ import  annotations 
78
89try :
9-     import  asyncclick  as  click 
10+     import  asyncclick 
11+ 
12+     ASYNCCLICK_SUPPORT  =  True 
1013except  ImportError :
14+     ASYNCCLICK_SUPPORT  =  False 
15+ try :
1116    import  click 
12- import  click .core 
17+ 
18+     CLICK_SUPPORT  =  True 
19+ except  ImportError  as  err :
20+     CLICK_SUPPORT  =  False 
21+     if  ASYNCCLICK_SUPPORT :
22+         pass 
23+     else :
24+         raise  err 
1325from  docutils  import  nodes 
1426from  docutils .parsers  import  rst 
1527from  docutils .parsers .rst  import  directives 
2840
2941ANSI_ESC_SEQ_RE  =  re .compile (r'\x1B\[\d+(;\d+){0,2}m' , flags = re .MULTILINE )
3042
31- _T_Formatter  =  ty .Callable [[click .Context ], ty .Generator [str , None , None ]]
43+ if  ASYNCCLICK_SUPPORT  and  CLICK_SUPPORT :
44+     click_context_type  =  asyncclick .Context  |  click .Context 
45+     click_option_type  =  asyncclick .core .Option  |  click .core .Option 
46+     click_choice_type  =  asyncclick .Choice  |  click .Choice 
47+     click_argument_type  =  asyncclick .Argument  |  click .Argument 
48+     click_command_type  =  asyncclick .Command  |  click .Command 
49+     click_multicommand_type  =  asyncclick .MultiCommand  |  click .MultiCommand 
50+     click_group_type  =  asyncclick .Group  |  click .Group 
51+     click_command_collection_type  =  (
52+         asyncclick .CommandCollection  |  click .CommandCollection 
53+     )
54+     join_options  =  click .formatting .join_options 
55+ elif  ASYNCCLICK_SUPPORT :
56+     click_context_type  =  asyncclick .Context 
57+     click_option_type  =  asyncclick .core .Option 
58+     click_choice_type  =  asyncclick .Choice 
59+     click_argument_type  =  asyncclick .Argument 
60+     click_command_type  =  asyncclick .Command 
61+     click_multicommand_type  =  asyncclick .MultiCommand 
62+     click_group_type  =  asyncclick .Group 
63+     click_command_collection_type  =  asyncclick .CommandCollection 
64+     join_options  =  asyncclick .formatting .join_options 
65+ else :
66+     click_context_type  =  click .Context 
67+     click_option_type  =  click .core .Option 
68+     click_choice_type  =  click .Choice 
69+     click_argument_type  =  click .Argument 
70+     click_command_type  =  click .Command 
71+     click_multicommand_type  =  click .MultiCommand 
72+     click_group_type  =  click .Group 
73+     click_command_collection_type  =  click .CommandCollection 
74+     join_options  =  click .formatting .join_options 
75+ 
76+ _T_Formatter  =  ty .Callable [[click_context_type ], ty .Generator [str , None , None ]]
3277
3378
3479def  _process_lines (event_name : str ) ->  ty .Callable [[_T_Formatter ], _T_Formatter ]:
3580    def  decorator (func : _T_Formatter ) ->  _T_Formatter :
3681        @functools .wraps (func ) 
37-         def  process_lines (ctx : click .Context ) ->  ty .Generator [str , None , None ]:
82+         def  process_lines (
83+             ctx : click_context_type ,
84+         ) ->  ty .Generator [str , None , None ]:
3885            lines  =  list (func (ctx ))
3986            if  "sphinx-click-env"  in  ctx .meta :
4087                ctx .meta ["sphinx-click-env" ].app .events .emit (event_name , ctx , lines )
@@ -56,15 +103,18 @@ def prefixed_lines() -> ty.Generator[str, None, None]:
56103    return  '' .join (prefixed_lines ())
57104
58105
59- def  _get_usage (ctx : click . Context ) ->  str :
106+ def  _get_usage (ctx : click_context_type ) ->  str :
60107    """Alternative, non-prefixed version of 'get_usage'.""" 
61108    formatter  =  ctx .make_formatter ()
62109    pieces  =  ctx .command .collect_usage_pieces (ctx )
63110    formatter .write_usage (ctx .command_path , ' ' .join (pieces ), prefix = '' )
64111    return  formatter .getvalue ().rstrip ('\n ' )  # type: ignore 
65112
66113
67- def  _get_help_record (ctx : click .Context , opt : click .core .Option ) ->  ty .Tuple [str , str ]:
114+ def  _get_help_record (
115+     ctx : click_context_type ,
116+     opt : click_option_type ,
117+ ) ->  ty .Tuple [str , str ]:
68118    """Re-implementation of click.Opt.get_help_record. 
69119
70120    The variant of 'get_help_record' found in Click makes uses of slashes to 
@@ -76,7 +126,7 @@ def _get_help_record(ctx: click.Context, opt: click.core.Option) -> ty.Tuple[str
76126    """ 
77127
78128    def  _write_opts (opts : ty .List [str ]) ->  str :
79-         rv , _  =  click . formatting . join_options (opts )
129+         rv , _  =  join_options (opts )
80130        if  not  opt .is_flag  and  not  opt .count :
81131            name  =  opt .name 
82132            if  opt .metavar :
@@ -120,7 +170,7 @@ def _write_opts(opts: ty.List[str]) -> str:
120170            )
121171        )
122172
123-     if  isinstance (opt .type , click . Choice ):
173+     if  isinstance (opt .type , click_choice_type ):
124174        extras .append (':options: %s'  %  ' | ' .join (str (x ) for  x  in  opt .type .choices ))
125175
126176    if  extras :
@@ -150,7 +200,9 @@ def _format_help(help_string: str) -> ty.Generator[str, None, None]:
150200
151201
152202@_process_lines ("sphinx-click-process-description" ) 
153- def  _format_description (ctx : click .Context ) ->  ty .Generator [str , None , None ]:
203+ def  _format_description (
204+     ctx : click_context_type ,
205+ ) ->  ty .Generator [str , None , None ]:
154206    """Format the description for a given `click.Command`. 
155207
156208    We parse this as reStructuredText, allowing users to embed rich 
@@ -162,7 +214,9 @@ def _format_description(ctx: click.Context) -> ty.Generator[str, None, None]:
162214
163215
164216@_process_lines ("sphinx-click-process-usage" ) 
165- def  _format_usage (ctx : click .Context ) ->  ty .Generator [str , None , None ]:
217+ def  _format_usage (
218+     ctx : click_context_type ,
219+ ) ->  ty .Generator [str , None , None ]:
166220    """Format the usage for a `click.Command`.""" 
167221    yield  '.. code-block:: shell' 
168222    yield  '' 
@@ -172,7 +226,8 @@ def _format_usage(ctx: click.Context) -> ty.Generator[str, None, None]:
172226
173227
174228def  _format_option (
175-     ctx : click .Context , opt : click .core .Option 
229+     ctx : click_context_type ,
230+     opt : click_option_type ,
176231) ->  ty .Generator [str , None , None ]:
177232    """Format the output for a `click.core.Option`.""" 
178233    opt_help  =  _get_help_record (ctx , opt )
@@ -194,13 +249,15 @@ def _format_option(
194249
195250
196251@_process_lines ("sphinx-click-process-options" ) 
197- def  _format_options (ctx : click .Context ) ->  ty .Generator [str , None , None ]:
252+ def  _format_options (
253+     ctx : click_context_type ,
254+ ) ->  ty .Generator [str , None , None ]:
198255    """Format all `click.Option` for a `click.Command`.""" 
199256    # the hidden attribute is part of click 7.x only hence use of getattr 
200257    params  =  [
201258        param 
202259        for  param  in  ctx .command .params 
203-         if  isinstance (param , click . core . Option ) and  not  getattr (param , 'hidden' , False )
260+         if  isinstance (param , click_option_type ) and  not  getattr (param , 'hidden' , False )
204261    ]
205262
206263    for  param  in  params :
@@ -209,7 +266,9 @@ def _format_options(ctx: click.Context) -> ty.Generator[str, None, None]:
209266        yield  '' 
210267
211268
212- def  _format_argument (arg : click .Argument ) ->  ty .Generator [str , None , None ]:
269+ def  _format_argument (
270+     arg : click_argument_type ,
271+ ) ->  ty .Generator [str , None , None ]:
213272    """Format the output of a `click.Argument`.""" 
214273    yield  '.. option:: {}' .format (arg .human_readable_name )
215274    yield  '' 
@@ -228,9 +287,11 @@ def _format_argument(arg: click.Argument) -> ty.Generator[str, None, None]:
228287
229288
230289@_process_lines ("sphinx-click-process-arguments" ) 
231- def  _format_arguments (ctx : click .Context ) ->  ty .Generator [str , None , None ]:
290+ def  _format_arguments (
291+     ctx : click_context_type ,
292+ ) ->  ty .Generator [str , None , None ]:
232293    """Format all `click.Argument` for a `click.Command`.""" 
233-     params  =  [x  for  x  in  ctx .command .params  if  isinstance (x , click . Argument )]
294+     params  =  [x  for  x  in  ctx .command .params  if  isinstance (x , click_argument_type )]
234295
235296    for  param  in  params :
236297        for  line  in  _format_argument (param ):
@@ -239,13 +300,13 @@ def _format_arguments(ctx: click.Context) -> ty.Generator[str, None, None]:
239300
240301
241302def  _format_envvar (
242-     param : ty . Union [ click . core . Option ,  click . Argument ] ,
303+     param : click_option_type   |   click_argument_type ,
243304) ->  ty .Generator [str , None , None ]:
244305    """Format the envvars of a `click.Option` or `click.Argument`.""" 
245306    yield  '.. envvar:: {}' .format (param .envvar )
246307    yield  '   :noindex:' 
247308    yield  '' 
248-     if  isinstance (param , click . Argument ):
309+     if  isinstance (param , click_argument_type ):
249310        param_ref  =  param .human_readable_name 
250311    else :
251312        # if a user has defined an opt with multiple "aliases", always use the 
@@ -256,7 +317,9 @@ def _format_envvar(
256317
257318
258319@_process_lines ("sphinx-click-process-envars" ) 
259- def  _format_envvars (ctx : click .Context ) ->  ty .Generator [str , None , None ]:
320+ def  _format_envvars (
321+     ctx : click_context_type ,
322+ ) ->  ty .Generator [str , None , None ]:
260323    """Format all envvars for a `click.Command`.""" 
261324
262325    auto_envvar_prefix  =  ctx .auto_envvar_prefix 
@@ -281,7 +344,9 @@ def _format_envvars(ctx: click.Context) -> ty.Generator[str, None, None]:
281344        yield  '' 
282345
283346
284- def  _format_subcommand (command : click .Command ) ->  ty .Generator [str , None , None ]:
347+ def  _format_subcommand (
348+     command : click_command_type ,
349+ ) ->  ty .Generator [str , None , None ]:
285350    """Format a sub-command of a `click.Command` or `click.Group`.""" 
286351    yield  '.. object:: {}' .format (command .name )
287352
@@ -296,7 +361,9 @@ def _format_subcommand(command: click.Command) -> ty.Generator[str, None, None]:
296361
297362
298363@_process_lines ("sphinx-click-process-epilog" ) 
299- def  _format_epilog (ctx : click .Context ) ->  ty .Generator [str , None , None ]:
364+ def  _format_epilog (
365+     ctx : click_context_type ,
366+ ) ->  ty .Generator [str , None , None ]:
300367    """Format the epilog for a given `click.Command`. 
301368
302369    We parse this as reStructuredText, allowing users to embed rich 
@@ -306,7 +373,9 @@ def _format_epilog(ctx: click.Context) -> ty.Generator[str, None, None]:
306373        yield  from  _format_help (ctx .command .epilog )
307374
308375
309- def  _get_lazyload_commands (ctx : click .Context ) ->  ty .Dict [str , click .Command ]:
376+ def  _get_lazyload_commands (
377+     ctx : click_context_type ,
378+ ) ->  ty .Dict [str , click_command_type ]:
310379    commands  =  {}
311380    for  command  in  ctx .command .list_commands (ctx ):
312381        commands [command ] =  ctx .command .get_command (ctx , command )
@@ -315,12 +384,12 @@ def _get_lazyload_commands(ctx: click.Context) -> ty.Dict[str, click.Command]:
315384
316385
317386def  _filter_commands (
318-     ctx : click . Context ,
387+     ctx : click_context_type ,
319388    commands : ty .Optional [ty .List [str ]] =  None ,
320- ) ->  ty .List [click . Command ]:
389+ ) ->  ty .List [click_command_type ]:
321390    """Return list of used commands.""" 
322391    lookup  =  getattr (ctx .command , 'commands' , {})
323-     if  not  lookup  and  isinstance (ctx .command , click . MultiCommand ):
392+     if  not  lookup  and  isinstance (ctx .command , click_multicommand_type ):
324393        lookup  =  _get_lazyload_commands (ctx )
325394
326395    if  commands  is  None :
@@ -330,7 +399,7 @@ def _filter_commands(
330399
331400
332401def  _format_command (
333-     ctx : click . Context ,
402+     ctx : click_context_type ,
334403    nested : NestedT ,
335404    commands : ty .Optional [ty .List [str ]] =  None ,
336405) ->  ty .Generator [str , None , None ]:
@@ -429,7 +498,7 @@ class ClickDirective(rst.Directive):
429498        'show-nested' : directives .flag ,
430499    }
431500
432-     def  _load_module (self , module_path : str ) ->  ty . Union [ click . Command ,  click . Group ] :
501+     def  _load_module (self , module_path : str ) ->  click_command_type   |   click_group_type :
433502        """Load the module.""" 
434503
435504        try :
@@ -460,7 +529,7 @@ def _load_module(self, module_path: str) -> ty.Union[click.Command, click.Group]
460529
461530        parser  =  getattr (mod , attr_name )
462531
463-         if  not  isinstance (parser , ( click . Command ,  click . Group ) ):
532+         if  not  isinstance (parser , click_command_type   |   click_group_type ):
464533            raise  self .error (
465534                '"{}" of type "{}" is not click.Command or click.Group.' 
466535                '"click.BaseCommand"' .format (type (parser ), module_path )
@@ -470,8 +539,8 @@ def _load_module(self, module_path: str) -> ty.Union[click.Command, click.Group]
470539    def  _generate_nodes (
471540        self ,
472541        name : str ,
473-         command : click . Command ,
474-         parent : ty .Optional [click . Context ],
542+         command : click_command_type ,
543+         parent : ty .Optional [click_context_type ],
475544        nested : NestedT ,
476545        commands : ty .Optional [ty .List [str ]] =  None ,
477546        semantic_group : bool  =  False ,
@@ -490,7 +559,10 @@ def _generate_nodes(
490559            `click.CommandCollection`. 
491560        :returns: A list of nested docutil nodes 
492561        """ 
493-         ctx  =  click .Context (command , info_name = name , parent = parent )
562+         if  ASYNCCLICK_SUPPORT  and  isinstance (command , asyncclick .Command ):
563+             ctx  =  asyncclick .Context (command , info_name = name , parent = parent )
564+         else :
565+             ctx  =  click .Context (command , info_name = name , parent = parent )
494566
495567        if  command .hidden :
496568            return  []
@@ -523,7 +595,7 @@ def _generate_nodes(
523595        # Subcommands 
524596
525597        if  nested  ==  NESTED_FULL :
526-             if  isinstance (command , click . CommandCollection ):
598+             if  isinstance (command , click_command_collection_type ):
527599                for  source  in  command .sources :
528600                    section .extend (
529601                        self ._generate_nodes (
0 commit comments