improve 2-3 codebase compatibility

This commit is contained in:
Bastien Gérard 2018-09-09 15:50:48 +02:00
parent d17cac8210
commit 4314fa883f
17 changed files with 73 additions and 68 deletions

View File

@ -45,27 +45,27 @@ post2.link_url = 'http://tractiondigital.com/labs/mongoengine/docs'
post2.tags = ['mongoengine'] post2.tags = ['mongoengine']
post2.save() post2.save()
print 'ALL POSTS' print('ALL POSTS')
print print()
for post in Post.objects: for post in Post.objects:
print post.title print(post.title)
#print '=' * post.title.count() #print '=' * post.title.count()
print "=" * 20 print("=" * 20)
if isinstance(post, TextPost): if isinstance(post, TextPost):
print post.content print(post.content)
if isinstance(post, LinkPost): if isinstance(post, LinkPost):
print 'Link:', post.link_url print('Link:', post.link_url)
print print()
print print()
print 'POSTS TAGGED \'MONGODB\'' print('POSTS TAGGED \'MONGODB\'')
print print()
for post in Post.objects(tags='mongodb'): for post in Post.objects(tags='mongodb'):
print post.title print(post.title)
print print()
num_posts = Post.objects(tags='mongodb').count() num_posts = Post.objects(tags='mongodb').count()
print 'Found %d posts with tag "mongodb"' % num_posts print('Found %d posts with tag "mongodb"' % num_posts)

View File

@ -3,10 +3,10 @@ from mongoengine.errors import NotRegistered
__all__ = ('UPDATE_OPERATORS', 'get_document', '_document_registry') __all__ = ('UPDATE_OPERATORS', 'get_document', '_document_registry')
UPDATE_OPERATORS = set(['set', 'unset', 'inc', 'dec', 'mul', UPDATE_OPERATORS = {'set', 'unset', 'inc', 'dec', 'mul',
'pop', 'push', 'push_all', 'pull', 'pop', 'push', 'push_all', 'pull',
'pull_all', 'add_to_set', 'set_on_insert', 'pull_all', 'add_to_set', 'set_on_insert',
'min', 'max', 'rename']) 'min', 'max', 'rename'}
_document_registry = {} _document_registry = {}

View File

@ -377,7 +377,7 @@ class EmbeddedDocumentList(BaseList):
class StrictDict(object): class StrictDict(object):
__slots__ = () __slots__ = ()
_special_fields = set(['get', 'pop', 'iteritems', 'items', 'keys', 'create']) _special_fields = {'get', 'pop', 'iteritems', 'items', 'keys', 'create'}
_classes = {} _classes = {}
def __init__(self, **kwargs): def __init__(self, **kwargs):

View File

@ -302,7 +302,7 @@ class BaseDocument(object):
data['_cls'] = self._class_name data['_cls'] = self._class_name
# only root fields ['test1.a', 'test2'] => ['test1', 'test2'] # only root fields ['test1.a', 'test2'] => ['test1', 'test2']
root_fields = set([f.split('.')[0] for f in fields]) root_fields = {f.split('.')[0] for f in fields}
for field_name in self: for field_name in self:
if root_fields and field_name not in root_fields: if root_fields and field_name not in root_fields:
@ -567,7 +567,7 @@ class BaseDocument(object):
continue continue
elif isinstance(field, SortedListField) and field._ordering: elif isinstance(field, SortedListField) and field._ordering:
# if ordering is affected whole list is changed # if ordering is affected whole list is changed
if any(map(lambda d: field._ordering in d._changed_fields, data)): if any(field._ordering in d._changed_fields for d in data):
changed_fields.append(db_field_name) changed_fields.append(db_field_name)
continue continue

View File

@ -501,7 +501,7 @@ class GeoJsonBaseField(BaseField):
def validate(self, value): def validate(self, value):
"""Validate the GeoJson object based on its type.""" """Validate the GeoJson object based on its type."""
if isinstance(value, dict): if isinstance(value, dict):
if set(value.keys()) == set(['type', 'coordinates']): if set(value.keys()) == {'type', 'coordinates'}:
if value['type'] != self._type: if value['type'] != self._type:
self.error('%s type must be "%s"' % self.error('%s type must be "%s"' %
(self._name, self._type)) (self._name, self._type))

View File

@ -146,7 +146,7 @@ class DeReference(object):
for key, doc in references.iteritems(): for key, doc in references.iteritems():
object_map[(col_name, key)] = doc object_map[(col_name, key)] = doc
else: # Generic reference: use the refs data to convert to document else: # Generic reference: use the refs data to convert to document
if isinstance(doc_type, (ListField, DictField, MapField,)): if isinstance(doc_type, (ListField, DictField, MapField)):
continue continue
refs = [dbref for dbref in dbrefs refs = [dbref for dbref in dbrefs

View File

@ -39,7 +39,7 @@ class InvalidCollectionError(Exception):
pass pass
class EmbeddedDocument(BaseDocument): class EmbeddedDocument(six.with_metaclass(DocumentMetaclass, BaseDocument)):
"""A :class:`~mongoengine.Document` that isn't stored in its own """A :class:`~mongoengine.Document` that isn't stored in its own
collection. :class:`~mongoengine.EmbeddedDocument`\ s should be used as collection. :class:`~mongoengine.EmbeddedDocument`\ s should be used as
fields on :class:`~mongoengine.Document`\ s through the fields on :class:`~mongoengine.Document`\ s through the
@ -58,7 +58,6 @@ class EmbeddedDocument(BaseDocument):
# The __metaclass__ attribute is removed by 2to3 when running with Python3 # The __metaclass__ attribute is removed by 2to3 when running with Python3
# my_metaclass is defined so that metaclass can be queried in Python 2 & 3 # my_metaclass is defined so that metaclass can be queried in Python 2 & 3
my_metaclass = DocumentMetaclass my_metaclass = DocumentMetaclass
__metaclass__ = DocumentMetaclass
# A generic embedded document doesn't have any immutable properties # A generic embedded document doesn't have any immutable properties
# that describe it uniquely, hence it shouldn't be hashable. You can # that describe it uniquely, hence it shouldn't be hashable. You can
@ -95,7 +94,7 @@ class EmbeddedDocument(BaseDocument):
self._instance.reload(*args, **kwargs) self._instance.reload(*args, **kwargs)
class Document(BaseDocument): class Document(six.with_metaclass(TopLevelDocumentMetaclass, BaseDocument)):
"""The base class used for defining the structure and properties of """The base class used for defining the structure and properties of
collections of documents stored in MongoDB. Inherit from this class, and collections of documents stored in MongoDB. Inherit from this class, and
add fields as class attributes to define a document's structure. add fields as class attributes to define a document's structure.
@ -150,7 +149,6 @@ class Document(BaseDocument):
# The __metaclass__ attribute is removed by 2to3 when running with Python3 # The __metaclass__ attribute is removed by 2to3 when running with Python3
# my_metaclass is defined so that metaclass can be queried in Python 2 & 3 # my_metaclass is defined so that metaclass can be queried in Python 2 & 3
my_metaclass = TopLevelDocumentMetaclass my_metaclass = TopLevelDocumentMetaclass
__metaclass__ = TopLevelDocumentMetaclass
__slots__ = ('__objects',) __slots__ = ('__objects',)
@ -996,7 +994,7 @@ class Document(BaseDocument):
return {'missing': missing, 'extra': extra} return {'missing': missing, 'extra': extra}
class DynamicDocument(Document): class DynamicDocument(six.with_metaclass(TopLevelDocumentMetaclass, Document)):
"""A Dynamic Document class allowing flexible, expandable and uncontrolled """A Dynamic Document class allowing flexible, expandable and uncontrolled
schemas. As a :class:`~mongoengine.Document` subclass, acts in the same schemas. As a :class:`~mongoengine.Document` subclass, acts in the same
way as an ordinary document but has expanded style properties. Any data way as an ordinary document but has expanded style properties. Any data
@ -1013,7 +1011,6 @@ class DynamicDocument(Document):
# The __metaclass__ attribute is removed by 2to3 when running with Python3 # The __metaclass__ attribute is removed by 2to3 when running with Python3
# my_metaclass is defined so that metaclass can be queried in Python 2 & 3 # my_metaclass is defined so that metaclass can be queried in Python 2 & 3
my_metaclass = TopLevelDocumentMetaclass my_metaclass = TopLevelDocumentMetaclass
__metaclass__ = TopLevelDocumentMetaclass
_dynamic = True _dynamic = True
@ -1029,7 +1026,7 @@ class DynamicDocument(Document):
super(DynamicDocument, self).__delattr__(*args, **kwargs) super(DynamicDocument, self).__delattr__(*args, **kwargs)
class DynamicEmbeddedDocument(EmbeddedDocument): class DynamicEmbeddedDocument(six.with_metaclass(DocumentMetaclass, EmbeddedDocument)):
"""A Dynamic Embedded Document class allowing flexible, expandable and """A Dynamic Embedded Document class allowing flexible, expandable and
uncontrolled schemas. See :class:`~mongoengine.DynamicDocument` for more uncontrolled schemas. See :class:`~mongoengine.DynamicDocument` for more
information about dynamic documents. information about dynamic documents.
@ -1038,7 +1035,6 @@ class DynamicEmbeddedDocument(EmbeddedDocument):
# The __metaclass__ attribute is removed by 2to3 when running with Python3 # The __metaclass__ attribute is removed by 2to3 when running with Python3
# my_metaclass is defined so that metaclass can be queried in Python 2 & 3 # my_metaclass is defined so that metaclass can be queried in Python 2 & 3
my_metaclass = DocumentMetaclass my_metaclass = DocumentMetaclass
__metaclass__ = DocumentMetaclass
_dynamic = True _dynamic = True

View File

@ -24,6 +24,7 @@ try:
except ImportError: except ImportError:
Int64 = long Int64 = long
from mongoengine.base import (BaseDocument, BaseField, ComplexBaseField, from mongoengine.base import (BaseDocument, BaseField, ComplexBaseField,
GeoJsonBaseField, LazyReference, ObjectIdField, GeoJsonBaseField, LazyReference, ObjectIdField,
get_document) get_document)
@ -41,6 +42,12 @@ except ImportError:
Image = None Image = None
ImageOps = None ImageOps = None
if six.PY3:
# Useless as long as 2to3 gets executed
# as it turns `long` into `int` blindly
long = int
__all__ = ( __all__ = (
'StringField', 'URLField', 'EmailField', 'IntField', 'LongField', 'StringField', 'URLField', 'EmailField', 'IntField', 'LongField',
'FloatField', 'DecimalField', 'BooleanField', 'DateTimeField', 'DateField', 'FloatField', 'DecimalField', 'BooleanField', 'DateTimeField', 'DateField',
@ -597,7 +604,7 @@ class ComplexDateTimeField(StringField):
>>> ComplexDateTimeField()._convert_from_string(a) >>> ComplexDateTimeField()._convert_from_string(a)
datetime.datetime(2011, 6, 8, 20, 26, 24, 92284) datetime.datetime(2011, 6, 8, 20, 26, 24, 92284)
""" """
values = map(int, data.split(self.separator)) values = [int(d) for d in data.split(self.separator)]
return datetime.datetime(*values) return datetime.datetime(*values)
def __get__(self, instance, owner): def __get__(self, instance, owner):
@ -1525,9 +1532,11 @@ class GridFSProxy(object):
def __get__(self, instance, value): def __get__(self, instance, value):
return self return self
def __nonzero__(self): def __bool__(self):
return bool(self.grid_id) return bool(self.grid_id)
__nonzero__ = __bool__ # For Py2 support
def __getstate__(self): def __getstate__(self):
self_dict = self.__dict__ self_dict = self.__dict__
self_dict['_fs'] = None self_dict['_fs'] = None

View File

@ -2,7 +2,6 @@ from __future__ import absolute_import
import copy import copy
import itertools import itertools
import operator
import pprint import pprint
import re import re
import warnings import warnings
@ -209,14 +208,12 @@ class BaseQuerySet(object):
queryset = self.order_by() queryset = self.order_by()
return False if queryset.first() is None else True return False if queryset.first() is None else True
def __nonzero__(self):
"""Avoid to open all records in an if stmt in Py2."""
return self._has_data()
def __bool__(self): def __bool__(self):
"""Avoid to open all records in an if stmt in Py3.""" """Avoid to open all records in an if stmt in Py3."""
return self._has_data() return self._has_data()
__nonzero__ = __bool__ # For Py2 support
# Core functions # Core functions
def all(self): def all(self):
@ -269,13 +266,13 @@ class BaseQuerySet(object):
queryset = queryset.filter(*q_objs, **query) queryset = queryset.filter(*q_objs, **query)
try: try:
result = queryset.next() result = six.next(queryset)
except StopIteration: except StopIteration:
msg = ('%s matching query does not exist.' msg = ('%s matching query does not exist.'
% queryset._document._class_name) % queryset._document._class_name)
raise queryset._document.DoesNotExist(msg) raise queryset._document.DoesNotExist(msg)
try: try:
queryset.next() six.next(queryset)
except StopIteration: except StopIteration:
return result return result
@ -1478,13 +1475,13 @@ class BaseQuerySet(object):
# Iterator helpers # Iterator helpers
def next(self): def __next__(self):
"""Wrap the result in a :class:`~mongoengine.Document` object. """Wrap the result in a :class:`~mongoengine.Document` object.
""" """
if self._limit == 0 or self._none: if self._limit == 0 or self._none:
raise StopIteration raise StopIteration
raw_doc = self._cursor.next() raw_doc = six.next(self._cursor)
if self._as_pymongo: if self._as_pymongo:
return self._get_as_pymongo(raw_doc) return self._get_as_pymongo(raw_doc)
@ -1498,6 +1495,8 @@ class BaseQuerySet(object):
return doc return doc
next = __next__ # For Python2 support
def rewind(self): def rewind(self):
"""Rewind the cursor to its unevaluated state. """Rewind the cursor to its unevaluated state.

View File

@ -63,9 +63,11 @@ class QueryFieldList(object):
self._only_called = True self._only_called = True
return self return self
def __nonzero__(self): def __bool__(self):
return bool(self.fields) return bool(self.fields)
__nonzero__ = __bool__ # For Py2 support
def as_dict(self): def as_dict(self):
field_list = {field: self.value for field in self.fields} field_list = {field: self.value for field in self.fields}
if self.slice: if self.slice:

View File

@ -36,7 +36,7 @@ class QuerySetManager(object):
queryset_class = owner._meta.get('queryset_class', self.default) queryset_class = owner._meta.get('queryset_class', self.default)
queryset = queryset_class(owner, owner._get_collection()) queryset = queryset_class(owner, owner._get_collection())
if self.get_queryset: if self.get_queryset:
arg_count = self.get_queryset.func_code.co_argcount arg_count = self.get_queryset.__code__.co_argcount
if arg_count == 1: if arg_count == 1:
queryset = self.get_queryset(queryset) queryset = self.get_queryset(queryset)
elif arg_count == 2: elif arg_count == 2:

View File

@ -115,7 +115,7 @@ class QuerySet(BaseQuerySet):
# the result cache. # the result cache.
try: try:
for _ in six.moves.range(ITER_CHUNK_SIZE): for _ in six.moves.range(ITER_CHUNK_SIZE):
self._result_cache.append(self.next()) self._result_cache.append(six.next(self))
except StopIteration: except StopIteration:
# Getting this exception means there are no more docs in the # Getting this exception means there are no more docs in the
# db cursor. Set _has_more to False so that we can use that # db cursor. Set _has_more to False so that we can use that
@ -170,7 +170,7 @@ class QuerySetNoCache(BaseQuerySet):
data = [] data = []
for _ in six.moves.range(REPR_OUTPUT_SIZE + 1): for _ in six.moves.range(REPR_OUTPUT_SIZE + 1):
try: try:
data.append(self.next()) data.append(six.next(self))
except StopIteration: except StopIteration:
break break

View File

@ -44,9 +44,8 @@ CLASSIFIERS = [
"Programming Language :: Python :: 2", "Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7", "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: Implementation :: PyPy",
'Topic :: Database', 'Topic :: Database',

View File

@ -1,4 +1,4 @@
from all_warnings import AllWarnings from .all_warnings import AllWarnings
from document import * from .document import *
from queryset import * from .queryset import *
from fields import * from .fields import *

View File

@ -1,13 +1,13 @@
import unittest import unittest
from class_methods import * from .class_methods import *
from delta import * from .delta import *
from dynamic import * from .dynamic import *
from indexes import * from .indexes import *
from inheritance import * from .inheritance import *
from instance import * from .instance import *
from json_serialisation import * from .json_serialisation import *
from validation import * from .validation import *
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -1,3 +1,3 @@
from fields import * from .fields import *
from file_tests import * from .file_tests import *
from geo import * from .geo import *

View File

@ -1,6 +1,6 @@
from transform import * from .transform import *
from field_list import * from .field_list import *
from queryset import * from .queryset import *
from visitor import * from .visitor import *
from geo import * from .geo import *
from modify import * from .modify import *