From dd023edc0fd3f8dcf271f87043f9cbb593993a72 Mon Sep 17 00:00:00 2001 From: Laine Date: Thu, 2 Aug 2012 15:30:21 -0700 Subject: [PATCH] made compatable with python 2.5 --- mongoengine/base.py | 8 ++++++++ mongoengine/fields.py | 4 ++-- mongoengine/queryset.py | 21 +++++++++++++++++---- tests/test_dereference.py | 1 + tests/test_django.py | 4 ++-- tests/test_document.py | 31 ++++++++++++++++++++++--------- tests/test_fields.py | 1 + tests/test_queryset.py | 4 ++-- 8 files changed, 55 insertions(+), 19 deletions(-) diff --git a/mongoengine/base.py b/mongoengine/base.py index d4a7b324..811a45f2 100644 --- a/mongoengine/base.py +++ b/mongoengine/base.py @@ -877,6 +877,10 @@ class BaseDocument(object): if not is_list and '_cls' in value: 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._dynamic = True value._changed_fields = [] @@ -998,6 +1002,10 @@ class BaseDocument(object): raise InvalidDocumentError(""" 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._changed_fields = changed_fields diff --git a/mongoengine/fields.py b/mongoengine/fields.py index a2947c18..fc6e8a50 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -1267,8 +1267,8 @@ class SequenceField(IntField): """ Generate and Increment the counter """ - sequence_id = "{0}.{1}".format(self.owner_document._get_collection_name(), - self.name) + sequence_id = "%s.%s"%(self.owner_document._get_collection_name(), + self.name) collection = get_db(alias = self.db_alias )[self.collection_name] counter = collection.find_and_modify(query={"_id": sequence_id}, update={"$inc": {"next": 1}}, diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index 1067e32e..cef9f806 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -4,6 +4,7 @@ import copy import itertools import operator import functools +import sys from functools import partial import pymongo @@ -14,6 +15,18 @@ from mongoengine import signals __all__ = ['queryset_manager', 'Q', 'InvalidQueryError', '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__ REPR_OUTPUT_SIZE = 20 @@ -120,13 +133,13 @@ class QueryTreeTransformerVisitor(QNodeVisitor): # the necessary parts. Then for each $or part, create a new query # that ANDs the necessary part with the $or part. clauses = [] - for or_group in itertools.product(*or_groups): - q_object = functools.reduce(lambda a, b: a & b, and_parts, Q()) - q_object = functools.reduce(lambda a, b: a & b, or_group, q_object) + for or_group in product(*or_groups): + q_object = reduce(lambda a, b: a & b, and_parts, Q()) + q_object = reduce(lambda a, b: a & b, or_group, q_object) clauses.append(q_object) # Finally, $or the generated clauses in to one query. Each of the # 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: children = [] diff --git a/tests/test_dereference.py b/tests/test_dereference.py index 75daf6a8..cc2ffbaa 100644 --- a/tests/test_dereference.py +++ b/tests/test_dereference.py @@ -1,3 +1,4 @@ +from __future__ import with_statement import unittest from mongoengine import * diff --git a/tests/test_django.py b/tests/test_django.py index ed21f275..32a3fe14 100644 --- a/tests/test_django.py +++ b/tests/test_django.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +from __future__ import with_statement import unittest from nose.plugins.skip import SkipTest from mongoengine.python3_support import PY3 @@ -16,7 +16,7 @@ try: from django.contrib.sessions.tests import SessionTestsMixin from mongoengine.django.sessions import SessionStore, MongoSession -except Exception as err: +except Exception, err: if PY3: SessionTestsMixin = type #dummy value so no error SessionStore = None #dummy value so no error diff --git a/tests/test_document.py b/tests/test_document.py index 8eaaceef..8e6791be 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -1,10 +1,13 @@ +from __future__ import with_statement import os import pickle import pymongo import bson import unittest import warnings +import sys +from nose.plugins.skip import SkipTest from datetime import datetime from tests.fixtures import Base, Mixin, PickleEmbedded, PickleTest @@ -37,6 +40,8 @@ class DocumentTest(unittest.TestCase): def test_future_warning(self): """Add FutureWarning for future allow_inhertiance default change. """ + if (sys.version_info < (2,6,0)): + raise SkipTest('catch warnings as errors only available in 2.6+') with warnings.catch_warnings(record=True) as errors: @@ -131,18 +136,21 @@ class DocumentTest(unittest.TestCase): meta = {'collection': 'wibble'} self.assertEqual('wibble', InheritedAbstractNamingTest._get_collection_name()) - with warnings.catch_warnings(record=True) as w: - # Cause all warnings to always be triggered. - warnings.simplefilter("always") - class NonAbstractBase(Document): - pass + # catch_warnings only available in python 2.6+ + if sys.version_info > (2,6,0): + with warnings.catch_warnings(record=True) as w: + # Cause all warnings to always be triggered. + warnings.simplefilter("always") - class InheritedDocumentFailTest(NonAbstractBase): - meta = {'collection': 'fail'} + class NonAbstractBase(Document): + pass - self.assertTrue(issubclass(w[0].category, SyntaxWarning)) - self.assertEqual('non_abstract_base', InheritedDocumentFailTest._get_collection_name()) + class InheritedDocumentFailTest(NonAbstractBase): + meta = {'collection': 'fail'} + + self.assertTrue(issubclass(w[0].category, SyntaxWarning)) + self.assertEqual('non_abstract_base', InheritedDocumentFailTest._get_collection_name()) # Mixin tests class BaseMixin(object): @@ -539,6 +547,11 @@ class DocumentTest(unittest.TestCase): def test_inherited_collections(self): """Ensure that subclassed documents don't override parents' collections. """ + + # catch_warnings only available in Python 2.6+ + if (sys.version_info < (2,6,0)): + raise SkipTest('catch warnings as errors only available in python 2.6+') + with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") diff --git a/tests/test_fields.py b/tests/test_fields.py index dca4f21e..cc718f5f 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -1,3 +1,4 @@ +from __future__ import with_statement import datetime import os import unittest diff --git a/tests/test_queryset.py b/tests/test_queryset.py index 1960fc62..0c2d3c3a 100644 --- a/tests/test_queryset.py +++ b/tests/test_queryset.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +from __future__ import with_statement import unittest from datetime import datetime, timedelta @@ -499,7 +499,7 @@ class QuerySetTest(unittest.TestCase): Blog.drop_collection() - # Recreates the collection + # Recreates the collection self.assertEqual(0, Blog.objects.count()) with query_counter() as q: