I have this code that works fine:
import click
@click.command(context_settings=dict(help_option_names=['-h', '--help']))
@click.option('--team_name', required=True, help='Team name')
@click.option('--input_file', default='url_file.txt', help='Input file name for applications, URLs')
@click.option('--output_file', default='test_results_file.txt', help='Output file name to store test results')
def main(team_name, input_file, output_file):
# function body
if __name__ == '__main__':
main() # how does this work?
As you see, main
is being called with no arguments though it is supposed to receive three. How does this work?
As mentioned in comments, this is taken care by the decorators. The click.command
decorator turns the function into an instance of click.Command
.
Each of options decorators build an instance of a click.Option
and attach it to the click.Command
object to be used later.
This click.Command
object implements a __call__
method which is invoked by your call to main()
.
def __call__(self, *args, **kwargs):
"""Alias for :meth:`main`."""
return self.main(*args, **kwargs)
It is quite simple and simply invokes click.Command.main()
.
Near the top of click.Command.main()
is:
if args is None:
args = get_os_args()
else:
args = list(args)
This code gets argv
from the command line or uses a provided list of args. Further code in this method does, among other things, the parsing of the command line into a context, and the eventual calling of your main()
with the values from the click.Option
instances built earlier:
with self.make_context(prog_name, args, **extra) as ctx:
rv = self.invoke(ctx)
This is the source of the mysterious 3 arguments.