Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python 3 fixes for other submodules, some pep8 #67

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

Version 1.9.0 (Dec 21, 2015)
-------------

* Added support for Django 1.9 in the db package

Version 1.8.0 (Jul 12, 2015)
-------------

Expand Down
26 changes: 14 additions & 12 deletions djangotoolbox/db/base.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
from django.utils.six.moves import cPickle as pickle
import datetime

import django
from django.conf import settings
from django.db.utils import DatabaseError
from django.utils import six
from django.utils import timezone
from django.utils.functional import Promise

from django.utils.six.moves import cPickle as pickle

from .creation import NonrelDatabaseCreation

import django

if django.VERSION < (1, 8):
from django.db.backends import (
Expand All @@ -21,9 +28,6 @@
from django.db.backends.base.introspection import BaseDatabaseIntrospection
from django.db.backends.base.operations import BaseDatabaseOperations

from django.db.utils import DatabaseError
from django.utils import timezone
from django.utils.functional import Promise

if django.VERSION < (1, 5):
from django.utils.encoding import (smart_unicode as smart_text,
Expand All @@ -39,8 +43,6 @@
else:
from django.utils.safestring import SafeBytes, SafeText, EscapeBytes, EscapeText

from .creation import NonrelDatabaseCreation


class NonrelDatabaseFeatures(BaseDatabaseFeatures):
# Most NoSQL databases don't have true transaction support.
Expand Down Expand Up @@ -459,7 +461,7 @@ def _value_for_db_collection(self, value, field, field_kind, db_type,
value = (
(key, self._value_for_db(subvalue, subfield,
subkind, db_subtype, lookup))
for key, subvalue in value.iteritems())
for key, subvalue in six.iteritems(value))

# Return just a dict, a once-flattened list;
if db_type == 'dict':
Expand Down Expand Up @@ -514,9 +516,9 @@ def _value_from_db_collection(self, value, field, field_kind, db_type):
# Generator yielding pairs with deconverted values, the
# "list" db_type stores keys and values interleaved.
if db_type == 'list':
value = zip(value[::2], value[1::2])
value = list(zip(value[::2], value[1::2]))
else:
value = value.iteritems()
value = iter(six.iteritems(value))

# DictField needs to hold a dict.
return dict(
Expand Down Expand Up @@ -575,7 +577,7 @@ def _value_for_db_model(self, value, field, field_kind, db_type, lookup):
value = (
(subfield.column, self._value_for_db(
subvalue, lookup=lookup, *self._convert_as(subfield, lookup)))
for subfield, subvalue in value.iteritems())
for subfield, subvalue in six.iteritems(value))

# Cast to a dict, interleave columns with values on a list,
# serialize, or return a generator.
Expand Down Expand Up @@ -603,7 +605,7 @@ def _value_from_db_model(self, value, field, field_kind, db_type):

# Separate keys from values and create a dict or unpickle one.
if db_type == 'list':
value = dict(zip(value[::2], value[1::2]))
value = dict(list(zip(value[::2], value[1::2])))
elif db_type == 'bytes' or db_type == 'string':
value = pickle.loads(value)

Expand Down
37 changes: 28 additions & 9 deletions djangotoolbox/db/basecompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

import django
from django.conf import settings
from django.db import connections
from django.db.models.fields import NOT_PROVIDED
from django.db.models.query import QuerySet
from django.db.models.sql.compiler import SQLCompiler
from django.db.models.sql.constants import MULTI, SINGLE
from django.db.models.sql.where import AND, OR
from django.db.utils import DatabaseError, IntegrityError
from django.utils.tree import Node
from django.db import connections


try:
from django.db.models.sql.where import SubqueryConstraint
Expand Down Expand Up @@ -177,7 +178,7 @@ def add_filters(self, filters):
if filters.negated:
self._negated = not self._negated

# ----------------------------------------------
# ----------------------------------------------s
# Internal API for reuse by subclasses
# ----------------------------------------------

Expand Down Expand Up @@ -233,7 +234,7 @@ def _decode_child(self, child):
raise DatabaseError("This database doesn't support filtering "
"on non-primary key ForeignKey fields.")

field = (f for f in opts.fields if f.column == column).next()
field = next(f for f in opts.fields if f.column == column)
assert field.rel is not None

value = self._normalize_lookup_value(
Expand Down Expand Up @@ -421,7 +422,10 @@ def execute_sql(self, result_type=MULTI):
"""
self.pre_sql_setup()

aggregates = self.query.aggregate_select.values()
if django.VERSION < (1, 8):
aggregates = list(self.query.aggregate_select.values())
else:
aggregates = list(self.query.annotation_select.values())

# Simulate a count().
if aggregates:
Expand All @@ -441,8 +445,18 @@ def execute_sql(self, result_type=MULTI):
raise DatabaseError("This database backend only supports "
"count() queries on the primary key.")
else:
try:
from django.db.models.expressions import Star

try:
is_star = isinstance(aggregate.input_field, Star) # Django 1.8.5+
except AttributeError:
is_star = isinstance(aggregate.get_source_expressions()[0], Star) # Django 1.9
except ImportError:
is_star = aggregate.input_field.value == '*'

# Fair warning: the latter part of this or statement hasn't been tested
if aggregate.input_field.value != '*' and aggregate.input_field != (opts.db_table, opts.pk.column):
if not is_star and aggregate.input_field != (opts.db_table, opts.pk.column):
raise DatabaseError("This database backend only supports "
"count() queries on the primary key.")

Expand Down Expand Up @@ -474,6 +488,9 @@ def _make_result(self, entity, fields):
# This is the default behavior of ``query.convert_values``
# until django 1.8, where multiple converters are a thing.
value = self.connection.ops.convert_values(value, field)

if hasattr(field, "from_db_value"):
value = field.from_db_value(value, None, self.connection, None)
if value is None and not field.null:
raise IntegrityError("Non-nullable field %s can't be None!" %
field.name)
Expand All @@ -492,8 +509,10 @@ def check_query(self):
"""
if hasattr(self.query, 'is_empty') and self.query.is_empty():
raise EmptyResultSet()
if (len([a for a in self.query.alias_map if self.query.alias_refcount[a]]) > 1
or self.query.distinct or self.query.extra or self.query.having):
if (len([a for a in self.query.alias_map if self.query.alias_refcount[a]]) > 1 or
self.query.distinct or self.query.extra): # or self.having -- Not quite working.
# having is no longer part of the query as of 1.9; It moved to the compiler
# https://github.com/django/django/commit/afe0bb7b13bb8dc4370f32225238012c873b0ee3
raise DatabaseError("This query is not supported by the database.")

def get_count(self, check_exists=False):
Expand Down Expand Up @@ -547,9 +566,9 @@ def get_fields(self):
only_load = self.deferred_to_columns()
if only_load:
db_table = self.query.model._meta.db_table
only_load = dict((k, v) for k, v in only_load.items()
only_load = dict((k, v) for k, v in list(only_load.items())
if v or k == db_table)
if len(only_load.keys()) > 1:
if len(list(only_load.keys())) > 1:
raise DatabaseError("Multi-table inheritance is not "
"supported by non-relational DBs %s." %
repr(only_load))
Expand Down
15 changes: 7 additions & 8 deletions djangotoolbox/fields.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# All fields except for BlobField written by Jonas Haag <[email protected]>

from django.core.exceptions import ValidationError
from django.utils.importlib import import_module
from django.db import models
from django.db.models.fields.related import add_lazy_relation
from django.db.models.fields.subclassing import Creator
from django.db.utils import IntegrityError
from django.db.models.fields.related import add_lazy_relation
from django.utils import six
from django.utils.importlib import import_module


__all__ = ('RawField', 'ListField', 'SetField', 'DictField',
Expand Down Expand Up @@ -85,7 +86,7 @@ def contribute_to_class(self, cls, name):
if item_metaclass and issubclass(item_metaclass, models.SubfieldBase):
setattr(cls, self.name, Creator(self))

if isinstance(self.item_field, models.ForeignKey) and isinstance(self.item_field.rel.to, basestring):
if isinstance(self.item_field, models.ForeignKey) and isinstance(self.item_field.rel.to, six.string_types):
"""
If rel.to is a string because the actual class is not yet defined, look up the
actual class later. Refer to django.models.fields.related.RelatedField.contribute_to_class.
Expand Down Expand Up @@ -225,14 +226,15 @@ def get_internal_type(self):

def _map(self, function, iterable, *args, **kwargs):
return self._type((key, function(value, *args, **kwargs))
for key, value in iterable.iteritems())
for key, value in six.iteritems(iterable))

def validate(self, values, model_instance):
if not isinstance(values, dict):
raise ValidationError("Value is of type %r. Should be a dict." %
type(values))


@six.add_metaclass(models.SubfieldBase)
class EmbeddedModelField(models.Field):
"""
Field that allows you to embed a model instance.
Expand All @@ -245,7 +247,6 @@ class EmbeddedModelField(models.Field):
the embedded instance (not just pre_save, get_db_prep_* and
to_python).
"""
__metaclass__ = models.SubfieldBase

def __init__(self, embedded_model=None, *args, **kwargs):
self.embedded_model = embedded_model
Expand All @@ -255,7 +256,6 @@ def __init__(self, embedded_model=None, *args, **kwargs):
def get_internal_type(self):
return 'EmbeddedModelField'


def _set_model(self, model):
"""
Resolves embedded model class once the field knows the model it
Expand All @@ -271,7 +271,7 @@ def _set_model(self, model):
our "model" attribute in its contribute_to_class method).
"""
self._model = model
if model is not None and isinstance(self.embedded_model, basestring):
if model is not None and isinstance(self.embedded_model, six.string_types):

def _resolve_lookup(self_, resolved_model, model):
self.embedded_model = resolved_model
Expand All @@ -280,7 +280,6 @@ def _resolve_lookup(self_, resolved_model, model):

model = property(lambda self: self._model, _set_model)


def stored_model(self, column_values):
"""
Returns the fixed embedded_model this field was initialized
Expand Down
8 changes: 4 additions & 4 deletions djangotoolbox/http.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import json

from django.conf import settings
from django.core.serializers.json import DjangoJSONEncoder
from django.http import HttpResponse
from django.utils import simplejson
from django.utils.encoding import force_unicode
from django.utils.functional import Promise

Expand All @@ -18,9 +19,8 @@ class JSONResponse(HttpResponse):

def __init__(self, pyobj, **kwargs):
super(JSONResponse, self).__init__(
simplejson.dumps(pyobj, cls=LazyEncoder),
content_type='application/json; charset=%s' %
settings.DEFAULT_CHARSET,
json.dumps(pyobj, cls=LazyEncoder),
content_type='application/json; charset=%s' % settings.DEFAULT_CHARSET,
**kwargs)


Expand Down
5 changes: 3 additions & 2 deletions djangotoolbox/test.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from unittest import TextTestResult, TextTestRunner

from django.test import TestCase
from django.utils.unittest import TextTestResult, TextTestRunner

try:
from django.test.runner import DiscoverRunner as TestRunner
except ImportError:
from django.test.simple import DjangoTestSuiteRunner as TestRunner

from .utils import object_list_to_table
from .utils import object_list_to_table, equal_lists

import re

Expand Down
Loading