Skip to content

Commit

Permalink
Support Django 1.10
Browse files Browse the repository at this point in the history
Don't use `SubfieldBase` for `ChoiceField` if cannot be imported (deprecated in Django 1.8, removed in Django 1.10)
  • Loading branch information
Mateusz Kurek committed Oct 20, 2016
1 parent 3f7df6d commit 5c519ca
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 119 deletions.
9 changes: 9 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,15 @@ The easiest way would be to run::
Change Log
----------

0.11.0
~~~~~~

* Drop compatibility for Django < 1.4 and Python 2.6

* Add support for Django 1.9 and 1.10 (use ``from_db_value`` instead of ``SubfieldBase``)

* Add support for Python 3.5

0.10.0
~~~~~~

Expand Down
5 changes: 2 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

setup (
name = 'dj.choices',
version = '0.10.0',
version = '0.11.0',
author = '\xc5\x81ukasz Langa',
author_email = '[email protected]',
description = "An enum implementation for Django forms and models.",
Expand All @@ -57,12 +57,11 @@
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Software Development :: Libraries :: Python Modules',
Expand Down
77 changes: 37 additions & 40 deletions src/dj/_choicestestproject/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,53 +26,21 @@
from __future__ import print_function
from __future__ import unicode_literals

from unittest.loader import defaultTestLoader

from django.conf import settings
from django.test import TestCase
from django.test.simple import DjangoTestSuiteRunner
from django.utils.importlib import import_module
try:
from unittest.loader import defaultTestLoader
except ImportError:
# Python 2.6
from unittest2.loader import defaultTestLoader


class OldStyleDiscoveryDjangoTestSuiteRunner(DjangoTestSuiteRunner):
"""A test suite runner that uses unittest2 test discovery.
Courtesy of @carljm."""

def build_suite(self, test_labels, extra_tests=None, **kwargs):
suite = None
discovery_root = settings.TEST_DISCOVERY_ROOT

if test_labels:
suite = defaultTestLoader.loadTestsFromNames(test_labels)
# if single named module has no tests, do discovery within it
if not suite.countTestCases() and len(test_labels) == 1:
suite = None
discovery_root = import_module(test_labels[0]).__path__[0]

if suite is None:
suite = defaultTestLoader.discover(
discovery_root,
top_level_dir=settings.BASE_PATH,
)

if extra_tests:
for test in extra_tests:
suite.addTest(test)

from django.test.simple import reorder_suite # Django 1.5 and lower
return reorder_suite(suite, (TestCase,))

try:
# Added in Django 1.6
from django.test.runner import DiscoverRunner
class DiscoveryDjangoTestSuiteRunner(DiscoverRunner):
"""Unfortunately the new DiscoverRunner doesn't handle custom top level
correctly."""
def __init__(self, pattern=None, top_level=None,
verbosity=1, interactive=True, failfast=False,
**kwargs):
def __init__(
self, pattern=None, top_level=None, verbosity=1, interactive=True,
failfast=False, **kwargs
):
self.test_label_default = settings.TEST_DISCOVERY_ROOT
if not top_level:
top_level = self.test_label_default
Expand All @@ -89,4 +57,33 @@ def build_suite(self, test_labels=None, extra_tests=None, **kwargs):
)

except ImportError:
DiscoveryDjangoTestSuiteRunner = OldStyleDiscoveryDjangoTestSuiteRunner
# Django < 1.6 compatibility
from django.utils.importlib import import_module
from django.test.simple import DjangoTestSuiteRunner
class DiscoveryDjangoTestSuiteRunner(DjangoTestSuiteRunner):
"""A test suite runner that uses unittest2 test discovery.
Courtesy of @carljm."""

def build_suite(self, test_labels, extra_tests=None, **kwargs):
suite = None
discovery_root = settings.TEST_DISCOVERY_ROOT

if test_labels:
suite = defaultTestLoader.loadTestsFromNames(test_labels)
# if single named module has no tests, do discovery within it
if not suite.countTestCases() and len(test_labels) == 1:
suite = None
discovery_root = import_module(test_labels[0]).__path__[0]

if suite is None:
suite = defaultTestLoader.discover(
discovery_root,
top_level_dir=settings.BASE_PATH,
)

if extra_tests:
for test in extra_tests:
suite.addTest(test)

from django.test.simple import reorder_suite # Django 1.5 and lower
return reorder_suite(suite, (TestCase,))
4 changes: 3 additions & 1 deletion src/dj/_choicestestproject/app/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-

# Copyright (C) 2012-2013 by Łukasz Langa
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
Expand Down Expand Up @@ -44,8 +44,10 @@ class Meta:
widgets = {
'sport': forms.HiddenInput(),
}
exclude = ()


class RegularIntegersForm(forms.ModelForm, HasBoundValue):
class Meta:
model = RegularIntegers
exclude = ()
5 changes: 0 additions & 5 deletions src/dj/_choicestestproject/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,3 @@
BASE_PATH = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
TEST_DISCOVERY_ROOT = os.path.realpath(os.path.dirname(dj.choices.__file__))
TEST_RUNNER = "dj._choicestestproject.DiscoveryDjangoTestSuiteRunner"

import django
if django.VERSION[:2] < (1, 4):
del LOGGING['filters']['require_debug_false']
del LOGGING['handlers']['mail_admins']['filters']
18 changes: 14 additions & 4 deletions src/dj/choices/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,15 @@

import six

try:
# Removed in Django 1.10 (replaced by `from_db_value` method)
from django.db.models import SubfieldBase
except ImportError:
class SubfieldBase(type):
pass

class ChoiceField(six.with_metaclass(models.SubfieldBase, IntegerField)):

class ChoiceField(six.with_metaclass(SubfieldBase, IntegerField)):
description = _("Integer")

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -67,9 +74,6 @@ def __init__(self, *args, **kwargs):
del kwargs[arg]
super(ChoiceField, self).__init__(*args, **kwargs)

def get_internal_type(self):
return "IntegerField"

def to_python(self, value):
value = super(ChoiceField, self).to_python(self.get_prep_value(value))
if value is None:
Expand All @@ -81,6 +85,12 @@ def to_python(self, value):
self.error_messages['invalid_choice'] % {'value': value}
)

def from_db_value(self, value, expression, connection, context):
# Added in Django 1.8. Replaced SubfieldBase
if value is None:
return value
return self.choice_class.from_id(value)

def from_python(self, value):
return self.get_prep_value(self.to_python(value))

Expand Down
78 changes: 12 additions & 66 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,73 +1,19 @@
[tox]
envlist = py26-django13,py26-django14,py26-django15,py26-django16,py27-django13,py27-django14,py27-django15,py27-django16,py27-django17,py34-django15,py34-django16,py34-django17
envlist =
{py27,py34,py35}-django{18,19,110},
{py27,py34}-django{16,17},
{py27}-django{14,15},

[testenv]
# deps=pytest
commands =
commands =
{envbindir}/django-admin.py test
setenv =
DJANGO_SETTINGS_MODULE=dj._choicestestproject.settings

[testenv:py26-django13]
basepython = python2.6
deps =
Django==1.3.7
unittest2

[testenv:py26-django14]
basepython = python2.6
deps =
Django==1.4.15
unittest2

[testenv:py26-django15]
basepython = python2.6
deps =
Django==1.5.10
unittest2

[testenv:py26-django16]
basepython = python2.6
deps =
Django==1.6.7
unittest2

[testenv:py27-django13]
basepython = python2.7
deps =
Django==1.3.7

[testenv:py27-django14]
basepython = python2.7
deps =
Django==1.4.15

[testenv:py27-django15]
basepython = python2.7
deps =
Django==1.5.10

[testenv:py27-django16]
basepython = python2.7
deps =
Django==1.6.7

[testenv:py27-django17]
basepython = python2.7
deps =
Django==1.7

[testenv:py34-django15]
basepython = python3.4
deps =
Django==1.5.10

[testenv:py34-django16]
basepython = python3.4
deps =
Django==1.6.7

[testenv:py34-django17]
basepython = python3.4
deps =
Django==1.7
django14: Django==1.4.22
django15: Django==1.5.12
django16: Django==1.6.11
django17: Django==1.7.11
django18: Django==1.8.15
django19: Django==1.9.10
django110: Django==1.10.2

0 comments on commit 5c519ca

Please sign in to comment.