Opened 3 years ago

Closed 2 years ago

Last modified 2 years ago

#33657 closed Bug (fixed)

Customizable management command formatters.

Reported by: James Pic Owned by: Abhinav Yadav
Component: Core (Management commands) Version: 4.0
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

With code like:

class Command(BaseCommand):
    help = '''
    Import a contract from tzkt.

    Example usage:

        ./manage.py tzkt_import 'Tezos Mainnet' KT1HTDtMBRCKoNHjfWEEvXneGQpCfPAt6BRe
    '''

Help output is:

$ ./manage.py help tzkt_import
usage: manage.py tzkt_import [-h] [--api API] [--version] [-v {0,1,2,3}] [--settings SETTINGS]
                             [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color]
                             [--skip-checks]
                             blockchain target

Import a contract from tzkt Example usage: ./manage.py tzkt_import 'Tezos Mainnet'
KT1HTDtMBRCKoNHjfWEEvXneGQpCfPAt6BRe

positional arguments:
  blockchain            Name of the blockchain to import into
  target                Id of the contract to import

When that was expected:

$ ./manage.py help tzkt_import
usage: manage.py tzkt_import [-h] [--api API] [--version] [-v {0,1,2,3}] [--settings SETTINGS]
                             [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color]
                             [--skip-checks]
                             blockchain target

Import a contract from tzkt 

Example usage: 

    ./manage.py tzkt_import 'Tezos Mainnet' KT1HTDtMBRCKoNHjfWEEvXneGQpCfPAt6BRe


positional arguments:
  blockchain            Name of the blockchain to import into
  target                Id of the contract to import

Change History (16)

comment:1 by Tim Graham, 3 years ago

This seems no fault of Django but is rather the default behavior of ArgumentParser ("By default, ArgumentParser objects line-wrap the description and epilog texts in command-line help messages"). This can be changed by using a custom formatter_class, though Django already specifies a custom one (DjangoHelpFormatter).

comment:2 by Mariusz Felisiak, 3 years ago

Easy pickings: set
Summary: Custom command help formatting destroyedCustomizable management command formatters.
Triage Stage: UnreviewedAccepted
Type: BugCleanup/optimization

It seems reasonable, to make it customizable by passing via kwargs to the BaseCommand.create_parser() (as documented):

  • django/core/management/base.py

    diff --git a/django/core/management/base.py b/django/core/management/base.py
    index f0e711ac76..52407807d8 100644
    a b class BaseCommand:  
    286286        Create and return the ``ArgumentParser`` which will be used to
    287287        parse the arguments to this command.
    288288        """
     289        kwargs.setdefault("formatter_class", DjangoHelpFormatter)
    289290        parser = CommandParser(
    290291            prog="%s %s" % (os.path.basename(prog_name), subcommand),
    291292            description=self.help or None,
    292             formatter_class=DjangoHelpFormatter,
    293293            missing_args_message=getattr(self, "missing_args_message", None),
    294294            called_from_command_line=getattr(self, "_called_from_command_line", None),
    295295            **kwargs,

What do you think?

comment:3 by James Pic, 3 years ago

Looks good but I don't see a reason for keeping a default that swallows newlines because PEP257 forbids having a multiline sentence on the first line anyway:

Multi-line docstrings consist of a summary line just like a one-line docstring, followed by a blank line, followed by a more elaborate description.

As such, the default formater which purpose is to unwrap the first sentence encourages breaking PEP 257.

And users who are naturally complying with PEP257 will have to override the formatter, it should be the other way around.

comment:4 by James Pic, 3 years ago

Also, the not-unwraping formater will also look fine with existing docstrings, it will work for both use cases, while the current one only works for one use case and breaks the other. The default formater should work for both

in reply to:  4 comment:5 by Mariusz Felisiak, 3 years ago

Replying to James Pic:

Also, the not-unwraping formater will also look fine with existing docstrings, it will work for both use cases, while the current one only works for one use case and breaks the other. The default formater should work for both

It seems you think that Python's (not Django's) default behavior should be changed according to PEP 257. I'd recommend to start a discussion in Python's bugtracker. As far as I'm aware the proposed solution will allow users to freely change a formatter, which should be enough from the Django point of view.

comment:6 by Subhankar Hotta, 3 years ago

Owner: changed from nobody to Subhankar Hotta
Status: newassigned

comment:7 by James Pic, 3 years ago

No, I think that Django's default behavior should match Python's PEP 257, and at the same time, have a default that works in all use cases.

I think my report and comments are pretty clear, I fail to understand how you could get my comment completely backward, so, unless you have any specific question about this statement, I'm going to give up on this.

Last edited 3 years ago by James Pic (previous) (diff)

comment:8 by Subhankar Hotta, 3 years ago

So as part of this issue, do we make changes to allow a user to override the formatter through kwargs and also keep DjangoHelpFormatter as the default?

in reply to:  8 comment:9 by Mariusz Felisiak, 3 years ago

Replying to Subhankar Hotta:

So as part of this issue, do we make changes to allow a user to override the formatter through kwargs and also keep DjangoHelpFormatter as the default?

Yes, see comment.

comment:10 by Mariusz Felisiak, 2 years ago

Owner: Subhankar Hotta removed
Status: assignednew

comment:11 by Abhinav Yadav, 2 years ago

Owner: set to Abhinav Yadav
Status: newassigned

comment:12 by Abhinav Yadav, 2 years ago

Has patch: set

comment:13 by Mariusz Felisiak, 2 years ago

Needs tests: set
Type: Cleanup/optimizationBug

comment:14 by Mariusz Felisiak, 2 years ago

Needs tests: unset
Triage Stage: AcceptedReady for checkin

comment:15 by GitHub <noreply@…>, 2 years ago

Resolution: fixed
Status: assignedclosed

In 2887b9f:

Fixed #33657 -- Allowed customizing formatter class of argument parsers.

comment:16 by Mariusz Felisiak <felisiak.mariusz@…>, 2 years ago

In 99e5ce96:

[4.1.x] Fixed #33657 -- Allowed customizing formatter class of argument parsers.

Backport of 2887b9f67cadc5295ef6a0574de2c2c8fdd66905 from main

Note: See TracTickets for help on using tickets.
Back to Top