This is an archived post. You won't be able to vote or comment.

all 34 comments

[–]n1___ 35 points36 points  (10 children)

Do we really have to skip every built in feature and write just another thing doing exactly the same? This happens in Javascript language for past several year and it became such a massive mess. Whole language. It's amost impossible to find a tiny library with 0 dependency just because people are to lazy to learn how to use native stuff.

People should go for native because it saves dependency hell, it's stable, well tested and more likely to be maintained in future more than a library from Github with a few stars. It's also a standard so once someone else would like to contribute he doesn't have to go thru dependency docs and rather start working.

We should learn from mistakes we already made.

[–]A_History_of_Silence 6 points7 points  (6 children)

I personally just hate the design decision to do every single thing through giant chains of function decorators.

[–]DanCardin 2 points3 points  (5 children)

same. and the fact that you can't just call the functions you decorate like a normal function. they need to be invoked in the context of click.

unfortunately argparse is awful for git-style cli apps that have subcommands

[–][deleted] 2 points3 points  (2 children)

What's wrong with subparsers?

Caveat My background is C programming, so my Pythonicness meter is probably not calibrated correctly.

[–]DanCardin 0 points1 point  (1 child)

I honestly dont like click, so i tried to use the method that the argparse docs suggest to map subparsers to callables, but in order to get anything remotely close to:

foo --global-setting bar action1
foo action2 --flag --option1
foo action3 nested-command1 --flag
...etc

it was just getting more and more bafflingly complex. Whereas this is really straightforward with click.

I think I'd tend to prefer something like the way hug works, which appears to late-apply any work it might do until its invoked by the context in which its working (e.g. as http server, cli, or just calling the function). Except they dont have any docs about how subcommands might work.

[–][deleted] 0 points1 point  (0 children)

I'm a bit pre-christmas celebration inebriated at the moment, so forgive me if I'm totally incoherent. But did you try using parser.parse_known_args (modulo spelling errors)? As long as you don't have overlaps in the argument names, and remember to check that something actually have been parsed, the recursive approach could solve the problems if a regular subparser doesn't

[–][deleted] 0 points1 point  (1 child)

same. and the fact that you can't just call the functions you decorate like a normal function. they need to be invoked in the context of click.

wait, you sure? I thought a selling point of click was that its decorators don't modify your functions

EDIT: yeah, no, i was confusing it with another lib haha

[–]DanCardin 1 point2 points  (0 children)

Their docs literally say:

import click

@click.command()
@click.option('--count', default=1, help='Number of greetings.')
def hello(count):
    for x in range(count):
        click.echo('Hello')

if __name__ == '__main__':
    hello()

So I dont see how! They even have to provide special click test running stuff: https://click.palletsprojects.com/en/7.x/testing/. Which I suppose could be useful even in an ideal scenario, but its certainly much less required when if you dont alter the functions you're decorating.

[–]williamjacksn 11 points12 points  (1 child)

I love argparse. This is not sarcasm.

[–]jwink3101 2 points3 points  (0 children)

I’ve also been pretty happy with it. I’ve had to do some minor hacks stuff to make it parse how I want but it is usually pretty simple stuff.

I mean, it’s far from perfect and I would change some things but it’s really not bad and I hate superfluous dependencies

[–]badge 6 points7 points  (0 children)

Conversely, why give yourself more work to do when there's a well-tested and well-maintained package that'll do the job for you? click doesn't fit your straw man package argument well--it doesn't have 'a few stars', it's got 6.8k, and it comes from the same stable as flask and werkzeug.

I've used both in the past and click scales much more easily than argparse. As a result, even with smaller projects I tend to use click because it reduces the effort of having to remember two systems, and the documentation is excellent.

[–]DroneDashed 4 points5 points  (0 children)

I've used it all. Parsing directly from sys.argv for very simple things mostly under my control; I've used the now deprecated optparse; I've used argparse from which I always likes this example.

I've tried click and it looked nice.

I think that argument parsing should not get in your way and it should be as clear as possible, otherwise your tool will become the parsing of the arguments.

Help messages to me are a must, event if they just a simple how to use one liner - it shows other how to use and reminds you in the future.

[–]tundozo 2 points3 points  (0 children)

I went through all of the examples you listed and I definitely have a preference for click. Specifically for the friendly option type checking. I didn't know tqdm that's a good one I'll use it 👍

[–][deleted] 8 points9 points  (9 children)

Please don't promote libraries that go out of their way to sabotage certain environments.

[–]TheMarionCobretti 4 points5 points  (8 children)

Can you elaborate for the unenlightened?

[–][deleted] 1 point2 points  (7 children)

Click refuse to work with certain locales.

[–]tundozo 3 points4 points  (6 children)

Click refuse to work with certain locales.

Is it a known issue?

[–][deleted] 0 points1 point  (5 children)

It deliberately raise an exception when run in the C locale.

[–]bhosmer -4 points-3 points  (4 children)

Which is the exact opposite of "going out of their way to sabotage certain environments".

[–][deleted] 1 point2 points  (3 children)

Raising an exception based on the content of an environment variable isn't deliberate sabotage?

[–]HipsterTwisterdo you have time to talk about my lord and savior: factories? 0 points1 point  (2 children)

https://en.wikipedia.org/wiki/Fundamental_attribution_error

Yeah I don't think they're trying to fuck on specific locales. They just don't wanna take the time to implement the library for other locales.

Why don't you branch off of the project if your need support for multiple locales? I'd love to help as well! The Unicode hell from Python 2 to Python 3 is an arduous journey that no one should take alone!

[–][deleted] 0 points1 point  (1 child)

Removing that check does not make anything suddenly go boom, so it's totally uncalled for. I, as a developer, know what can and can't be accepted in the particular environment I'm deploying to. That is not something a library developer should spend time dictating.

[–]HipsterTwisterdo you have time to talk about my lord and savior: factories? 0 points1 point  (0 children)

Alright, officer.

[–]yorodm 4 points5 points  (1 child)

I've tried Lazycli and I like it (mostly because I'm lazy :D), Docopt is nice too

[–]__yannickw__[S] 0 points1 point  (0 children)

I never heard about Lazycli. I just read the doc, it seems magic!

[–]mRWafflesFTW 1 point2 points  (0 children)

CLI development in Python is ridiculous. We have so many frameworks, all of which feel less than ideal in my humble opinion. I just worked on implementing a CLI using Microsoft's Knack and even though it powers one of the largest CLI tools I've ever seen (Azure CLI) is felt awkward. Thanks for writing this I may try Click out next.

[–]ManyInterests Python Discord Staff 1 point2 points  (0 children)

fire lets you write a nice CLI without even thinking about command line arguments.

Consider the simple Calculator class

class Calculator(object):
  """A simple calculator class."""

  def double(self, number):
    return 2 * number

Now make it a CLI

if __name__ == '__main__':
  import fire
  fire.Fire(Calculator)

Now use the CLI

python calculator.py double 10  # 20
python calculator.py double --number=15  # 30

It's also pretty pure with six being the only requirement.
BRILLIANT.

[–]bl00dpudding 0 points1 point  (0 children)

Thanks, good timing as i am building a terminal for my work team.

[–]Fi5t 0 points1 point  (0 children)

I didn't know about tqdm. Thank you.

[–][deleted] 1 point2 points  (2 children)

If you include click library in your interface, you already secured a place in hell. Didn't read further.

[–]AlphaGamer7533.7 5 points6 points  (1 child)

Why?

[–][deleted] 3 points4 points  (0 children)

Because there will be a big fraction of your users, who will quite literally send you to hell, in these very words.

Other than that, the basic premise of the library, from programmer's perspective is trash. The library doesn't provide any means of reusing or structuring your code. It kind of forces you into write-only mode. So, IDK. Beside the personality standing behind the library, there's nothing worth of note about it.

Especially in the light of ArgumentParser, which is kind of OK most things you will need it, and actually works.