#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 , 3 years ago
comment:2 by , 3 years ago
Easy pickings: | set |
---|---|
Summary: | Custom command help formatting destroyed → Customizable management command formatters. |
Triage Stage: | Unreviewed → Accepted |
Type: | Bug → Cleanup/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: 286 286 Create and return the ``ArgumentParser`` which will be used to 287 287 parse the arguments to this command. 288 288 """ 289 kwargs.setdefault("formatter_class", DjangoHelpFormatter) 289 290 parser = CommandParser( 290 291 prog="%s %s" % (os.path.basename(prog_name), subcommand), 291 292 description=self.help or None, 292 formatter_class=DjangoHelpFormatter,293 293 missing_args_message=getattr(self, "missing_args_message", None), 294 294 called_from_command_line=getattr(self, "_called_from_command_line", None), 295 295 **kwargs,
What do you think?
comment:3 by , 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.
follow-up: 5 comment:4 by , 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
comment:5 by , 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 , 3 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:7 by , 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.
follow-up: 9 comment:8 by , 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?
comment:9 by , 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 , 3 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
comment:11 by , 3 years ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:13 by , 3 years ago
Needs tests: | set |
---|---|
Type: | Cleanup/optimization → Bug |
comment:14 by , 3 years ago
Needs tests: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
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).