Python 2.5 and 3.1 support confirmed

This commit is contained in:
Ross Lawley 2012-08-07 13:07:51 +01:00
parent 44bd8cb85b
commit dd4af2df81
12 changed files with 68 additions and 55 deletions

View File

@ -1,8 +1,10 @@
# http://travis-ci.org/#!/MongoEngine/mongoengine # http://travis-ci.org/#!/MongoEngine/mongoengine
language: python language: python
python: python:
- 2.5
- 2.6 - 2.6
- 2.7 - 2.7
- 3.1
- 3.2 - 3.2
install: install:
- if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then sudo apt-get install zlib1g zlib1g-dev; fi - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then sudo apt-get install zlib1g zlib1g-dev; fi

View File

@ -10,7 +10,7 @@ from queryset import DoesNotExist, MultipleObjectsReturned
from queryset import DO_NOTHING from queryset import DO_NOTHING
from mongoengine import signals from mongoengine import signals
from mongoengine.python3_support import PY3, txt_type from mongoengine.python_support import PY3, PY25, txt_type
import pymongo import pymongo
from bson import ObjectId from bson import ObjectId
@ -894,10 +894,8 @@ 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 if PY25:
for key,val in value.items(): value = dict([(str(k), v) for k, v 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 = []
@ -1019,12 +1017,9 @@ 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 if PY25:
for key,val in data.items(): data = dict([(str(k), v) for k, v 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
obj._created = False obj._created = False
return obj return obj

View File

@ -1,7 +1,7 @@
#coding: utf-8 #coding: utf-8
from nose.plugins.skip import SkipTest from nose.plugins.skip import SkipTest
from mongoengine.python3_support import PY3 from mongoengine.python_support import PY3
from mongoengine import connect from mongoengine import connect
try: try:

View File

@ -10,8 +10,8 @@ from operator import itemgetter
import gridfs import gridfs
from bson import Binary, DBRef, SON, ObjectId from bson import Binary, DBRef, SON, ObjectId
from mongoengine.python3_support import (PY3, bin_type, from mongoengine.python_support import (PY3, bin_type, txt_type,
txt_type, str_types, StringIO) str_types, StringIO)
from base import (BaseField, ComplexBaseField, ObjectIdField, from base import (BaseField, ComplexBaseField, ObjectIdField,
ValidationError, get_document, BaseDocument) ValidationError, get_document, BaseDocument)
from queryset import DO_NOTHING, QuerySet from queryset import DO_NOTHING, QuerySet
@ -840,13 +840,20 @@ class BinaryField(BaseField):
self.max_bytes = max_bytes self.max_bytes = max_bytes
super(BinaryField, self).__init__(**kwargs) super(BinaryField, self).__init__(**kwargs)
def __set__(self, instance, value):
"""Handle bytearrays in python 3.1"""
if PY3 and isinstance(value, bytearray):
value = bin_type(value)
return super(BinaryField, self).__set__(instance, value)
def to_mongo(self, value): def to_mongo(self, value):
return Binary(value) return Binary(value)
def validate(self, value): def validate(self, value):
if not isinstance(value, (bin_type, txt_type, Binary)): if not isinstance(value, (bin_type, txt_type, Binary)):
self.error("BinaryField only accepts instances of " self.error("BinaryField only accepts instances of "
"(%s, %s, Binary)" % (bin_type.__name__,txt_type.__name__)) "(%s, %s, Binary)" % (
bin_type.__name__, txt_type.__name__))
if self.max_bytes is not None and len(value) > self.max_bytes: if self.max_bytes is not None and len(value) > self.max_bytes:
self.error('Binary value is too long') self.error('Binary value is too long')
@ -1270,9 +1277,9 @@ class SequenceField(IntField):
""" """
Generate and Increment the counter Generate and Increment the counter
""" """
sequence_id = "%s.%s"%(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},
update={"$inc": {"next": 1}}, update={"$inc": {"next": 1}},
new=True, new=True,

View File

@ -1,8 +1,9 @@
"""Helper functions and types to aid with Python 3 support.""" """Helper functions and types to aid with Python 2.5 - 3 support."""
import sys import sys
PY3 = sys.version_info[0] == 3 PY3 = sys.version_info[0] == 3
PY25 = sys.version_info[:2] == (2, 5)
if PY3: if PY3:
import codecs import codecs
@ -27,3 +28,16 @@ else:
txt_type = unicode txt_type = unicode
str_types = (bin_type, txt_type) str_types = (bin_type, txt_type)
if PY25:
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)
reduce = reduce
else:
from itertools import product
from functools import reduce

View File

@ -3,9 +3,9 @@ import re
import copy import copy
import itertools import itertools
import operator import operator
import functools
import sys
from functools import partial from functools import partial
from mongoengine.python_support import product, reduce
import pymongo import pymongo
from bson.code import Code from bson.code import Code
@ -15,18 +15,6 @@ 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

View File

@ -6,6 +6,5 @@ detailed-errors = 1
#cover-html = 1 #cover-html = 1
#cover-html-dir = ../htmlcov #cover-html-dir = ../htmlcov
#cover-package = mongoengine #cover-package = mongoengine
where = tests
py3where = build py3where = build
#tests = test_bugfix.py where = tests

View File

@ -1,6 +1,6 @@
from setuptools import setup, find_packages
import os import os
import sys import sys
from setuptools import setup, find_packages
# Hack to silence atexit traceback in newer python versions # Hack to silence atexit traceback in newer python versions
try: try:
@ -16,6 +16,7 @@ try:
except: except:
pass pass
def get_version(version_tuple): def get_version(version_tuple):
version = '%s.%s' % (version_tuple[0], version_tuple[1]) version = '%s.%s' % (version_tuple[0], version_tuple[1])
if version_tuple[2]: if version_tuple[2]:
@ -38,7 +39,13 @@ CLASSIFIERS = [
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Programming Language :: Python', 'Programming Language :: Python',
"Programming Language :: Python :: 2", "Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.5",
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.1",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: Implementation :: CPython",
'Topic :: Database', 'Topic :: Database',
'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Software Development :: Libraries :: Python Modules',
] ]

View File

@ -1,7 +1,7 @@
from __future__ import with_statement 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.python_support import PY3
from mongoengine import * from mongoengine import *
try: try:

View File

@ -209,7 +209,6 @@ class DocumentTest(unittest.TestCase):
} }
self.assertEqual(Dog._superclasses, dog_superclasses) self.assertEqual(Dog._superclasses, dog_superclasses)
def test_external_superclasses(self): def test_external_superclasses(self):
"""Ensure that the correct list of sub and super classes is assembled. """Ensure that the correct list of sub and super classes is assembled.
when importing part of the model when importing part of the model

View File

@ -14,7 +14,7 @@ from nose.plugins.skip import SkipTest
from mongoengine import * from mongoengine import *
from mongoengine.connection import get_db from mongoengine.connection import get_db
from mongoengine.base import _document_registry, NotRegistered from mongoengine.base import _document_registry, NotRegistered
from mongoengine.python3_support import PY3, b, StringIO, bin_type from mongoengine.python_support import PY3, b, StringIO, bin_type
TEST_IMAGE_PATH = os.path.join(os.path.dirname(__file__), 'mongoengine.png') TEST_IMAGE_PATH = os.path.join(os.path.dirname(__file__), 'mongoengine.png')

View File

@ -9,7 +9,7 @@ from bson import ObjectId
from mongoengine import * from mongoengine import *
from mongoengine.connection import get_connection from mongoengine.connection import get_connection
from mongoengine.python3_support import PY3 from mongoengine.python_support import PY3
from mongoengine.tests import query_counter from mongoengine.tests import query_counter
from mongoengine.queryset import (QuerySet, QuerySetManager, from mongoengine.queryset import (QuerySet, QuerySetManager,
MultipleObjectsReturned, DoesNotExist, MultipleObjectsReturned, DoesNotExist,
@ -1455,6 +1455,8 @@ class QuerySetTest(unittest.TestCase):
name = StringField() name = StringField()
parent = ReferenceField('self', reverse_delete_rule=CASCADE) parent = ReferenceField('self', reverse_delete_rule=CASCADE)
Category.drop_collection()
num_children = 3 num_children = 3
base = Category(name='Root') base = Category(name='Root')
base.save() base.save()