#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.

Reply via email to