Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(317)

Unified Diff: venv/Lib/site-packages/django/core/management/__init__.py

Issue 554060043: testMe
Patch Set: Created 2 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: venv/Lib/site-packages/django/core/management/__init__.py
===================================================================
new file mode 100644
--- /dev/null
+++ b/venv/Lib/site-packages/django/core/management/__init__.py
@@ -0,0 +1,364 @@
+from __future__ import unicode_literals
+
+import os
+import pkgutil
+import sys
+from collections import OrderedDict, defaultdict
+from importlib import import_module
+
+import django
+from django.apps import apps
+from django.conf import settings
+from django.core.exceptions import ImproperlyConfigured
+from django.core.management.base import (
+ BaseCommand, CommandError, CommandParser, handle_default_options,
+)
+from django.core.management.color import color_style
+from django.utils import autoreload, lru_cache, six
+from django.utils._os import npath, upath
+from django.utils.encoding import force_text
+
+
+def find_commands(management_dir):
+ """
+ Given a path to a management directory, returns a list of all the command
+ names that are available.
+
+ Returns an empty list if no commands are defined.
+ """
+ command_dir = os.path.join(management_dir, 'commands')
+ return [name for _, name, is_pkg in pkgutil.iter_modules([npath(command_dir)])
+ if not is_pkg and not name.startswith('_')]
+
+
+def load_command_class(app_name, name):
+ """
+ Given a command name and an application name, returns the Command
+ class instance. All errors raised by the import process
+ (ImportError, AttributeError) are allowed to propagate.
+ """
+ module = import_module('%s.management.commands.%s' % (app_name, name))
+ return module.Command()
+
+
+@lru_cache.lru_cache(maxsize=None)
+def get_commands():
+ """
+ Returns a dictionary mapping command names to their callback applications.
+
+ This works by looking for a management.commands package in django.core, and
+ in each installed application -- if a commands package exists, all commands
+ in that package are registered.
+
+ Core commands are always included. If a settings module has been
+ specified, user-defined commands will also be included.
+
+ The dictionary is in the format {command_name: app_name}. Key-value
+ pairs from this dictionary can then be used in calls to
+ load_command_class(app_name, command_name)
+
+ If a specific version of a command must be loaded (e.g., with the
+ startapp command), the instantiated module can be placed in the
+ dictionary in place of the application name.
+
+ The dictionary is cached on the first call and reused on subsequent
+ calls.
+ """
+ commands = {name: 'django.core' for name in find_commands(upath(__path__[0]))}
+
+ if not settings.configured:
+ return commands
+
+ for app_config in reversed(list(apps.get_app_configs())):
+ path = os.path.join(app_config.path, 'management')
+ commands.update({name: app_config.name for name in find_commands(path)})
+
+ return commands
+
+
+def call_command(command_name, *args, **options):
+ """
+ Calls the given command, with the given options and args/kwargs.
+
+ This is the primary API you should use for calling specific commands.
+
+ `command_name` may be a string or a command object. Using a string is
+ preferred unless the command object is required for further processing or
+ testing.
+
+ Some examples:
+ call_command('migrate')
+ call_command('shell', plain=True)
+ call_command('sqlmigrate', 'myapp')
+
+ from django.core.management.commands import flush
+ cmd = flush.Command()
+ call_command(cmd, verbosity=0, interactive=False)
+ # Do something with cmd ...
+ """
+ if isinstance(command_name, BaseCommand):
+ # Command object passed in.
+ command = command_name
+ command_name = command.__class__.__module__.split('.')[-1]
+ else:
+ # Load the command object by name.
+ try:
+ app_name = get_commands()[command_name]
+ except KeyError:
+ raise CommandError("Unknown command: %r" % command_name)
+
+ if isinstance(app_name, BaseCommand):
+ # If the command is already loaded, use it directly.
+ command = app_name
+ else:
+ command = load_command_class(app_name, command_name)
+
+ # Simulate argument parsing to get the option defaults (see #10080 for details).
+ parser = command.create_parser('', command_name)
+ # Use the `dest` option name from the parser option
+ opt_mapping = {
+ sorted(s_opt.option_strings)[0].lstrip('-').replace('-', '_'): s_opt.dest
+ for s_opt in parser._actions if s_opt.option_strings
+ }
+ arg_options = {opt_mapping.get(key, key): value for key, value in options.items()}
+ defaults = parser.parse_args(args=[force_text(a) for a in args])
+ defaults = dict(defaults._get_kwargs(), **arg_options)
+ # Move positional args out of options to mimic legacy optparse
+ args = defaults.pop('args', ())
+ if 'skip_checks' not in options:
+ defaults['skip_checks'] = True
+
+ return command.execute(*args, **defaults)
+
+
+class ManagementUtility(object):
+ """
+ Encapsulates the logic of the django-admin and manage.py utilities.
+ """
+ def __init__(self, argv=None):
+ self.argv = argv or sys.argv[:]
+ self.prog_name = os.path.basename(self.argv[0])
+ self.settings_exception = None
+
+ def main_help_text(self, commands_only=False):
+ """
+ Returns the script's main help text, as a string.
+ """
+ if commands_only:
+ usage = sorted(get_commands().keys())
+ else:
+ usage = [
+ "",
+ "Type '%s help <subcommand>' for help on a specific subcommand." % self.prog_name,
+ "",
+ "Available subcommands:",
+ ]
+ commands_dict = defaultdict(lambda: [])
+ for name, app in six.iteritems(get_commands()):
+ if app == 'django.core':
+ app = 'django'
+ else:
+ app = app.rpartition('.')[-1]
+ commands_dict[app].append(name)
+ style = color_style()
+ for app in sorted(commands_dict.keys()):
+ usage.append("")
+ usage.append(style.NOTICE("[%s]" % app))
+ for name in sorted(commands_dict[app]):
+ usage.append(" %s" % name)
+ # Output an extra note if settings are not properly configured
+ if self.settings_exception is not None:
+ usage.append(style.NOTICE(
+ "Note that only Django core commands are listed "
+ "as settings are not properly configured (error: %s)."
+ % self.settings_exception))
+
+ return '\n'.join(usage)
+
+ def fetch_command(self, subcommand):
+ """
+ Tries to fetch the given subcommand, printing a message with the
+ appropriate command called from the command line (usually
+ "django-admin" or "manage.py") if it can't be found.
+ """
+ # Get commands outside of try block to prevent swallowing exceptions
+ commands = get_commands()
+ try:
+ app_name = commands[subcommand]
+ except KeyError:
+ if os.environ.get('DJANGO_SETTINGS_MODULE'):
+ # If `subcommand` is missing due to misconfigured settings, the
+ # following line will retrigger an ImproperlyConfigured exception
+ # (get_commands() swallows the original one) so the user is
+ # informed about it.
+ settings.INSTALLED_APPS
+ else:
+ sys.stderr.write("No Django settings specified.\n")
+ sys.stderr.write(
+ "Unknown command: %r\nType '%s help' for usage.\n"
+ % (subcommand, self.prog_name)
+ )
+ sys.exit(1)
+ if isinstance(app_name, BaseCommand):
+ # If the command is already loaded, use it directly.
+ klass = app_name
+ else:
+ klass = load_command_class(app_name, subcommand)
+ return klass
+
+ def autocomplete(self):
+ """
+ Output completion suggestions for BASH.
+
+ The output of this function is passed to BASH's `COMREPLY` variable and
+ treated as completion suggestions. `COMREPLY` expects a space
+ separated string as the result.
+
+ The `COMP_WORDS` and `COMP_CWORD` BASH environment variables are used
+ to get information about the cli input. Please refer to the BASH
+ man-page for more information about this variables.
+
+ Subcommand options are saved as pairs. A pair consists of
+ the long option string (e.g. '--exclude') and a boolean
+ value indicating if the option requires arguments. When printing to
+ stdout, an equal sign is appended to options which require arguments.
+
+ Note: If debugging this function, it is recommended to write the debug
+ output in a separate file. Otherwise the debug output will be treated
+ and formatted as potential completion suggestions.
+ """
+ # Don't complete if user hasn't sourced bash_completion file.
+ if 'DJANGO_AUTO_COMPLETE' not in os.environ:
+ return
+
+ cwords = os.environ['COMP_WORDS'].split()[1:]
+ cword = int(os.environ['COMP_CWORD'])
+
+ try:
+ curr = cwords[cword - 1]
+ except IndexError:
+ curr = ''
+
+ subcommands = list(get_commands()) + ['help']
+ options = [('--help', False)]
+
+ # subcommand
+ if cword == 1:
+ print(' '.join(sorted(filter(lambda x: x.startswith(curr), subcommands))))
+ # subcommand options
+ # special case: the 'help' subcommand has no options
+ elif cwords[0] in subcommands and cwords[0] != 'help':
+ subcommand_cls = self.fetch_command(cwords[0])
+ # special case: add the names of installed apps to options
+ if cwords[0] in ('dumpdata', 'sqlmigrate', 'sqlsequencereset', 'test'):
+ try:
+ app_configs = apps.get_app_configs()
+ # Get the last part of the dotted path as the app name.
+ options.extend((app_config.label, 0) for app_config in app_configs)
+ except ImportError:
+ # Fail silently if DJANGO_SETTINGS_MODULE isn't set. The
+ # user will find out once they execute the command.
+ pass
+ parser = subcommand_cls.create_parser('', cwords[0])
+ options.extend(
+ (sorted(s_opt.option_strings)[0], s_opt.nargs != 0)
+ for s_opt in parser._actions if s_opt.option_strings
+ )
+ # filter out previously specified options from available options
+ prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]]
+ options = [opt for opt in options if opt[0] not in prev_opts]
+
+ # filter options by current input
+ options = sorted((k, v) for k, v in options if k.startswith(curr))
+ for option in options:
+ opt_label = option[0]
+ # append '=' to options which require args
+ if option[1]:
+ opt_label += '='
+ print(opt_label)
+ # Exit code of the bash completion function is never passed back to
+ # the user, so it's safe to always exit with 0.
+ # For more details see #25420.
+ sys.exit(0)
+
+ def execute(self):
+ """
+ Given the command-line arguments, this figures out which subcommand is
+ being run, creates a parser appropriate to that command, and runs it.
+ """
+ try:
+ subcommand = self.argv[1]
+ except IndexError:
+ subcommand = 'help' # Display help if no arguments were given.
+
+ # Preprocess options to extract --settings and --pythonpath.
+ # These options could affect the commands that are available, so they
+ # must be processed early.
+ parser = CommandParser(None, usage="%(prog)s subcommand [options] [args]", add_help=False)
+ parser.add_argument('--settings')
+ parser.add_argument('--pythonpath')
+ parser.add_argument('args', nargs='*') # catch-all
+ try:
+ options, args = parser.parse_known_args(self.argv[2:])
+ handle_default_options(options)
+ except CommandError:
+ pass # Ignore any option errors at this point.
+
+ try:
+ settings.INSTALLED_APPS
+ except ImproperlyConfigured as exc:
+ self.settings_exception = exc
+
+ if settings.configured:
+ # Start the auto-reloading dev server even if the code is broken.
+ # The hardcoded condition is a code smell but we can't rely on a
+ # flag on the command class because we haven't located it yet.
+ if subcommand == 'runserver' and '--noreload' not in self.argv:
+ try:
+ autoreload.check_errors(django.setup)()
+ except Exception:
+ # The exception will be raised later in the child process
+ # started by the autoreloader. Pretend it didn't happen by
+ # loading an empty list of applications.
+ apps.all_models = defaultdict(OrderedDict)
+ apps.app_configs = OrderedDict()
+ apps.apps_ready = apps.models_ready = apps.ready = True
+
+ # Remove options not compatible with the built-in runserver
+ # (e.g. options for the contrib.staticfiles' runserver).
+ # Changes here require manually testing as described in
+ # #27522.
+ _parser = self.fetch_command('runserver').create_parser('django', 'runserver')
+ _options, _args = _parser.parse_known_args(self.argv[2:])
+ for _arg in _args:
+ self.argv.remove(_arg)
+
+ # In all other cases, django.setup() is required to succeed.
+ else:
+ django.setup()
+
+ self.autocomplete()
+
+ if subcommand == 'help':
+ if '--commands' in args:
+ sys.stdout.write(self.main_help_text(commands_only=True) + '\n')
+ elif len(options.args) < 1:
+ sys.stdout.write(self.main_help_text() + '\n')
+ else:
+ self.fetch_command(options.args[0]).print_help(self.prog_name, options.args[0])
+ # Special-cases: We want 'django-admin --version' and
+ # 'django-admin --help' to work, for backwards compatibility.
+ elif subcommand == 'version' or self.argv[1:] == ['--version']:
+ sys.stdout.write(django.get_version() + '\n')
+ elif self.argv[1:] in (['--help'], ['-h']):
+ sys.stdout.write(self.main_help_text() + '\n')
+ else:
+ self.fetch_command(subcommand).run_from_argv(self.argv)
+
+
+def execute_from_command_line(argv=None):
+ """
+ A simple method that runs a ManagementUtility.
+ """
+ utility = ManagementUtility(argv)
+ utility.execute()
« no previous file with comments | « venv/Lib/site-packages/django/core/mail/utils.py ('k') | venv/Lib/site-packages/django/core/management/base.py » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b