Refs #26315 -- Cleaned up argparse options in commands.
* Removed type coercion. Options created by argparse are already coerced to the correct type. * Removed fallback default values. Options created by argparse already have a default value. * Used direct indexing. Options created by argparse are always set. This eliminates the need to use dict.get().
This commit is contained in:
parent
4115288b4f
commit
1845bc1d10
|
@ -29,7 +29,7 @@ class Command(BaseCommand):
|
|||
help='Specifies the database to use. Default is "default".')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if options.get('username'):
|
||||
if options['username']:
|
||||
username = options['username']
|
||||
else:
|
||||
username = getpass.getuser()
|
||||
|
@ -37,7 +37,7 @@ class Command(BaseCommand):
|
|||
UserModel = get_user_model()
|
||||
|
||||
try:
|
||||
u = UserModel._default_manager.using(options.get('database')).get(**{
|
||||
u = UserModel._default_manager.using(options['database']).get(**{
|
||||
UserModel.USERNAME_FIELD: username
|
||||
})
|
||||
except UserModel.DoesNotExist:
|
||||
|
|
|
@ -53,8 +53,8 @@ class Command(BaseCommand):
|
|||
return super(Command, self).execute(*args, **options)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
username = options.get(self.UserModel.USERNAME_FIELD)
|
||||
database = options.get('database')
|
||||
username = options[self.UserModel.USERNAME_FIELD]
|
||||
database = options['database']
|
||||
|
||||
# If not provided, create the user with an unusable password
|
||||
password = None
|
||||
|
@ -72,7 +72,7 @@ class Command(BaseCommand):
|
|||
username = self.username_field.clean(username, None)
|
||||
|
||||
for field_name in self.UserModel.REQUIRED_FIELDS:
|
||||
if options.get(field_name):
|
||||
if options[field_name]:
|
||||
field = self.UserModel._meta.get_field(field_name)
|
||||
user_data[field_name] = field.clean(options[field_name], None)
|
||||
else:
|
||||
|
@ -118,7 +118,7 @@ class Command(BaseCommand):
|
|||
|
||||
for field_name in self.UserModel.REQUIRED_FIELDS:
|
||||
field = self.UserModel._meta.get_field(field_name)
|
||||
user_data[field_name] = options.get(field_name)
|
||||
user_data[field_name] = options[field_name]
|
||||
while user_data[field_name] is None:
|
||||
message = force_str('%s%s: ' % (
|
||||
capfirst(field.verbose_name),
|
||||
|
|
|
@ -21,8 +21,8 @@ class Command(RunserverCommand):
|
|||
handler.
|
||||
"""
|
||||
handler = super(Command, self).get_handler(*args, **options)
|
||||
use_static_handler = options.get('use_static_handler', True)
|
||||
insecure_serving = options.get('insecure_serving', False)
|
||||
use_static_handler = options['use_static_handler']
|
||||
insecure_serving = options['insecure_serving']
|
||||
if use_static_handler and (settings.DEBUG or insecure_serving):
|
||||
return StaticFilesHandler(handler)
|
||||
return handler
|
||||
|
|
|
@ -314,13 +314,13 @@ class BaseCommand(object):
|
|||
controlled by the ``requires_system_checks`` attribute, except if
|
||||
force-skipped).
|
||||
"""
|
||||
if options.get('no_color'):
|
||||
if options['no_color']:
|
||||
self.style = no_style()
|
||||
self.stderr.style_func = None
|
||||
if options.get('stdout'):
|
||||
self.stdout = OutputWrapper(options['stdout'])
|
||||
if options.get('stderr'):
|
||||
self.stderr = OutputWrapper(options.get('stderr'), self.stderr.style_func)
|
||||
self.stderr = OutputWrapper(options['stderr'], self.stderr.style_func)
|
||||
|
||||
saved_locale = None
|
||||
if not self.leave_locale_alone:
|
||||
|
|
|
@ -33,7 +33,7 @@ class Command(BaseCommand):
|
|||
|
||||
def handle(self, *app_labels, **options):
|
||||
include_deployment_checks = options['deploy']
|
||||
if options.get('list_tags'):
|
||||
if options['list_tags']:
|
||||
self.stdout.write('\n'.join(sorted(registry.tags_available(include_deployment_checks))))
|
||||
return
|
||||
|
||||
|
@ -42,7 +42,7 @@ class Command(BaseCommand):
|
|||
else:
|
||||
app_configs = None
|
||||
|
||||
tags = options.get('tags')
|
||||
tags = options['tags']
|
||||
if tags:
|
||||
try:
|
||||
invalid_tag = next(
|
||||
|
|
|
@ -45,10 +45,10 @@ class Command(BaseCommand):
|
|||
help='Use fuzzy translations.')
|
||||
|
||||
def handle(self, **options):
|
||||
locale = options.get('locale')
|
||||
exclude = options.get('exclude')
|
||||
self.verbosity = int(options.get('verbosity'))
|
||||
if options.get('fuzzy'):
|
||||
locale = options['locale']
|
||||
exclude = options['exclude']
|
||||
self.verbosity = options['verbosity']
|
||||
if options['fuzzy']:
|
||||
self.program_options = self.program_options + ['-f']
|
||||
|
||||
if find_command(self.program) is None:
|
||||
|
|
|
@ -27,9 +27,9 @@ class Command(BaseCommand):
|
|||
'be run.')
|
||||
|
||||
def handle(self, *tablenames, **options):
|
||||
db = options.get('database')
|
||||
self.verbosity = int(options.get('verbosity'))
|
||||
dry_run = options.get('dry_run')
|
||||
db = options['database']
|
||||
self.verbosity = options['verbosity']
|
||||
dry_run = options['dry_run']
|
||||
if len(tablenames):
|
||||
# Legacy behavior, tablename specified as argument
|
||||
for tablename in tablenames:
|
||||
|
|
|
@ -14,7 +14,7 @@ class Command(BaseCommand):
|
|||
'open a shell. Defaults to the "default" database.')
|
||||
|
||||
def handle(self, **options):
|
||||
connection = connections[options.get('database')]
|
||||
connection = connections[options['database']]
|
||||
try:
|
||||
connection.client.runshell()
|
||||
except OSError:
|
||||
|
|
|
@ -45,16 +45,16 @@ class Command(BaseCommand):
|
|||
help='Specifies file to which the output is written.')
|
||||
|
||||
def handle(self, *app_labels, **options):
|
||||
format = options.get('format')
|
||||
indent = options.get('indent')
|
||||
using = options.get('database')
|
||||
excludes = options.get('exclude')
|
||||
output = options.get('output')
|
||||
show_traceback = options.get('traceback')
|
||||
use_natural_foreign_keys = options.get('use_natural_foreign_keys')
|
||||
use_natural_primary_keys = options.get('use_natural_primary_keys')
|
||||
use_base_manager = options.get('use_base_manager')
|
||||
pks = options.get('primary_keys')
|
||||
format = options['format']
|
||||
indent = options['indent']
|
||||
using = options['database']
|
||||
excludes = options['exclude']
|
||||
output = options['output']
|
||||
show_traceback = options['traceback']
|
||||
use_natural_foreign_keys = options['use_natural_foreign_keys']
|
||||
use_natural_primary_keys = options['use_natural_primary_keys']
|
||||
use_base_manager = options['use_base_manager']
|
||||
pks = options['primary_keys']
|
||||
|
||||
if pks:
|
||||
primary_keys = pks.split(',')
|
||||
|
|
|
@ -25,10 +25,10 @@ class Command(BaseCommand):
|
|||
help='Nominates a database to flush. Defaults to the "default" database.')
|
||||
|
||||
def handle(self, **options):
|
||||
database = options.get('database')
|
||||
database = options['database']
|
||||
connection = connections[database]
|
||||
verbosity = options.get('verbosity')
|
||||
interactive = options.get('interactive')
|
||||
verbosity = options['verbosity']
|
||||
interactive = options['interactive']
|
||||
# The following are stealth options used by Django's internals.
|
||||
reset_sequences = options.get('reset_sequences', True)
|
||||
allow_cascade = options.get('allow_cascade', False)
|
||||
|
|
|
@ -50,10 +50,10 @@ class Command(BaseCommand):
|
|||
|
||||
def handle(self, *fixture_labels, **options):
|
||||
|
||||
self.ignore = options.get('ignore')
|
||||
self.using = options.get('database')
|
||||
self.app_label = options.get('app_label')
|
||||
self.verbosity = options.get('verbosity')
|
||||
self.ignore = options['ignore']
|
||||
self.using = options['database']
|
||||
self.app_label = options['app_label']
|
||||
self.verbosity = options['verbosity']
|
||||
|
||||
with transaction.atomic(using=self.using):
|
||||
self.loaddata(fixture_labels)
|
||||
|
|
|
@ -212,13 +212,13 @@ class Command(BaseCommand):
|
|||
default=False, help="Keep .pot file after making messages. Useful when debugging.")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
locale = options.get('locale')
|
||||
exclude = options.get('exclude')
|
||||
self.domain = options.get('domain')
|
||||
self.verbosity = options.get('verbosity')
|
||||
process_all = options.get('all')
|
||||
extensions = options.get('extensions')
|
||||
self.symlinks = options.get('symlinks')
|
||||
locale = options['locale']
|
||||
exclude = options['exclude']
|
||||
self.domain = options['domain']
|
||||
self.verbosity = options['verbosity']
|
||||
process_all = options['all']
|
||||
extensions = options['extensions']
|
||||
self.symlinks = options['symlinks']
|
||||
|
||||
# Need to ensure that the i18n framework is enabled
|
||||
if settings.configured:
|
||||
|
@ -226,25 +226,25 @@ class Command(BaseCommand):
|
|||
else:
|
||||
settings.configure(USE_I18N=True)
|
||||
|
||||
ignore_patterns = options.get('ignore_patterns')
|
||||
if options.get('use_default_ignore_patterns'):
|
||||
ignore_patterns = options['ignore_patterns']
|
||||
if options['use_default_ignore_patterns']:
|
||||
ignore_patterns += ['CVS', '.*', '*~', '*.pyc']
|
||||
self.ignore_patterns = list(set(ignore_patterns))
|
||||
|
||||
# Avoid messing with mutable class variables
|
||||
if options.get('no_wrap'):
|
||||
if options['no_wrap']:
|
||||
self.msgmerge_options = self.msgmerge_options[:] + ['--no-wrap']
|
||||
self.msguniq_options = self.msguniq_options[:] + ['--no-wrap']
|
||||
self.msgattrib_options = self.msgattrib_options[:] + ['--no-wrap']
|
||||
self.xgettext_options = self.xgettext_options[:] + ['--no-wrap']
|
||||
if options.get('no_location'):
|
||||
if options['no_location']:
|
||||
self.msgmerge_options = self.msgmerge_options[:] + ['--no-location']
|
||||
self.msguniq_options = self.msguniq_options[:] + ['--no-location']
|
||||
self.msgattrib_options = self.msgattrib_options[:] + ['--no-location']
|
||||
self.xgettext_options = self.xgettext_options[:] + ['--no-location']
|
||||
|
||||
self.no_obsolete = options.get('no_obsolete')
|
||||
self.keep_pot = options.get('keep_pot')
|
||||
self.no_obsolete = options['no_obsolete']
|
||||
self.keep_pot = options['keep_pot']
|
||||
|
||||
if self.domain not in ('django', 'djangojs'):
|
||||
raise CommandError("currently makemessages only supports domains "
|
||||
|
|
|
@ -43,13 +43,13 @@ class Command(BaseCommand):
|
|||
help='Exit with a non-zero status if model changes are missing migrations.')
|
||||
|
||||
def handle(self, *app_labels, **options):
|
||||
self.verbosity = options.get('verbosity')
|
||||
self.interactive = options.get('interactive')
|
||||
self.dry_run = options.get('dry_run', False)
|
||||
self.merge = options.get('merge', False)
|
||||
self.empty = options.get('empty', False)
|
||||
self.migration_name = options.get('name')
|
||||
self.exit_code = options.get('exit_code', False)
|
||||
self.verbosity = options['verbosity']
|
||||
self.interactive = options['interactive']
|
||||
self.dry_run = options['dry_run']
|
||||
self.merge = options['merge']
|
||||
self.empty = options['empty']
|
||||
self.migration_name = options['name']
|
||||
self.exit_code = options['exit_code']
|
||||
check_changes = options['check_changes']
|
||||
|
||||
if self.exit_code:
|
||||
|
|
|
@ -47,8 +47,8 @@ class Command(BaseCommand):
|
|||
|
||||
def handle(self, *args, **options):
|
||||
|
||||
self.verbosity = options.get('verbosity')
|
||||
self.interactive = options.get('interactive')
|
||||
self.verbosity = options['verbosity']
|
||||
self.interactive = options['interactive']
|
||||
|
||||
# Import the 'management' module within each installed app, to register
|
||||
# dispatcher events.
|
||||
|
@ -57,7 +57,7 @@ class Command(BaseCommand):
|
|||
import_module('.management', app_config.name)
|
||||
|
||||
# Get the database we're operating from
|
||||
db = options.get('database')
|
||||
db = options['database']
|
||||
connection = connections[db]
|
||||
|
||||
# Hook for backends needing any database preparation
|
||||
|
@ -114,7 +114,7 @@ class Command(BaseCommand):
|
|||
targets = executor.loader.graph.leaf_nodes()
|
||||
|
||||
plan = executor.migration_plan(targets)
|
||||
run_syncdb = options.get('run_syncdb') and executor.loader.unmigrated_apps
|
||||
run_syncdb = options['run_syncdb'] and executor.loader.unmigrated_apps
|
||||
|
||||
# Print some useful info
|
||||
if self.verbosity >= 1:
|
||||
|
@ -172,8 +172,8 @@ class Command(BaseCommand):
|
|||
"apply them."
|
||||
))
|
||||
else:
|
||||
fake = options.get("fake")
|
||||
fake_initial = options.get("fake_initial")
|
||||
fake = options['fake']
|
||||
fake_initial = options['fake_initial']
|
||||
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
|
||||
|
||||
# Send the post_migrate signal, so individual apps can do whatever they need
|
||||
|
|
|
@ -42,7 +42,7 @@ class Command(BaseCommand):
|
|||
help='Tells Django to NOT use the auto-reloader.')
|
||||
|
||||
def execute(self, *args, **options):
|
||||
if options.get('no_color'):
|
||||
if options['no_color']:
|
||||
# We rely on the environment because it's currently the only
|
||||
# way to reach WSGIRequestHandler. This seems an acceptable
|
||||
# compromise considering `runserver` runs indefinitely.
|
||||
|
@ -61,11 +61,11 @@ class Command(BaseCommand):
|
|||
if not settings.DEBUG and not settings.ALLOWED_HOSTS:
|
||||
raise CommandError('You must set settings.ALLOWED_HOSTS if DEBUG is False.')
|
||||
|
||||
self.use_ipv6 = options.get('use_ipv6')
|
||||
self.use_ipv6 = options['use_ipv6']
|
||||
if self.use_ipv6 and not socket.has_ipv6:
|
||||
raise CommandError('Your Python does not support IPv6.')
|
||||
self._raw_ipv6 = False
|
||||
if not options.get('addrport'):
|
||||
if not options['addrport']:
|
||||
self.addr = ''
|
||||
self.port = self.default_port
|
||||
else:
|
||||
|
@ -85,14 +85,14 @@ class Command(BaseCommand):
|
|||
raise CommandError('"%s" is not a valid IPv6 address.' % self.addr)
|
||||
if not self.addr:
|
||||
self.addr = '::1' if self.use_ipv6 else '127.0.0.1'
|
||||
self._raw_ipv6 = bool(self.use_ipv6)
|
||||
self._raw_ipv6 = self.use_ipv6
|
||||
self.run(**options)
|
||||
|
||||
def run(self, **options):
|
||||
"""
|
||||
Runs the server, using the autoreloader if needed
|
||||
"""
|
||||
use_reloader = options.get('use_reloader')
|
||||
use_reloader = options['use_reloader']
|
||||
|
||||
if use_reloader:
|
||||
autoreload.main(self.inner_run, None, options)
|
||||
|
@ -104,7 +104,8 @@ class Command(BaseCommand):
|
|||
# to be raised in the child process, raise it now.
|
||||
autoreload.raise_last_exception()
|
||||
|
||||
threading = options.get('use_threading')
|
||||
threading = options['use_threading']
|
||||
# 'shutdown_message' is a stealth option.
|
||||
shutdown_message = options.get('shutdown_message', '')
|
||||
quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C'
|
||||
|
||||
|
|
|
@ -24,10 +24,10 @@ class Command(BaseCommand):
|
|||
parser.set_defaults(format='list')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
self.verbosity = options.get('verbosity')
|
||||
self.verbosity = options['verbosity']
|
||||
|
||||
# Get the database we're operating from
|
||||
db = options.get('database')
|
||||
db = options['database']
|
||||
connection = connections[db]
|
||||
|
||||
if options['format'] == "plan":
|
||||
|
|
|
@ -18,7 +18,7 @@ class Command(AppCommand):
|
|||
def handle_app_config(self, app_config, **options):
|
||||
if app_config.models_module is None:
|
||||
return
|
||||
connection = connections[options.get('database')]
|
||||
connection = connections[options['database']]
|
||||
models = app_config.get_models(include_auto_created=True)
|
||||
statements = connection.ops.sequence_reset_sql(self.style, models)
|
||||
return '\n'.join(statements)
|
||||
|
|
|
@ -27,8 +27,8 @@ class Command(BaseCommand):
|
|||
|
||||
def handle(self, **options):
|
||||
|
||||
self.verbosity = options.get('verbosity')
|
||||
self.interactive = options.get('interactive')
|
||||
self.verbosity = options['verbosity']
|
||||
self.interactive = options['interactive']
|
||||
app_label = options['app_label']
|
||||
start_migration_name = options['start_migration_name']
|
||||
migration_name = options['migration_name']
|
||||
|
|
|
@ -57,9 +57,9 @@ class Command(BaseCommand):
|
|||
from django.conf import settings
|
||||
from django.test.utils import get_runner
|
||||
|
||||
TestRunner = get_runner(settings, options.get('testrunner'))
|
||||
TestRunner = get_runner(settings, options['testrunner'])
|
||||
|
||||
if options.get('liveserver') is not None:
|
||||
if options['liveserver'] is not None:
|
||||
os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = options['liveserver']
|
||||
del options['liveserver']
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ class Command(BaseCommand):
|
|||
help='Tells Django to use an IPv6 address.')
|
||||
|
||||
def handle(self, *fixture_labels, **options):
|
||||
verbosity = options.get('verbosity')
|
||||
interactive = options.get('interactive')
|
||||
verbosity = options['verbosity']
|
||||
interactive = options['interactive']
|
||||
|
||||
# Create a test database.
|
||||
db_name = connection.creation.create_test_db(verbosity=verbosity, autoclobber=not interactive, serialize=False)
|
||||
|
|
|
@ -640,6 +640,14 @@ Miscellaneous
|
|||
* Tests that violate deferrable database constraints will now error when run on
|
||||
a database that supports deferrable constraints.
|
||||
|
||||
* Built-in management commands now use indexing of keys in ``options``, e.g.
|
||||
``options['verbosity']``, instead of ``options.get()`` and no longer perform
|
||||
any type coercion. This could be a problem if you're calling commands using
|
||||
``Command.execute()`` (which bypasses the argument parser that sets a default
|
||||
value) instead of :func:`~django.core.management.call_command`. Instead of
|
||||
calling ``Command.execute()``, pass the command object as the first argument
|
||||
to ``call_command()``.
|
||||
|
||||
.. _deprecated-features-1.10:
|
||||
|
||||
Features deprecated in 1.10
|
||||
|
|
Loading…
Reference in New Issue