Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

argparse should preserve argument ordering in Namespace #83239

Closed
rhettinger opened this issue Dec 15, 2019 · 5 comments
Closed

argparse should preserve argument ordering in Namespace #83239

rhettinger opened this issue Dec 15, 2019 · 5 comments
Labels
3.9 only security fixes stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@rhettinger
Copy link
Contributor

BPO 39058
Nosy @rhettinger, @ericsnowcurrently
PRs
  • bpo-39058: Preserve attribute order in the repr for argparse.Namespace() #17621
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2020-05-18.01:53:39.428>
    created_at = <Date 2019-12-15.22:16:04.343>
    labels = ['type-feature', 'library', '3.9']
    title = 'argparse should preserve argument ordering in Namespace'
    updated_at = <Date 2020-05-18.01:53:39.428>
    user = 'https://github.com/rhettinger'

    bugs.python.org fields:

    activity = <Date 2020-05-18.01:53:39.428>
    actor = 'rhettinger'
    assignee = 'none'
    closed = True
    closed_date = <Date 2020-05-18.01:53:39.428>
    closer = 'rhettinger'
    components = ['Library (Lib)']
    creation = <Date 2019-12-15.22:16:04.343>
    creator = 'rhettinger'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 39058
    keywords = ['patch']
    message_count = 5.0
    messages = ['358455', '358554', '358556', '358591', '369160']
    nosy_count = 3.0
    nosy_names = ['rhettinger', 'eric.snow', 'paul.j3']
    pr_nums = ['17621']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue39058'
    versions = ['Python 3.9']

    @rhettinger
    Copy link
    Contributor Author

    Currently, Namespace() objects sort the attributes in the __repr__. This is annoying because argument order matters and because everywhere else in the module we preserve order (i.e. users see help in the order that arguments are added).

    Note, the docs do not promise that Namespace is displayed with a sort. This is likely just an artifact of older dictionaries having arbitrary or randomised ordering.

    >> from argparse import ArgumentParser
    >> parser = ArgumentParser()
    >> _ = parser.add_argument('source')
    >> _ = parser.add_argument('destination')

    # Order matters to the user inputing the arguments 
    # (source must go first and destination must go last
    >>> args = parser.parse_args(['input.txt', 'output.txt'])
    
    # Order is preserved internally
    >>> vars(args)
    {'source': 'input.txt', 'destination': 'output.txt'}
    
    # Despite this, the Namespace() repr alphabetizes the output
    >>> args
    Namespace(destination='output.txt', source='input.txt')
    
    # Order is preserved in help()
    >>> parser.parse_args(['-h'])       
    usage: [-h] source destination

    positional arguments:
    source
    destination

    optional arguments:
    -h, --help show this help message and exit

    @rhettinger rhettinger added 3.9 only security fixes stdlib Python modules in the Lib dir type-feature A feature request or enhancement labels Dec 15, 2019
    @ericsnowcurrently
    Copy link
    Member

    Currently, Namespace() objects sort the attributes in the __repr__. This is annoying because argument
    order matters and because everywhere else in the module we preserve order (i.e. users see help in the
    order that arguments are added).

    Hmm, I was going to suggest switching to types.SimpleNamespace, but
    realized we sort that repr too (likely for the same reason). I've
    opened issue bpo-39075 to address that.

    In writing up that issue, I considered that a sorted repr can be
    useful in some cases. However, I don't think any of those cases
    really apply here.

    Anyway, I agree with your conclusion. :)

    @ericsnowcurrently
    Copy link
    Member

    FWIW, I've also opened issue bpo-39076 about subclassing types.SimpleNamespace.

    @paulj3
    Copy link
    Mannequin

    paulj3 mannequin commented Dec 17, 2019

    This patch changes the super class, _AttributeHolder. ArgumentParser and Actions also inherit from this, though they have their own _get_kwargs methods, and so aren't affected by the sort and its removal.

    I just had occasion on stackoverflow to discuss the order in which attributes are added. A poster wanted to preserve the sys.argv order.

    https://stackoverflow.com/questions/58904423/find-the-order-of-arguments-in-argparse-python3/58905067#58905067

    Most attributes are added as defaults at the start of parsing - via a loop through parser._actions. Predefining the namespace, SUPPRESS defaults, parser.set_defaults may alter this default order.

    Anyways removing the sort makes sense, and the proposed change phrase "in the order attributes were added" is sufficiently general.

    @rhettinger
    Copy link
    Contributor Author

    New changeset 9681953 by Raymond Hettinger in branch 'master':
    bpo-39058: Preserve attribute order in argparse Namespace reprs. (GH-17621)
    9681953

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.9 only security fixes stdlib Python modules in the Lib dir type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants