Merge pull request #2446 from tomchristie/django-18-alpha

Support 1.8-alpha.
This commit is contained in:
Tom Christie 2015-01-23 13:13:05 +00:00
commit d1fe3f6548
10 changed files with 38 additions and 84 deletions

View File

@ -33,10 +33,6 @@ env:
matrix: matrix:
fast_finish: true fast_finish: true
allow_failures: allow_failures:
- env: TOX_ENV=py34-django18alpha
- env: TOX_ENV=py33-django18alpha
- env: TOX_ENV=py32-django18alpha
- env: TOX_ENV=py27-django18alpha
- env: TOX_ENV=py34-djangomaster - env: TOX_ENV=py34-djangomaster
- env: TOX_ENV=py33-djangomaster - env: TOX_ENV=py33-djangomaster
- env: TOX_ENV=py32-djangomaster - env: TOX_ENV=py32-djangomaster

1
env/pip-selfcheck.json vendored Normal file
View File

@ -0,0 +1 @@
{"last_check":"2015-01-23T11:37:11Z","pypi_version":"6.0.6"}

View File

@ -298,7 +298,7 @@ class FileUploadParser(BaseParser):
if 'filename*' in filename_parm: if 'filename*' in filename_parm:
return self.get_encoded_filename(filename_parm) return self.get_encoded_filename(filename_parm)
return force_text(filename_parm['filename']) return force_text(filename_parm['filename'])
except (AttributeError, KeyError): except (AttributeError, KeyError, ValueError):
pass pass
def get_encoded_filename(self, filename_parm): def get_encoded_filename(self, filename_parm):

View File

@ -81,10 +81,13 @@ class Response(SimpleTemplateResponse):
def __getstate__(self): def __getstate__(self):
""" """
Remove attributes from the response that shouldn't be cached Remove attributes from the response that shouldn't be cached.
""" """
state = super(Response, self).__getstate__() state = super(Response, self).__getstate__()
for key in ('accepted_renderer', 'renderer_context', 'data'): for key in (
'accepted_renderer', 'renderer_context', 'resolver_match',
'client', 'request', 'wsgi_request', '_closable_objects'
):
if key in state: if key in state:
del state[key] del state[key]
return state return state

View File

@ -121,12 +121,17 @@ def _get_reverse_relationships(opts):
""" """
Returns an `OrderedDict` of field names to `RelationInfo`. Returns an `OrderedDict` of field names to `RelationInfo`.
""" """
# Note that we have a hack here to handle internal API differences for
# this internal API across Django 1.7 -> Django 1.8.
# See: https://code.djangoproject.com/ticket/24208
reverse_relations = OrderedDict() reverse_relations = OrderedDict()
for relation in opts.get_all_related_objects(): for relation in opts.get_all_related_objects():
accessor_name = relation.get_accessor_name() accessor_name = relation.get_accessor_name()
related = getattr(relation, 'related_model', relation.model)
reverse_relations[accessor_name] = RelationInfo( reverse_relations[accessor_name] = RelationInfo(
model_field=None, model_field=None,
related=relation.model, related=related,
to_many=relation.field.rel.multiple, to_many=relation.field.rel.multiple,
has_through_model=False has_through_model=False
) )
@ -134,9 +139,10 @@ def _get_reverse_relationships(opts):
# Deal with reverse many-to-many relationships. # Deal with reverse many-to-many relationships.
for relation in opts.get_all_related_many_to_many_objects(): for relation in opts.get_all_related_many_to_many_objects():
accessor_name = relation.get_accessor_name() accessor_name = relation.get_accessor_name()
related = getattr(relation, 'related_model', relation.model)
reverse_relations[accessor_name] = RelationInfo( reverse_relations[accessor_name] = RelationInfo(
model_field=None, model_field=None,
related=relation.model, related=related,
to_many=True, to_many=True,
has_through_model=( has_through_model=(
(getattr(relation.field.rel, 'through', None) is not None) (getattr(relation.field.rel, 'through', None) is not None)

View File

@ -467,6 +467,7 @@ class DjangoFilterOrderingTests(TestCase):
for d in data: for d in data:
DjangoFilterOrderingModel.objects.create(**d) DjangoFilterOrderingModel.objects.create(**d)
@unittest.skipUnless(django_filters, 'django-filter not installed')
def test_default_ordering(self): def test_default_ordering(self):
class DjangoFilterOrderingView(generics.ListAPIView): class DjangoFilterOrderingView(generics.ListAPIView):
serializer_class = DjangoFilterOrderingSerializer serializer_class = DjangoFilterOrderingSerializer

View File

@ -56,7 +56,13 @@ class TemplateHTMLRendererTests(TestCase):
return Template("example: {{ object }}") return Template("example: {{ object }}")
raise TemplateDoesNotExist(template_name) raise TemplateDoesNotExist(template_name)
def select_template(template_name_list, dirs=None, using=None):
if template_name_list == ['example.html']:
return Template("example: {{ object }}")
raise TemplateDoesNotExist(template_name_list[0])
django.template.loader.get_template = get_template django.template.loader.get_template = get_template
django.template.loader.select_template = select_template
def tearDown(self): def tearDown(self):
""" """

View File

@ -161,7 +161,9 @@ class TestFileUploadParser(TestCase):
self.__replace_content_disposition('inline; filename=fallback.txt; filename*=utf-8--ÀĥƦ.txt') self.__replace_content_disposition('inline; filename=fallback.txt; filename*=utf-8--ÀĥƦ.txt')
filename = parser.get_filename(self.stream, None, self.parser_context) filename = parser.get_filename(self.stream, None, self.parser_context)
self.assertEqual(filename, 'fallback.txt') # Malformed. Either None or 'fallback.txt' will be acceptable.
# See also https://code.djangoproject.com/ticket/24209
self.assertIn(filename, ('fallback.txt', None))
def __replace_content_disposition(self, disposition): def __replace_content_disposition(self, disposition):
self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = disposition self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = disposition

View File

@ -22,7 +22,6 @@ from rest_framework.test import APIRequestFactory
from collections import MutableMapping from collections import MutableMapping
import datetime import datetime
import json import json
import pickle
import re import re
@ -618,84 +617,24 @@ class CacheRenderTest(TestCase):
urls = 'tests.test_renderers' urls = 'tests.test_renderers'
cache_key = 'just_a_cache_key'
@classmethod
def _get_pickling_errors(cls, obj, seen=None):
""" Return any errors that would be raised if `obj' is pickled
Courtesy of koffie @ http://stackoverflow.com/a/7218986/109897
"""
if seen is None:
seen = []
try:
state = obj.__getstate__()
except AttributeError:
return
if state is None:
return
if isinstance(state, tuple):
if not isinstance(state[0], dict):
state = state[1]
else:
state = state[0].update(state[1])
result = {}
for i in state:
try:
pickle.dumps(state[i], protocol=2)
except pickle.PicklingError:
if not state[i] in seen:
seen.append(state[i])
result[i] = cls._get_pickling_errors(state[i], seen)
return result
def http_resp(self, http_method, url):
"""
Simple wrapper for Client http requests
Removes the `client' and `request' attributes from as they are
added by django.test.client.Client and not part of caching
responses outside of tests.
"""
method = getattr(self.client, http_method)
resp = method(url)
resp._closable_objects = []
del resp.client, resp.request
try:
del resp.wsgi_request
except AttributeError:
pass
return resp
def test_obj_pickling(self):
"""
Test that responses are properly pickled
"""
resp = self.http_resp('get', '/cache')
# Make sure that no pickling errors occurred
self.assertEqual(self._get_pickling_errors(resp), {})
# Unfortunately LocMem backend doesn't raise PickleErrors but returns
# None instead.
cache.set(self.cache_key, resp)
self.assertTrue(cache.get(self.cache_key) is not None)
def test_head_caching(self): def test_head_caching(self):
""" """
Test caching of HEAD requests Test caching of HEAD requests
""" """
resp = self.http_resp('head', '/cache') response = self.client.head('/cache')
cache.set(self.cache_key, resp) cache.set('key', response)
cached_response = cache.get('key')
cached_resp = cache.get(self.cache_key) assert isinstance(cached_response, Response)
self.assertIsInstance(cached_resp, Response) assert cached_response.content == response.content
assert cached_response.status_code == response.status_code
def test_get_caching(self): def test_get_caching(self):
""" """
Test caching of GET requests Test caching of GET requests
""" """
resp = self.http_resp('get', '/cache') response = self.client.get('/cache')
cache.set(self.cache_key, resp) cache.set('key', response)
cached_response = cache.get('key')
cached_resp = cache.get(self.cache_key) assert isinstance(cached_response, Response)
self.assertIsInstance(cached_resp, Response) assert cached_response.content == response.content
self.assertEqual(cached_resp.content, resp.content) assert cached_response.status_code == response.status_code

View File

@ -22,7 +22,7 @@ deps =
{py26,py27}-django{14,15}: django-oauth2-provider==0.2.3 {py26,py27}-django{14,15}: django-oauth2-provider==0.2.3
{py26,py27}-django16: django-oauth2-provider==0.2.4 {py26,py27}-django16: django-oauth2-provider==0.2.4
pytest-django==2.8.0 pytest-django==2.8.0
django-filter==0.7 {py26,py27,py32,py33,py34}-django{14,15,16,17}: django-filter==0.7
defusedxml==0.3 defusedxml==0.3
markdown>=2.1.0 markdown>=2.1.0
PyYAML>=3.10 PyYAML>=3.10