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() |