made compatable with python 2.5

This commit is contained in:
Laine 2012-08-02 15:30:21 -07:00
parent 91aa90ad4a
commit ed74477150
8 changed files with 94 additions and 40 deletions

View File

@ -877,6 +877,10 @@ class BaseDocument(object):
if not is_list and '_cls' in value: if not is_list and '_cls' in value:
cls = get_document(value['_cls']) cls = get_document(value['_cls'])
# Make keys str instead of unicode
for key,val in value.items():
del value[key]
value[str(key)] = val
value = cls(**value) value = cls(**value)
value._dynamic = True value._dynamic = True
value._changed_fields = [] value._changed_fields = []
@ -998,6 +1002,10 @@ class BaseDocument(object):
raise InvalidDocumentError(""" raise InvalidDocumentError("""
Invalid data to create a `%s` instance.\n%s""".strip() % (cls._class_name, errors)) Invalid data to create a `%s` instance.\n%s""".strip() % (cls._class_name, errors))
# Make all keys str instead of unicode
for key,val in data.items():
del data[key]
data[str(key)] = val
obj = cls(**data) obj = cls(**data)
obj._changed_fields = changed_fields obj._changed_fields = changed_fields

View File

@ -1267,7 +1267,7 @@ class SequenceField(IntField):
""" """
Generate and Increment the counter Generate and Increment the counter
""" """
sequence_id = "{0}.{1}".format(self.owner_document._get_collection_name(), sequence_id = "%s.%s"%(self.owner_document._get_collection_name(),
self.name) self.name)
collection = get_db(alias = self.db_alias )[self.collection_name] collection = get_db(alias = self.db_alias )[self.collection_name]
counter = collection.find_and_modify(query={"_id": sequence_id}, counter = collection.find_and_modify(query={"_id": sequence_id},

View File

@ -4,6 +4,7 @@ import copy
import itertools import itertools
import operator import operator
import functools import functools
import sys
from functools import partial from functools import partial
import pymongo import pymongo
@ -14,6 +15,18 @@ from mongoengine import signals
__all__ = ['queryset_manager', 'Q', 'InvalidQueryError', __all__ = ['queryset_manager', 'Q', 'InvalidQueryError',
'DO_NOTHING', 'NULLIFY', 'CASCADE', 'DENY', 'PULL'] 'DO_NOTHING', 'NULLIFY', 'CASCADE', 'DENY', 'PULL']
if sys.version_info < (2,6,0):
def product(*args, **kwds):
pools = map(tuple, args) * kwds.get('repeat', 1)
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)
else:
from itertools import product
from functools import reduce
# The maximum number of items to display in a QuerySet.__repr__ # The maximum number of items to display in a QuerySet.__repr__
REPR_OUTPUT_SIZE = 20 REPR_OUTPUT_SIZE = 20
@ -120,13 +133,13 @@ class QueryTreeTransformerVisitor(QNodeVisitor):
# the necessary parts. Then for each $or part, create a new query # the necessary parts. Then for each $or part, create a new query
# that ANDs the necessary part with the $or part. # that ANDs the necessary part with the $or part.
clauses = [] clauses = []
for or_group in itertools.product(*or_groups): for or_group in product(*or_groups):
q_object = functools.reduce(lambda a, b: a & b, and_parts, Q()) q_object = reduce(lambda a, b: a & b, and_parts, Q())
q_object = functools.reduce(lambda a, b: a & b, or_group, q_object) q_object = reduce(lambda a, b: a & b, or_group, q_object)
clauses.append(q_object) clauses.append(q_object)
# Finally, $or the generated clauses in to one query. Each of the # Finally, $or the generated clauses in to one query. Each of the
# clauses is sufficient for the query to succeed. # clauses is sufficient for the query to succeed.
return functools.reduce(lambda a, b: a | b, clauses, Q()) return reduce(lambda a, b: a | b, clauses, Q())
if combination.operation == combination.OR: if combination.operation == combination.OR:
children = [] children = []

View File

@ -1,3 +1,4 @@
from __future__ import with_statement
import unittest import unittest
from mongoengine import * from mongoengine import *

View File

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*- from __future__ import with_statement
import unittest import unittest
from nose.plugins.skip import SkipTest from nose.plugins.skip import SkipTest
from mongoengine.python3_support import PY3 from mongoengine.python3_support import PY3
@ -16,7 +16,7 @@ try:
from django.contrib.sessions.tests import SessionTestsMixin from django.contrib.sessions.tests import SessionTestsMixin
from mongoengine.django.sessions import SessionStore, MongoSession from mongoengine.django.sessions import SessionStore, MongoSession
except Exception as err: except Exception, err:
if PY3: if PY3:
SessionTestsMixin = type #dummy value so no error SessionTestsMixin = type #dummy value so no error
SessionStore = None #dummy value so no error SessionStore = None #dummy value so no error

View File

@ -1,10 +1,13 @@
from __future__ import with_statement
import os import os
import pickle import pickle
import pymongo import pymongo
import bson import bson
import unittest import unittest
import warnings import warnings
import sys
from nose.plugins.skip import SkipTest
from datetime import datetime from datetime import datetime
from tests.fixtures import Base, Mixin, PickleEmbedded, PickleTest from tests.fixtures import Base, Mixin, PickleEmbedded, PickleTest
@ -38,7 +41,14 @@ class DocumentTest(unittest.TestCase):
"""Add FutureWarning for future allow_inhertiance default change. """Add FutureWarning for future allow_inhertiance default change.
""" """
with warnings.catch_warnings(record=True) as errors: self.warning_list = []
showwarning_default = warnings.showwarning
def append_to_warning_list(message,category, *args):
self.warning_list.append({"message":message, "category":category})
# add warnings to self.warning_list instead of stderr
warnings.showwarning = append_to_warning_list
class SimpleBase(Document): class SimpleBase(Document):
a = IntField() a = IntField()
@ -46,11 +56,14 @@ class DocumentTest(unittest.TestCase):
class InheritedClass(SimpleBase): class InheritedClass(SimpleBase):
b = IntField() b = IntField()
# restore default handling of warnings
warnings.showwarning = showwarning_default
InheritedClass() InheritedClass()
self.assertEqual(len(errors), 1) self.assertEqual(len(self.warning_list), 1)
warning = errors[0] warning = self.warning_list[0]
self.assertEqual(FutureWarning, warning.category) self.assertEqual(FutureWarning, warning["category"])
self.assertTrue("InheritedClass" in str(warning.message)) self.assertTrue("InheritedClass" in str(warning["message"]))
def test_drop_collection(self): def test_drop_collection(self):
"""Ensure that the collection may be dropped from the database. """Ensure that the collection may be dropped from the database.
@ -131,8 +144,15 @@ class DocumentTest(unittest.TestCase):
meta = {'collection': 'wibble'} meta = {'collection': 'wibble'}
self.assertEqual('wibble', InheritedAbstractNamingTest._get_collection_name()) self.assertEqual('wibble', InheritedAbstractNamingTest._get_collection_name())
with warnings.catch_warnings(record=True) as w: # set up for redirecting warnings
# Cause all warnings to always be triggered. self.warning_list = []
showwarning_default = warnings.showwarning
def append_to_warning_list(message, category, *args):
self.warning_list.append({'message':message, 'category':category})
# add warnings to self.warning_list instead of stderr
warnings.showwarning = append_to_warning_list
warnings.simplefilter("always") warnings.simplefilter("always")
class NonAbstractBase(Document): class NonAbstractBase(Document):
@ -141,7 +161,10 @@ class DocumentTest(unittest.TestCase):
class InheritedDocumentFailTest(NonAbstractBase): class InheritedDocumentFailTest(NonAbstractBase):
meta = {'collection': 'fail'} meta = {'collection': 'fail'}
self.assertTrue(issubclass(w[0].category, SyntaxWarning)) # restore default handling of warnings
warnings.showwarning = showwarning_default
self.assertTrue(issubclass(self.warning_list[0]["category"], SyntaxWarning))
self.assertEqual('non_abstract_base', InheritedDocumentFailTest._get_collection_name()) self.assertEqual('non_abstract_base', InheritedDocumentFailTest._get_collection_name())
# Mixin tests # Mixin tests
@ -539,21 +562,29 @@ class DocumentTest(unittest.TestCase):
def test_inherited_collections(self): def test_inherited_collections(self):
"""Ensure that subclassed documents don't override parents' collections. """Ensure that subclassed documents don't override parents' collections.
""" """
with warnings.catch_warnings(record=True) as w:
# Cause all warnings to always be triggered.
warnings.simplefilter("always")
class Drink(Document): class Drink(Document):
name = StringField() name = StringField()
class AlcoholicDrink(Drink):
meta = {'collection': 'booze'}
class Drinker(Document): class Drinker(Document):
drink = GenericReferenceField() drink = GenericReferenceField()
# Confirm we triggered a SyntaxWarning try:
assert issubclass(w[0].category, SyntaxWarning) warnings.simplefilter("error")
class AcloholicDrink(Drink):
meta = {'collection': 'booze'}
except SyntaxWarning, w:
warnings.simplefilter("ignore")
class AlcoholicDrink(Drink):
meta = {'collection': 'booze'}
else:
raise AssertionError("SyntaxWarning should be triggered")
warnings.resetwarnings()
Drink.drop_collection() Drink.drop_collection()
AlcoholicDrink.drop_collection() AlcoholicDrink.drop_collection()

View File

@ -1,3 +1,4 @@
from __future__ import with_statement
import datetime import datetime
import os import os
import unittest import unittest

View File

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*- from __future__ import with_statement
import unittest import unittest
from datetime import datetime, timedelta from datetime import datetime, timedelta
@ -499,7 +499,7 @@ class QuerySetTest(unittest.TestCase):
Blog.drop_collection() Blog.drop_collection()
# Recreates the collection # Recreates the collection
self.assertEqual(0, Blog.objects.count()) self.assertEqual(0, Blog.objects.count())
with query_counter() as q: with query_counter() as q: