#31035: Promote BaseCommand.run_from_argv to a documented method
-------------------------------+--------------------------------------
Reporter: Roman Odaisky | Owner: nobody
Type: New feature | Status: closed
Component: Documentation | Version: master
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by Roman Odaisky):
Replying to [comment:3 Carlton Gibson]:
> > Maybe another overridable method should be introduced between
run_from_argv() and handle()?
>
> Yes... what's needed I guess is a way to tell the parser to use
[https://docs.python.org/3.8/library/argparse.html#argparse.ArgumentParser.parse_known_args
`parse_known_args()`]
> (a `self.parse_args()` hook I suppose).
>
> Is this something you'd want to work on?
The extra method would be trivial, see below—commands can override
execute_argv() while any important cleanup code can still be added to
run_from_argv (which will continue being an undocumented implementation
detail). Using parse_known_args also wouldn’t be very hard, except if the
3rd party CLI to which you’re forwarding the arguments accepts, say,
--verbosity=4, Django won’t pass that through.
{{{
diff --git a/django/core/management/base.py
b/django/core/management/base.py
index 0376d67662..619e9503e3 100644
--- a/django/core/management/base.py
+++ b/django/core/management/base.py
@@ -317,6 +317,17 @@ class BaseCommand:
``Exception`` is not ``CommandError``, raise it.
"""
self._called_from_command_line = True
+ try:
+ self.execute_argv(argv)
+ finally:
+ try:
+ connections.close_all()
+ except ImproperlyConfigured:
+ # Ignore if connections aren't setup at this point (e.g.
no
+ # configured settings).
+ pass
+
+ def execute_argv(self, argv):
parser = self.create_parser(argv[0], argv[1])
options = parser.parse_args(argv[2:])
@@ -324,10 +335,11 @@ class BaseCommand:
# Move positional args out of options to mimic legacy optparse
args = cmd_options.pop('args', ())
handle_default_options(options)
+
try:
self.execute(*args, **cmd_options)
- except Exception as e:
- if options.traceback or not isinstance(e, CommandError):
+ except CommandError as e:
+ if options.traceback:
raise
# SystemCheckError takes care of its own formatting.
@@ -336,13 +348,6 @@ class BaseCommand:
else:
self.stderr.write('%s: %s' % (e.__class__.__name__, e))
sys.exit(1)
- finally:
- try:
- connections.close_all()
- except ImproperlyConfigured:
- # Ignore if connections aren't setup at this point (e.g.
no
- # configured settings).
- pass
def execute(self, *args, **options):
"""
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31035#comment:4>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/065.7334337fb3a20c9fe625913b5d01f5e1%40djangoproject.com.