summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Dufresne <jon.dufresne@gmail.com>2016-03-02 18:01:36 -0800
committerTim Graham <timograham@gmail.com>2016-03-05 13:19:29 -0500
commit1845bc1d1007751a7f65c66aeddc35f032f6bf41 (patch)
tree2f2ae8c2c60b7421e49cbbd40b42ce79fe852566
parent4115288b4f7bbd694946a1ddef0f0ba85c03f9a1 (diff)
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().
-rw-r--r--django/contrib/auth/management/commands/changepassword.py4
-rw-r--r--django/contrib/auth/management/commands/createsuperuser.py8
-rw-r--r--django/contrib/staticfiles/management/commands/runserver.py4
-rw-r--r--django/core/management/base.py4
-rw-r--r--django/core/management/commands/check.py4
-rw-r--r--django/core/management/commands/compilemessages.py8
-rw-r--r--django/core/management/commands/createcachetable.py6
-rw-r--r--django/core/management/commands/dbshell.py2
-rw-r--r--django/core/management/commands/dumpdata.py20
-rw-r--r--django/core/management/commands/flush.py6
-rw-r--r--django/core/management/commands/loaddata.py8
-rw-r--r--django/core/management/commands/makemessages.py26
-rw-r--r--django/core/management/commands/makemigrations.py14
-rw-r--r--django/core/management/commands/migrate.py12
-rw-r--r--django/core/management/commands/runserver.py13
-rw-r--r--django/core/management/commands/showmigrations.py4
-rw-r--r--django/core/management/commands/sqlsequencereset.py2
-rw-r--r--django/core/management/commands/squashmigrations.py4
-rw-r--r--django/core/management/commands/test.py4
-rw-r--r--django/core/management/commands/testserver.py4
-rw-r--r--docs/releases/1.10.txt8
21 files changed, 87 insertions, 78 deletions
diff --git a/django/contrib/auth/management/commands/changepassword.py b/django/contrib/auth/management/commands/changepassword.py
index fd1deada0f..f6a73a8af0 100644
--- a/django/contrib/auth/management/commands/changepassword.py
+++ b/django/contrib/auth/management/commands/changepassword.py
@@ -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:
diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py
index d318c114e6..30850fd4ac 100644
--- a/django/contrib/auth/management/commands/createsuperuser.py
+++ b/django/contrib/auth/management/commands/createsuperuser.py
@@ -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),
diff --git a/django/contrib/staticfiles/management/commands/runserver.py b/django/contrib/staticfiles/management/commands/runserver.py
index 64ef22818e..b6108b8e97 100644
--- a/django/contrib/staticfiles/management/commands/runserver.py
+++ b/django/contrib/staticfiles/management/commands/runserver.py
@@ -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
diff --git a/django/core/management/base.py b/django/core/management/base.py
index de3591a298..f747e57ab4 100644
--- a/django/core/management/base.py
+++ b/django/core/management/base.py
@@ -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:
diff --git a/django/core/management/commands/check.py b/django/core/management/commands/check.py
index 5a66f7ac59..4f5cc71f43 100644
--- a/django/core/management/commands/check.py
+++ b/django/core/management/commands/check.py
@@ -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(
diff --git a/django/core/management/commands/compilemessages.py b/django/core/management/commands/compilemessages.py
index 664c96de05..07e108fa1b 100644
--- a/django/core/management/commands/compilemessages.py
+++ b/django/core/management/commands/compilemessages.py
@@ -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:
diff --git a/django/core/management/commands/createcachetable.py b/django/core/management/commands/createcachetable.py
index fc47cea77d..4a6456b536 100644
--- a/django/core/management/commands/createcachetable.py
+++ b/django/core/management/commands/createcachetable.py
@@ -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:
diff --git a/django/core/management/commands/dbshell.py b/django/core/management/commands/dbshell.py
index 9d6097eb47..d2ff81f7ca 100644
--- a/django/core/management/commands/dbshell.py
+++ b/django/core/management/commands/dbshell.py
@@ -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:
diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py
index 222d1c6f94..f8edcafabb 100644
--- a/django/core/management/commands/dumpdata.py
+++ b/django/core/management/commands/dumpdata.py
@@ -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(',')
diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py
index 018c12ed96..3820f2cce8 100644
--- a/django/core/management/commands/flush.py
+++ b/django/core/management/commands/flush.py
@@ -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)
diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py
index 3cd92d7d4e..a53270a38b 100644
--- a/django/core/management/commands/loaddata.py
+++ b/django/core/management/commands/loaddata.py
@@ -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)
diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py
index ebec17ff01..cfe6d3d087 100644
--- a/django/core/management/commands/makemessages.py
+++ b/django/core/management/commands/makemessages.py
@@ -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 "
diff --git a/django/core/management/commands/makemigrations.py b/django/core/management/commands/makemigrations.py
index 80e4314b3c..229cb991af 100644
--- a/django/core/management/commands/makemigrations.py
+++ b/django/core/management/commands/makemigrations.py
@@ -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:
diff --git a/django/core/management/commands/migrate.py b/django/core/management/commands/migrate.py
index b85021ac72..f78fde3ebb 100644
--- a/django/core/management/commands/migrate.py
+++ b/django/core/management/commands/migrate.py
@@ -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
diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py
index 1f5b52f113..d5c8189d6b 100644
--- a/django/core/management/commands/runserver.py
+++ b/django/core/management/commands/runserver.py
@@ -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'
diff --git a/django/core/management/commands/showmigrations.py b/django/core/management/commands/showmigrations.py
index 254b9c5d4c..0e53e11259 100644
--- a/django/core/management/commands/showmigrations.py
+++ b/django/core/management/commands/showmigrations.py
@@ -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":
diff --git a/django/core/management/commands/sqlsequencereset.py b/django/core/management/commands/sqlsequencereset.py
index ea7286c6ac..ebb6f9da2e 100644
--- a/django/core/management/commands/sqlsequencereset.py
+++ b/django/core/management/commands/sqlsequencereset.py
@@ -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)
diff --git a/django/core/management/commands/squashmigrations.py b/django/core/management/commands/squashmigrations.py
index 9ad5f60d35..61c99baafd 100644
--- a/django/core/management/commands/squashmigrations.py
+++ b/django/core/management/commands/squashmigrations.py
@@ -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']
diff --git a/django/core/management/commands/test.py b/django/core/management/commands/test.py
index 21f2a97850..2d98abebd0 100644
--- a/django/core/management/commands/test.py
+++ b/django/core/management/commands/test.py
@@ -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']
diff --git a/django/core/management/commands/testserver.py b/django/core/management/commands/testserver.py
index 3c14b26181..a241283ce2 100644
--- a/django/core/management/commands/testserver.py
+++ b/django/core/management/commands/testserver.py
@@ -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)
diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt
index 0d1ea5b5d2..e19ecf5662 100644
--- a/docs/releases/1.10.txt
+++ b/docs/releases/1.10.txt
@@ -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