1
0
mirror of https://github.com/django/django.git synced 2025-10-23 21:59:11 +00:00

Merge branch 'master' into schema-alteration

Conflicts:
	django/db/backends/mysql/introspection.py
	django/db/backends/oracle/creation.py
	django/db/backends/postgresql_psycopg2/creation.py
	django/db/models/base.py
	django/db/models/loading.py
This commit is contained in:
Andrew Godwin
2013-07-22 19:04:25 +01:00
231 changed files with 2725 additions and 1373 deletions

View File

@@ -180,7 +180,11 @@ def encode_multipart(boundary, data):
def encode_file(boundary, key, file):
to_bytes = lambda s: force_bytes(s, settings.DEFAULT_CHARSET)
content_type = mimetypes.guess_type(file.name)[0]
if hasattr(file, 'content_type'):
content_type = file.content_type
else:
content_type = mimetypes.guess_type(file.name)[0]
if content_type is None:
content_type = 'application/octet-stream'
return [

View File

@@ -238,6 +238,7 @@ def setup_databases(verbosity, interactive, **kwargs):
mirrored_aliases = {}
test_databases = {}
dependencies = {}
default_sig = connections[DEFAULT_DB_ALIAS].creation.test_db_signature()
for alias in connections:
connection = connections[alias]
if connection.settings_dict['TEST_MIRROR']:
@@ -259,7 +260,7 @@ def setup_databases(verbosity, interactive, **kwargs):
dependencies[alias] = (
connection.settings_dict['TEST_DEPENDENCIES'])
else:
if alias != DEFAULT_DB_ALIAS:
if alias != DEFAULT_DB_ALIAS and connection.creation.test_db_signature() != default_sig:
dependencies[alias] = connection.settings_dict.get(
'TEST_DEPENDENCIES', [DEFAULT_DB_ALIAS])
@@ -271,15 +272,16 @@ def setup_databases(verbosity, interactive, **kwargs):
test_databases.items(), dependencies):
test_db_name = None
# Actually create the database for the first connection
for alias in aliases:
connection = connections[alias]
old_names.append((connection, db_name, True))
if test_db_name is None:
test_db_name = connection.creation.create_test_db(
verbosity, autoclobber=not interactive)
destroy = True
else:
connection.settings_dict['NAME'] = test_db_name
destroy = False
old_names.append((connection, db_name, destroy))
for alias, mirror_alias in mirrored_aliases.items():
mirrors.append((alias, connections[alias].settings_dict['NAME']))

View File

@@ -1,5 +1,6 @@
import os
import time
import warnings
from django.conf import settings
from django.db import connections
@@ -9,11 +10,14 @@ from django.utils.functional import empty
template_rendered = Signal(providing_args=["template", "context"])
setting_changed = Signal(providing_args=["setting", "value"])
setting_changed = Signal(providing_args=["setting", "value", "enter"])
# Most setting_changed receivers are supposed to be added below,
# except for cases where the receiver is related to a contrib app.
# Settings that may not work well when using 'override_settings' (#19031)
COMPLEX_OVERRIDE_SETTINGS = set(['DATABASES'])
@receiver(setting_changed)
def update_connections_time_zone(**kwargs):
@@ -74,8 +78,15 @@ def language_changed(**kwargs):
if kwargs['setting'] == 'LOCALE_PATHS':
trans_real._translations = {}
@receiver(setting_changed)
def file_storage_changed(**kwargs):
if kwargs['setting'] in ('MEDIA_ROOT', 'DEFAULT_FILE_STORAGE'):
from django.core.files.storage import default_storage
default_storage._wrapped = empty
@receiver(setting_changed)
def complex_setting_changed(**kwargs):
if kwargs['enter'] and kwargs['setting'] in COMPLEX_OVERRIDE_SETTINGS:
warnings.warn("Overriding setting %s can lead to unexpected behaviour." % kwargs['setting'])

View File

@@ -8,7 +8,6 @@ import json
import os
import re
import sys
import select
import socket
import threading
import unittest
@@ -880,10 +879,19 @@ class TestCase(TransactionTestCase):
self.atomics[db_name].__exit__(None, None, None)
class CheckCondition(object):
"""Descriptor class for deferred condition checking"""
def __init__(self, cond_func):
self.cond_func = cond_func
def __get__(self, obj, objtype):
return self.cond_func()
def _deferredSkip(condition, reason):
def decorator(test_func):
if not (isinstance(test_func, type) and
issubclass(test_func, TestCase)):
issubclass(test_func, unittest.TestCase)):
@wraps(test_func)
def skip_wrapper(*args, **kwargs):
if condition():
@@ -891,7 +899,9 @@ def _deferredSkip(condition, reason):
return test_func(*args, **kwargs)
test_item = skip_wrapper
else:
# Assume a class is decorated
test_item = test_func
test_item.__unittest_skip__ = CheckCondition(condition)
test_item.__unittest_skip_why__ = reason
return test_item
return decorator
@@ -924,104 +934,6 @@ class QuietWSGIRequestHandler(WSGIRequestHandler):
pass
if sys.version_info >= (3, 3, 0):
_ImprovedEvent = threading.Event
elif sys.version_info >= (2, 7, 0):
_ImprovedEvent = threading._Event
else:
class _ImprovedEvent(threading._Event):
"""
Does the same as `threading.Event` except it overrides the wait() method
with some code borrowed from Python 2.7 to return the set state of the
event (see: http://hg.python.org/cpython/rev/b5aa8aa78c0f/). This allows
to know whether the wait() method exited normally or because of the
timeout. This class can be removed when Django supports only Python >= 2.7.
"""
def wait(self, timeout=None):
self._Event__cond.acquire()
try:
if not self._Event__flag:
self._Event__cond.wait(timeout)
return self._Event__flag
finally:
self._Event__cond.release()
class StoppableWSGIServer(WSGIServer):
"""
The code in this class is borrowed from the `SocketServer.BaseServer` class
in Python 2.6. The important functionality here is that the server is non-
blocking and that it can be shut down at any moment. This is made possible
by the server regularly polling the socket and checking if it has been
asked to stop.
Note for the future: Once Django stops supporting Python 2.6, this class
can be removed as `WSGIServer` will have this ability to shutdown on
demand and will not require the use of the _ImprovedEvent class whose code
is borrowed from Python 2.7.
"""
def __init__(self, *args, **kwargs):
super(StoppableWSGIServer, self).__init__(*args, **kwargs)
self.__is_shut_down = _ImprovedEvent()
self.__serving = False
def serve_forever(self, poll_interval=0.5):
"""
Handle one request at a time until shutdown.
Polls for shutdown every poll_interval seconds.
"""
self.__serving = True
self.__is_shut_down.clear()
while self.__serving:
r, w, e = select.select([self], [], [], poll_interval)
if r:
self._handle_request_noblock()
self.__is_shut_down.set()
def shutdown(self):
"""
Stops the serve_forever loop.
Blocks until the loop has finished. This must be called while
serve_forever() is running in another thread, or it will
deadlock.
"""
self.__serving = False
if not self.__is_shut_down.wait(2):
raise RuntimeError(
"Failed to shutdown the live test server in 2 seconds. The "
"server might be stuck or generating a slow response.")
def handle_request(self):
"""Handle one request, possibly blocking.
"""
fd_sets = select.select([self], [], [], None)
if not fd_sets[0]:
return
self._handle_request_noblock()
def _handle_request_noblock(self):
"""
Handle one request, without blocking.
I assume that select.select has returned that the socket is
readable before this function was called, so there should be
no risk of blocking in get_request().
"""
try:
request, client_address = self.get_request()
except socket.error:
return
if self.verify_request(request, client_address):
try:
self.process_request(request, client_address)
except Exception:
self.handle_error(request, client_address)
self.close_request(request)
class _MediaFilesHandler(StaticFilesHandler):
"""
Handler for serving the media files. This is a private class that is
@@ -1071,7 +983,7 @@ class LiveServerThread(threading.Thread):
# one that is free to use for the WSGI server.
for index, port in enumerate(self.possible_ports):
try:
self.httpd = StoppableWSGIServer(
self.httpd = WSGIServer(
(self.host, port), QuietWSGIRequestHandler)
except WSGIServerException as e:
if (index + 1 < len(self.possible_ports) and
@@ -1128,7 +1040,7 @@ class LiveServerTestCase(TransactionTestCase):
for conn in connections.all():
# If using in-memory sqlite databases, pass the connections to
# the server thread.
if (conn.settings_dict['ENGINE'].rsplit('.', 1)[-1] in ('sqlite3', 'spatialite')
if (conn.vendor == 'sqlite'
and conn.settings_dict['NAME'] == ':memory:'):
# Explicitly enable thread-shareability for this connection
conn.allow_thread_sharing = True
@@ -1180,7 +1092,7 @@ class LiveServerTestCase(TransactionTestCase):
# Restore sqlite connections' non-sharability
for conn in connections.all():
if (conn.settings_dict['ENGINE'].rsplit('.', 1)[-1] in ('sqlite3', 'spatialite')
if (conn.vendor == 'sqlite'
and conn.settings_dict['NAME'] == ':memory:'):
conn.allow_thread_sharing = False

View File

@@ -228,7 +228,7 @@ class override_settings(object):
settings._wrapped = override
for key, new_value in self.options.items():
setting_changed.send(sender=settings._wrapped.__class__,
setting=key, value=new_value)
setting=key, value=new_value, enter=True)
def disable(self):
settings._wrapped = self.wrapped
@@ -236,7 +236,7 @@ class override_settings(object):
for key in self.options:
new_value = getattr(settings, key, None)
setting_changed.send(sender=settings._wrapped.__class__,
setting=key, value=new_value)
setting=key, value=new_value, enter=False)
def compare_xml(want, got):