Enchancement suggestion for argparse: intuit type from default

Discussion in 'Python' started by Roy Smith, Mar 13, 2012.

  1. Roy Smith

    Roy Smith Guest

    Using argparse, if I write:

    parser.add_argument('--foo', default=100)

    it seems like it should be able to intuit that the type of foo should
    be int (i.e. type(default)) without my having to write:

    parser.add_argument('--foo', type=int, default=100)

    Does this seem like a reasonable enhancement to argparse?
    Roy Smith, Mar 13, 2012
    #1
    1. Advertising

  2. Roy Smith

    rusi Guest

    On Mar 14, 2:08 am, (Roy Smith) wrote:
    > Using argparse, if I write:
    >
    >     parser.add_argument('--foo', default=100)
    >
    > it seems like it should be able to intuit that the type of foo should
    > be int (i.e. type(default)) without my having to write:
    >
    >     parser.add_argument('--foo', type=int, default=100)
    >
    > Does this seem like a reasonable enhancement to argparse?


    Sounds reasonable to me
    rusi, Mar 14, 2012
    #2
    1. Advertising

  3. Am 13.03.2012 22:08, schrieb Roy Smith:
    > Using argparse, if I write:
    >
    > parser.add_argument('--foo', default=100)
    >
    > it seems like it should be able to intuit that the type of foo should
    > be int (i.e. type(default)) without my having to write:
    >
    > parser.add_argument('--foo', type=int, default=100)
    >
    > Does this seem like a reasonable enhancement to argparse?


    The following would turn into an error:

    # in foo.py:
    p.add_argument('--offset', 0)

    # calling foo.py:
    foo.py --offset 1.5

    OTOH, this would be obvious even from halfway serious testing, so I'm +1
    for making this change. Have you looked at existing use of this and
    where it would break anything? When the argument doesn't match the type,
    is the error message sufficiently understandable?

    Uli
    Ulrich Eckhardt, Mar 14, 2012
    #3
  4. On Wed, 14 Mar 2012 08:35:12 +1100, Ben Finney wrote:

    > (Roy Smith) writes:
    >
    >> Using argparse, if I write:
    >>
    >> parser.add_argument('--foo', default=100)
    >>
    >> it seems like it should be able to intuit that the type of foo should
    >> be int (i.e. type(default))

    > […]
    >
    > -0.5.
    >
    > That feels too magical to me. I don't see a need to special-case that
    > usage. There's not much burden in being explicit for the argument type.


    And yet you are programming in Python instead of Java, Pascal or Ada :)

    It's not magic at all, it's science! Or to be precise, it's a very simple
    form of type inference, similar to (but much more basic than) that used
    by languages such as Go, Haskell, Ocaml, and ML.

    http://en.wikipedia.org/wiki/Type_inference

    Given the premise that arguments in argparser are typed, if the argument
    can take the value 100 (the default), it is logical that it can't be a
    string (because 100 is not a string) or a boolean (because 100 is not a
    boolean) or a list (because... well, you get the point).

    What if you want an argument --foo that will accept arbitrary types? Then
    you would need some way to tell argparse not to infer the type from the
    default.

    Python *names* are not typed, but objects are. Python infers the type of
    the object from its syntax. We write:

    n = 100

    and not:

    n = int 100

    Assuming that argparse arguments are typed, and that there is a way to
    over-rule the type-inference, there is no need to declare types in the
    common case. Explicit declarations should be used only for the uncommon
    cases where type inference cannot cope.



    --
    Steven
    Steven D'Aprano, Mar 14, 2012
    #4
  5. Roy Smith

    Roy Smith Guest

    In article <>,
    Ben Finney <> wrote:

    > Right. I dislike proposals for run-time type inference in Python, since
    > they are too magical.
    >
    > Especially since we're talking about user input (arguments from the
    > command line to the program); that requires more explicit declarations
    > and checking, not less.
    >
    > > What if you want an argument --foo that will accept arbitrary types? Then
    > > you would need some way to tell argparse not to infer the type from the
    > > default.

    >
    > So we would then need to special-case the special-case? Even more reason
    > to dislike this proposal.
    >
    > > Explicit declarations should be used only for the uncommon cases where
    > > type inference cannot cope.

    >
    > That's our point of disagreement, then: I think explicit declarations
    > should be required regarding user input.


    I wasn't suggesting that the type be inferred from what the user
    entered. I was suggesting it be inferred from what the programmer had
    done (i.e. what value they had given the 'default' parameter).

    It's already inferred that the type is a string if you don't give it any
    value. What possible meaning could:

    parser.add_argument('--foo', default=100)

    have? If I run the program with:

    $ prog

    then foo defaults to the integer 100, but if I run it with:

    $ prog --foo=100

    then I get the string "100"? Surely there's not much of a use case for
    that.
    Roy Smith, Mar 14, 2012
    #5
  6. Roy Smith

    MRAB Guest

    On 14/03/2012 13:30, Roy Smith wrote:
    > In article<>,
    > Ben Finney<> wrote:
    >
    >> Right. I dislike proposals for run-time type inference in Python, since
    >> they are too magical.
    >>
    >> Especially since we're talking about user input (arguments from the
    >> command line to the program); that requires more explicit declarations
    >> and checking, not less.
    >>
    >> > What if you want an argument --foo that will accept arbitrary types? Then
    >> > you would need some way to tell argparse not to infer the type from the
    >> > default.

    >>
    >> So we would then need to special-case the special-case? Even more reason
    >> to dislike this proposal.
    >>
    >> > Explicit declarations should be used only for the uncommon cases where
    >> > type inference cannot cope.

    >>
    >> That's our point of disagreement, then: I think explicit declarations
    >> should be required regarding user input.

    >
    > I wasn't suggesting that the type be inferred from what the user
    > entered. I was suggesting it be inferred from what the programmer had
    > done (i.e. what value they had given the 'default' parameter).
    >

    In other words, if there's a default but no explicit type, then the
    type is the type of the default.

    > It's already inferred that the type is a string if you don't give it any
    > value. What possible meaning could:
    >
    > parser.add_argument('--foo', default=100)
    >
    > have? If I run the program with:
    >
    > $ prog
    >
    > then foo defaults to the integer 100, but if I run it with:
    >
    > $ prog --foo=100
    >
    > then I get the string "100"? Surely there's not much of a use case for
    > that.
    MRAB, Mar 14, 2012
    #6
  7. Roy Smith

    Ian Kelly Guest

    On Wed, Mar 14, 2012 at 7:30 AM, Roy Smith <> wrote:
    > It's already inferred that the type is a string if you don't give it any
    > value.  What possible meaning could:
    >
    > parser.add_argument('--foo', default=100)
    >
    > have?  If I run the program with:
    >
    > $ prog
    >
    > then foo defaults to the integer 100, but if I run it with:
    >
    > $ prog --foo=100
    >
    > then I get the string "100"?  Surely there's not much of a use case for
    > that.


    What about:

    parser.add_argument('--foo', default=None)

    Probably it should not infer NoneType as the argument type in this
    case. So would it just ignore the default in this case and let the
    type remain str?

    Also, how would the inference interact with different actions? For example:

    parser.add_argument('--foo', action='append', default=['one'])

    I'm not exactly sure what a use case for this might be, but anyway,
    the type here should clearly be str, not list. And then what about
    this variation:

    parser.add_argument('--foo', action='append', default=[1])

    Should it try to infer that because the list contains an int, the type
    should be int? And even if you manage to get the inference working
    flawlessly and expectedly for append, what about custom actions?

    It seems to me that there are a large number of edge cases here that
    will end up hurting predictability for the end user.

    Cheers,
    Ian
    Ian Kelly, Mar 14, 2012
    #7
  8. Roy Smith

    John Nagle Guest

    On 3/13/2012 2:08 PM, Roy Smith wrote:
    > Using argparse, if I write:
    >
    > parser.add_argument('--foo', default=100)
    >
    > it seems like it should be able to intuit that the type of foo should
    > be int (i.e. type(default)) without my having to write:
    >
    > parser.add_argument('--foo', type=int, default=100)
    >
    > Does this seem like a reasonable enhancement to argparse?


    default=None

    presents some problems.

    John Nagle
    John Nagle, Mar 14, 2012
    #8
  9. Roy Smith

    Roy Smith Guest

    In article <4f612a9d$0$12033$>,
    John Nagle <> wrote:

    > On 3/13/2012 2:08 PM, Roy Smith wrote:
    > > Using argparse, if I write:
    > >
    > > parser.add_argument('--foo', default=100)
    > >
    > > it seems like it should be able to intuit that the type of foo should
    > > be int (i.e. type(default)) without my having to write:
    > >
    > > parser.add_argument('--foo', type=int, default=100)
    > >
    > > Does this seem like a reasonable enhancement to argparse?

    >
    > default=None
    >
    > presents some problems.


    I'll admit I hadn't considered that, but I don't see it as a major
    problem. The type intuition could be designed to only work for types
    other than NoneType.
    Roy Smith, Mar 15, 2012
    #9
  10. Roy Smith

    MRAB Guest

    On 15/03/2012 00:52, Roy Smith wrote:
    > In article<4f612a9d$0$12033$>,
    > John Nagle<> wrote:
    >
    >> On 3/13/2012 2:08 PM, Roy Smith wrote:
    >> > Using argparse, if I write:
    >> >
    >> > parser.add_argument('--foo', default=100)
    >> >
    >> > it seems like it should be able to intuit that the type of foo should
    >> > be int (i.e. type(default)) without my having to write:
    >> >
    >> > parser.add_argument('--foo', type=int, default=100)
    >> >
    >> > Does this seem like a reasonable enhancement to argparse?

    >>
    >> default=None
    >>
    >> presents some problems.

    >
    > I'll admit I hadn't considered that, but I don't see it as a major
    > problem. The type intuition could be designed to only work for types
    > other than NoneType.


    True, you could consider that a special case.

    If you really do want NoneType, or if the type doesn't otherwise match
    the default (or there's no default), then you can still be explicit.
    MRAB, Mar 15, 2012
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Giri
    Replies:
    0
    Views:
    350
  2. Giri
    Replies:
    0
    Views:
    430
  3. Giri
    Replies:
    0
    Views:
    328
  4. Giri
    Replies:
    0
    Views:
    292
  5. John O'Hagan
    Replies:
    1
    Views:
    646
    Peter Otten
    Sep 16, 2010
Loading...

Share This Page