From 3da2f88dfe7a79219138298d5a2c328014a9da64 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sun, 5 Feb 2017 05:57:41 +0300 Subject: [PATCH] Delete deprecated gunicorn_django command and --settings option --- docs/source/news.rst | 11 ++ docs/source/run.rst | 2 + docs/source/settings.rst | 18 --- gunicorn/app/django_wsgi.py | 120 -------------- gunicorn/app/djangoapp.py | 160 ------------------- gunicorn/config.py | 17 -- gunicorn/management/__init__.py | 0 gunicorn/management/commands/__init__.py | 0 gunicorn/management/commands/run_gunicorn.py | 113 ------------- setup.py | 1 - 10 files changed, 13 insertions(+), 429 deletions(-) delete mode 100644 gunicorn/app/django_wsgi.py delete mode 100644 gunicorn/app/djangoapp.py delete mode 100644 gunicorn/management/__init__.py delete mode 100644 gunicorn/management/commands/__init__.py delete mode 100644 gunicorn/management/commands/run_gunicorn.py diff --git a/docs/source/news.rst b/docs/source/news.rst index 42c50eec..6108d980 100644 --- a/docs/source/news.rst +++ b/docs/source/news.rst @@ -2,6 +2,17 @@ Changelog ========= +19.7.0 / Not yet released +========================= + +Core +++++ + +- The previously deprecated ``gunicorn_django`` command has been deprecated. + Use the :ref:`gunicorn-cmd` command-line interface instead. +- The previously deprecated ``django_settings`` setting has been removed. + Use the :ref:`raw-env` setting instead. + 19.6.0 / 2016/05/21 =================== diff --git a/docs/source/run.rst b/docs/source/run.rst index 84636102..879e91df 100644 --- a/docs/source/run.rst +++ b/docs/source/run.rst @@ -13,6 +13,8 @@ Commands After installing Gunicorn you will have access to the command line script ``gunicorn``. +.. _gunicorn-cmd: + gunicorn -------- diff --git a/docs/source/settings.rst b/docs/source/settings.rst index 85d113ef..30d6e808 100644 --- a/docs/source/settings.rst +++ b/docs/source/settings.rst @@ -805,24 +805,6 @@ default_proc_name Internal setting that is adjusted for each type of application. -Django ------- - -.. _django-settings: - -django_settings -~~~~~~~~~~~~~~~ - -* ``--settings STRING`` -* ``None`` - -The Python path to a Django settings module. (deprecated) - -e.g. ``myproject.settings.main``. If this isn't provided, the -``DJANGO_SETTINGS_MODULE`` environment variable will be used. - -**DEPRECATED**: use the ``--env`` argument instead. - Server Mechanics ---------------- diff --git a/gunicorn/app/django_wsgi.py b/gunicorn/app/django_wsgi.py deleted file mode 100644 index 31d8aec2..00000000 --- a/gunicorn/app/django_wsgi.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- coding: utf-8 - -# -# This file is part of gunicorn released under the MIT license. -# See the NOTICE for more information. - -""" module used to build the django wsgi application """ -from __future__ import print_function - -import os -import re -import sys -import time -try: - from StringIO import StringIO -except: - from io import StringIO - from imp import reload - - -from django.conf import settings -from django.core.management.validation import get_validation_errors -from django.utils import translation - -try: - from django.core.servers.basehttp import get_internal_wsgi_application - django14 = True -except ImportError: - from django.core.handlers.wsgi import WSGIHandler - django14 = False - -from gunicorn import util - - -def make_wsgi_application(): - # validate models - s = StringIO() - if get_validation_errors(s): - s.seek(0) - error = s.read() - msg = "One or more models did not validate:\n%s" % error - print(msg, file=sys.stderr) - sys.stderr.flush() - sys.exit(1) - - translation.activate(settings.LANGUAGE_CODE) - if django14: - return get_internal_wsgi_application() - return WSGIHandler() - - -def reload_django_settings(): - mod = util.import_module(os.environ['DJANGO_SETTINGS_MODULE']) - - # Reload module. - reload(mod) - - # Reload settings. - # Use code from django.settings.Settings module. - - # Settings that should be converted into tuples if they're mistakenly entered - # as strings. - tuple_settings = ("INSTALLED_APPS", "TEMPLATE_DIRS") - - for setting in dir(mod): - if setting == setting.upper(): - setting_value = getattr(mod, setting) - if setting in tuple_settings and type(setting_value) == str: - setting_value = (setting_value,) # In case the user forgot the comma. - setattr(settings, setting, setting_value) - - # Expand entries in INSTALLED_APPS like "django.contrib.*" to a list - # of all those apps. - new_installed_apps = [] - for app in settings.INSTALLED_APPS: - if app.endswith('.*'): - app_mod = util.import_module(app[:-2]) - appdir = os.path.dirname(app_mod.__file__) - app_subdirs = os.listdir(appdir) - name_pattern = re.compile(r'[a-zA-Z]\w*') - for d in sorted(app_subdirs): - if (name_pattern.match(d) and - os.path.isdir(os.path.join(appdir, d))): - new_installed_apps.append('%s.%s' % (app[:-2], d)) - else: - new_installed_apps.append(app) - setattr(settings, "INSTALLED_APPS", new_installed_apps) - - if hasattr(time, 'tzset') and settings.TIME_ZONE: - # When we can, attempt to validate the timezone. If we can't find - # this file, no check happens and it's harmless. - zoneinfo_root = '/usr/share/zoneinfo' - if (os.path.exists(zoneinfo_root) and not - os.path.exists(os.path.join(zoneinfo_root, - *(settings.TIME_ZONE.split('/'))))): - raise ValueError("Incorrect timezone setting: %s" % - settings.TIME_ZONE) - # Move the time zone info into os.environ. See ticket #2315 for why - # we don't do this unconditionally (breaks Windows). - os.environ['TZ'] = settings.TIME_ZONE - time.tzset() - - # Settings are configured, so we can set up the logger if required - if getattr(settings, 'LOGGING_CONFIG', False): - # First find the logging configuration function ... - logging_config_path, logging_config_func_name = settings.LOGGING_CONFIG.rsplit('.', 1) - logging_config_module = util.import_module(logging_config_path) - logging_config_func = getattr(logging_config_module, logging_config_func_name) - - # ... then invoke it with the logging settings - logging_config_func(settings.LOGGING) - - -def make_command_wsgi_application(admin_mediapath): - reload_django_settings() - - try: - from django.core.servers.basehttp import AdminMediaHandler - return AdminMediaHandler(make_wsgi_application(), admin_mediapath) - except ImportError: - return make_wsgi_application() diff --git a/gunicorn/app/djangoapp.py b/gunicorn/app/djangoapp.py deleted file mode 100644 index c14f37a1..00000000 --- a/gunicorn/app/djangoapp.py +++ /dev/null @@ -1,160 +0,0 @@ -# -*- coding: utf-8 - -# -# This file is part of gunicorn released under the MIT license. -# See the NOTICE for more information. - -import os -import sys - -from gunicorn.app.base import Application -from gunicorn import util - - -def is_setting_mod(path): - return (os.path.isfile(os.path.join(path, "settings.py")) or - os.path.isfile(os.path.join(path, "settings.pyc"))) - - -def find_settings_module(path): - path = os.path.abspath(path) - project_path = None - settings_name = "settings" - - if os.path.isdir(path): - project_path = None - if not is_setting_mod(path): - for d in os.listdir(path): - if d in ('..', '.'): - continue - - root = os.path.join(path, d) - if is_setting_mod(root): - project_path = root - break - else: - project_path = path - elif os.path.isfile(path): - project_path = os.path.dirname(path) - settings_name, _ = os.path.splitext(os.path.basename(path)) - - return project_path, settings_name - - -def make_default_env(cfg): - if cfg.django_settings: - os.environ['DJANGO_SETTINGS_MODULE'] = cfg.django_settings - - if cfg.pythonpath and cfg.pythonpath is not None: - paths = cfg.pythonpath.split(",") - for path in paths: - pythonpath = os.path.abspath(cfg.pythonpath) - if pythonpath not in sys.path: - sys.path.insert(0, pythonpath) - - try: - os.environ['DJANGO_SETTINGS_MODULE'] - except KeyError: - # not settings env set, try to build one. - cwd = util.getcwd() - project_path, settings_name = find_settings_module(cwd) - - if not project_path: - raise RuntimeError("django project not found") - - pythonpath, project_name = os.path.split(project_path) - os.environ['DJANGO_SETTINGS_MODULE'] = "%s.%s" % (project_name, - settings_name) - if pythonpath not in sys.path: - sys.path.insert(0, pythonpath) - - if project_path not in sys.path: - sys.path.insert(0, project_path) - - -class DjangoApplication(Application): - - def init(self, parser, opts, args): - if args: - if ("." in args[0] and not (os.path.isfile(args[0]) - or os.path.isdir(args[0]))): - self.cfg.set("django_settings", args[0]) - else: - # not settings env set, try to build one. - project_path, settings_name = find_settings_module( - os.path.abspath(args[0])) - if project_path not in sys.path: - sys.path.insert(0, project_path) - - if not project_path: - raise RuntimeError("django project not found") - - pythonpath, project_name = os.path.split(project_path) - self.cfg.set("django_settings", "%s.%s" % (project_name, - settings_name)) - self.cfg.set("pythonpath", pythonpath) - - def load(self): - # chdir to the configured path before loading, - # default is the current dir - os.chdir(self.cfg.chdir) - - # set settings - make_default_env(self.cfg) - - # load wsgi application and return it. - mod = util.import_module("gunicorn.app.django_wsgi") - return mod.make_wsgi_application() - - -class DjangoApplicationCommand(Application): - - def __init__(self, options, admin_media_path): - self.usage = None - self.prog = None - self.cfg = None - self.config_file = options.get("config") or "" - self.options = options - self.admin_media_path = admin_media_path - self.callable = None - self.project_path = None - self.do_load_config() - - def init(self, *args): - if 'settings' in self.options: - self.options['django_settings'] = self.options.pop('settings') - - cfg = {} - for k, v in self.options.items(): - if k.lower() in self.cfg.settings and v is not None: - cfg[k.lower()] = v - return cfg - - def load(self): - # chdir to the configured path before loading, - # default is the current dir - os.chdir(self.cfg.chdir) - - # set settings - make_default_env(self.cfg) - - # load wsgi application and return it. - mod = util.import_module("gunicorn.app.django_wsgi") - return mod.make_command_wsgi_application(self.admin_media_path) - - -def run(): - """\ - The ``gunicorn_django`` command line runner for launching Django - applications. - """ - util.warn("""This command is deprecated. - - You should now run your application with the WSGI interface - installed with your project. Ex.: - - gunicorn myproject.wsgi:application - - See https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/gunicorn/ - for more info.""") - from gunicorn.app.djangoapp import DjangoApplication - DjangoApplication("%(prog)s [OPTIONS] [SETTINGS_PATH]").run() diff --git a/gunicorn/config.py b/gunicorn/config.py index 607bfb3a..8b058ccc 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -1411,23 +1411,6 @@ class DefaultProcName(Setting): """ -class DjangoSettings(Setting): - name = "django_settings" - section = "Django" - cli = ["--settings"] - meta = "STRING" - validator = validate_string - default = None - desc = """\ - The Python path to a Django settings module. (deprecated) - - e.g. ``myproject.settings.main``. If this isn't provided, the - ``DJANGO_SETTINGS_MODULE`` environment variable will be used. - - **DEPRECATED**: use the ``--env`` argument instead. - """ - - class PythonPath(Setting): name = "pythonpath" section = "Server Mechanics" diff --git a/gunicorn/management/__init__.py b/gunicorn/management/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/gunicorn/management/commands/__init__.py b/gunicorn/management/commands/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/gunicorn/management/commands/run_gunicorn.py b/gunicorn/management/commands/run_gunicorn.py deleted file mode 100644 index 6ee35d6d..00000000 --- a/gunicorn/management/commands/run_gunicorn.py +++ /dev/null @@ -1,113 +0,0 @@ -# -*- coding: utf-8 - -# -# This file is part of gunicorn released under the MIT license. -# See the NOTICE for more information. - -from optparse import make_option -import sys - -from django.core.management.base import BaseCommand, CommandError - -from gunicorn.app.djangoapp import DjangoApplicationCommand -from gunicorn.config import make_settings -from gunicorn import util - - -# monkey patch django. -# This patch make sure that we use real threads to get the ident which -# is going to happen if we are using gevent or eventlet. -try: - from django.db.backends import BaseDatabaseWrapper, DatabaseError - - if "validate_thread_sharing" in BaseDatabaseWrapper.__dict__: - import thread - _get_ident = thread.get_ident - - __old__init__ = BaseDatabaseWrapper.__init__ - - def _init(self, *args, **kwargs): - __old__init__(self, *args, **kwargs) - self._thread_ident = _get_ident() - - def _validate_thread_sharing(self): - if (not self.allow_thread_sharing - and self._thread_ident != _get_ident()): - raise DatabaseError("DatabaseWrapper objects created in a " - "thread can only be used in that same thread. The object " - "with alias '%s' was created in thread id %s and this is " - "thread id %s." - % (self.alias, self._thread_ident, _get_ident())) - - BaseDatabaseWrapper.__init__ = _init - BaseDatabaseWrapper.validate_thread_sharing = _validate_thread_sharing -except ImportError: - pass - - -def make_options(): - opts = [ - make_option('--adminmedia', dest='admin_media_path', default='', - help='Specifies the directory from which to serve admin media.') - ] - - g_settings = make_settings(ignore=("version")) - keys = g_settings.keys() - for k in keys: - if k in ('pythonpath', 'django_settings',): - continue - - setting = g_settings[k] - if not setting.cli: - continue - - args = tuple(setting.cli) - - kwargs = { - "dest": setting.name, - "metavar": setting.meta or None, - "action": setting.action or "store", - "type": setting.type or "string", - "default": None, - "help": "%s [%s]" % (setting.short, setting.default) - } - if kwargs["action"] != "store": - kwargs.pop("type") - - opts.append(make_option(*args, **kwargs)) - - return tuple(opts) - -GUNICORN_OPTIONS = make_options() - - -class Command(BaseCommand): - option_list = BaseCommand.option_list + GUNICORN_OPTIONS - help = "Starts a fully-functional Web server using gunicorn." - args = '[optional port number, or ipaddr:port or unix:/path/to/sockfile]' - - # Validation is called explicitly each time the server is reloaded. - requires_model_validation = False - - def handle(self, addrport=None, *args, **options): - - # deprecation warning to announce future deletion in R21 - util.warn("""This command is deprecated. - - You should now run your application with the WSGI interface - installed with your project. Ex.: - - gunicorn myproject.wsgi:application - - See https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/gunicorn/ - for more info.""") - - if args: - raise CommandError('Usage is run_gunicorn %s' % self.args) - - if addrport: - sys.argv = sys.argv[:-1] - options['bind'] = addrport - - admin_media_path = options.pop('admin_media_path', '') - - DjangoApplicationCommand(options, admin_media_path).run() diff --git a/setup.py b/setup.py index 8f3b9f1d..52656f24 100644 --- a/setup.py +++ b/setup.py @@ -94,7 +94,6 @@ setup( entry_points=""" [console_scripts] gunicorn=gunicorn.app.wsgiapp:run - gunicorn_django=gunicorn.app.djangoapp:run gunicorn_paster=gunicorn.app.pasterapp:run [paste.server_runner]