Drop python2 support
This commit is contained in:
parent
a0b803959c
commit
421e3f324f
35
.travis.yml
35
.travis.yml
@ -1,13 +1,10 @@
|
|||||||
# For full coverage, we'd have to test all supported Python, MongoDB, and
|
# For full coverage, we'd have to test all supported Python, MongoDB, and
|
||||||
# PyMongo combinations. However, that would result in an overly long build
|
# PyMongo combinations. However, that would result in an overly long build
|
||||||
# with a very large number of jobs, hence we only test a subset of all the
|
# with a very large number of jobs, hence we only test a subset of all the
|
||||||
# combinations:
|
# combinations.
|
||||||
# * MongoDB v3.4 & the latest PyMongo v3.x is currently the "main" setup,
|
# * Python3.7, MongoDB v3.4 & the latest PyMongo v3.x is currently the "main" setup,
|
||||||
# tested against Python v2.7, v3.5, v3.6, v3.7, v3.8, PyPy and PyPy3.
|
# Other combinations are tested. See below for the details or check the travis jobs
|
||||||
# * Besides that, we test the lowest actively supported Python/MongoDB/PyMongo
|
|
||||||
# combination: MongoDB v3.4, PyMongo v3.4, Python v2.7.
|
|
||||||
# * MongoDB v3.6 is tested against Python v3.6, and PyMongo v3.6, v3.7, v3.8.
|
|
||||||
#
|
|
||||||
# We should periodically check MongoDB Server versions supported by MongoDB
|
# We should periodically check MongoDB Server versions supported by MongoDB
|
||||||
# Inc., add newly released versions to the test matrix, and remove versions
|
# Inc., add newly released versions to the test matrix, and remove versions
|
||||||
# which have reached their End of Life. See:
|
# which have reached their End of Life. See:
|
||||||
@ -16,21 +13,15 @@
|
|||||||
#
|
#
|
||||||
# Reminder: Update README.rst if you change MongoDB versions we test.
|
# Reminder: Update README.rst if you change MongoDB versions we test.
|
||||||
|
|
||||||
|
|
||||||
language: python
|
language: python
|
||||||
|
dist: xenial
|
||||||
python:
|
python:
|
||||||
- 2.7
|
|
||||||
- 3.5
|
- 3.5
|
||||||
- 3.6
|
- 3.6
|
||||||
- 3.7
|
- 3.7
|
||||||
- 3.8
|
- 3.8
|
||||||
- pypy
|
|
||||||
- pypy3
|
- pypy3
|
||||||
|
|
||||||
dist: xenial
|
|
||||||
|
|
||||||
dist: xenial
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- MONGODB_3_4=3.4.17
|
- MONGODB_3_4=3.4.17
|
||||||
@ -41,6 +32,8 @@ env:
|
|||||||
- PYMONGO_3_6=3.6
|
- PYMONGO_3_6=3.6
|
||||||
- PYMONGO_3_9=3.9
|
- PYMONGO_3_9=3.9
|
||||||
- PYMONGO_3_10=3.10
|
- PYMONGO_3_10=3.10
|
||||||
|
|
||||||
|
- MAIN_PYTHON_VERSION = "3.7"
|
||||||
matrix:
|
matrix:
|
||||||
- MONGODB=${MONGODB_3_4} PYMONGO=${PYMONGO_3_10}
|
- MONGODB=${MONGODB_3_4} PYMONGO=${PYMONGO_3_10}
|
||||||
|
|
||||||
@ -49,8 +42,6 @@ matrix:
|
|||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- python: 2.7
|
|
||||||
env: MONGODB=${MONGODB_3_4} PYMONGO=${PYMONGO_3_4}
|
|
||||||
- python: 3.7
|
- python: 3.7
|
||||||
env: MONGODB=${MONGODB_3_6} PYMONGO=${PYMONGO_3_6}
|
env: MONGODB=${MONGODB_3_6} PYMONGO=${PYMONGO_3_6}
|
||||||
- python: 3.7
|
- python: 3.7
|
||||||
@ -74,20 +65,20 @@ install:
|
|||||||
# tox dryrun to setup the tox venv (we run a mock test).
|
# tox dryrun to setup the tox venv (we run a mock test).
|
||||||
- tox -e $(echo py$TRAVIS_PYTHON_VERSION-mg$PYMONGO | tr -d . | sed -e 's/pypypy/pypy/') -- -a "-k=test_ci_placeholder"
|
- tox -e $(echo py$TRAVIS_PYTHON_VERSION-mg$PYMONGO | tr -d . | sed -e 's/pypypy/pypy/') -- -a "-k=test_ci_placeholder"
|
||||||
# Install black for Python v3.7 only.
|
# Install black for Python v3.7 only.
|
||||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.7' ]]; then pip install black; fi
|
- if [[ $TRAVIS_PYTHON_VERSION == $MAIN_PYTHON_VERSION ]]; then pip install black; fi
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- mkdir ${PWD}/mongodb-linux-x86_64-${MONGODB}/data
|
- mkdir ${PWD}/mongodb-linux-x86_64-${MONGODB}/data
|
||||||
- ${PWD}/mongodb-linux-x86_64-${MONGODB}/bin/mongod --dbpath ${PWD}/mongodb-linux-x86_64-${MONGODB}/data --logpath ${PWD}/mongodb-linux-x86_64-${MONGODB}/mongodb.log --fork
|
- ${PWD}/mongodb-linux-x86_64-${MONGODB}/bin/mongod --dbpath ${PWD}/mongodb-linux-x86_64-${MONGODB}/data --logpath ${PWD}/mongodb-linux-x86_64-${MONGODB}/mongodb.log --fork
|
||||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.7' ]]; then flake8 .; else echo "flake8 only runs on py37"; fi # Run flake8 for Python 3.7 only
|
- if [[ $TRAVIS_PYTHON_VERSION == $MAIN_PYTHON_VERSION ]]; then flake8 .; else echo "flake8 only runs on py37"; fi
|
||||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.7' ]]; then black --check .; else echo "black only runs on py37"; fi # Run black for Python 3.7 only
|
- if [[ $TRAVIS_PYTHON_VERSION == $MAIN_PYTHON_VERSION ]]; then black --check .; else echo "black only runs on py37"; fi
|
||||||
- mongo --eval 'db.version();' # Make sure mongo is awake
|
- mongo --eval 'db.version();' # Make sure mongo is awake
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- tox -e $(echo py$TRAVIS_PYTHON_VERSION-mg$PYMONGO | tr -d . | sed -e 's/pypypy/pypy/') -- -a "--cov=mongoengine"
|
- tox -e $(echo py$TRAVIS_PYTHON_VERSION-mg$PYMONGO | tr -d . | sed -e 's/pypypy/pypy/') -- -a "--cov=mongoengine"
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- coveralls --verbose
|
- - if [[ $TRAVIS_PYTHON_VERSION == $MAIN_PYTHON_VERSION ]]; then coveralls --verbose; else echo "coveralls only sent for py37"; fi
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
irc: irc.freenode.org#mongoengine
|
irc: irc.freenode.org#mongoengine
|
||||||
@ -109,11 +100,11 @@ deploy:
|
|||||||
distributions: "sdist bdist_wheel"
|
distributions: "sdist bdist_wheel"
|
||||||
|
|
||||||
# Only deploy on tagged commits (aka GitHub releases) and only for the parent
|
# Only deploy on tagged commits (aka GitHub releases) and only for the parent
|
||||||
# repo's builds running Python v2.7 along with PyMongo v3.x and MongoDB v3.4.
|
# repo's builds running Python v3.7 along with PyMongo v3.x and MongoDB v3.4.
|
||||||
# We run Travis against many different Python, PyMongo, and MongoDB versions
|
# We run Travis against many different Python, PyMongo, and MongoDB versions
|
||||||
# and we don't want the deploy to occur multiple times).
|
# and we don't want the deploy to occur multiple times).
|
||||||
on:
|
on:
|
||||||
tags: true
|
tags: true
|
||||||
repo: MongoEngine/mongoengine
|
repo: MongoEngine/mongoengine
|
||||||
condition: ($PYMONGO = ${PYMONGO_3_10}) && ($MONGODB = ${MONGODB_3_4})
|
condition: ($PYMONGO = ${PYMONGO_3_10}) && ($MONGODB = ${MONGODB_3_4})
|
||||||
python: 2.7
|
python: 3.7
|
||||||
|
@ -20,23 +20,23 @@ post to the `user group <http://groups.google.com/group/mongoengine-users>`
|
|||||||
Supported Interpreters
|
Supported Interpreters
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
MongoEngine supports CPython 2.7 and newer. Language
|
MongoEngine supports CPython 3.7 and newer as well as Pypy3.
|
||||||
features not supported by all interpreters can not be used.
|
Language features not supported by all interpreters can not be used.
|
||||||
|
|
||||||
Python 2/3 compatibility
|
Python3 codebase
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
The codebase is written in a compatible manner for python 2 & 3 so it
|
Since 0.20, the codebase is exclusively Python 3.
|
||||||
is important that this is taken into account when it comes to discrepencies
|
|
||||||
between the two versions (see https://python-future.org/compatible_idioms.html).
|
Earlier versions were exclusively Python2, and was relying on 2to3 to support Python3 installs.
|
||||||
Travis runs the tests against different Python versions as a safety net.
|
Travis runs the tests against the main Python 3.x versions.
|
||||||
|
|
||||||
|
|
||||||
Style Guide
|
Style Guide
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
MongoEngine uses `black <https://github.com/python/black>`_ for code
|
MongoEngine uses `black <https://github.com/python/black>`_ for code formatting.
|
||||||
formatting.
|
Black runs as part of the CI so it will fail in case the code is not formatted properly.
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
-------
|
-------
|
||||||
|
@ -3,8 +3,6 @@ import timeit
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
setup = """
|
setup = """
|
||||||
from builtins import range
|
|
||||||
|
|
||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
|
|
||||||
connection = MongoClient()
|
connection = MongoClient()
|
||||||
@ -59,8 +57,6 @@ myNoddys = noddy.find()
|
|||||||
print("{}s".format(t.timeit(1)))
|
print("{}s".format(t.timeit(1)))
|
||||||
|
|
||||||
setup = """
|
setup = """
|
||||||
from builtins import range
|
|
||||||
|
|
||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
|
|
||||||
connection = MongoClient()
|
connection = MongoClient()
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
from bson import DBRef
|
from bson import DBRef
|
||||||
from future.utils import listitems
|
|
||||||
import six
|
import six
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
|
|
||||||
@ -181,19 +180,6 @@ class BaseList(list):
|
|||||||
__iadd__ = mark_as_changed_wrapper(list.__iadd__)
|
__iadd__ = mark_as_changed_wrapper(list.__iadd__)
|
||||||
__imul__ = mark_as_changed_wrapper(list.__imul__)
|
__imul__ = mark_as_changed_wrapper(list.__imul__)
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
# Under py3 __setslice__, __delslice__ and __getslice__
|
|
||||||
# are replaced by __setitem__, __delitem__ and __getitem__ with a slice as parameter
|
|
||||||
# so we mimic this under python 2
|
|
||||||
def __setslice__(self, i, j, sequence):
|
|
||||||
return self.__setitem__(slice(i, j), sequence)
|
|
||||||
|
|
||||||
def __delslice__(self, i, j):
|
|
||||||
return self.__delitem__(slice(i, j))
|
|
||||||
|
|
||||||
def __getslice__(self, i, j):
|
|
||||||
return self.__getitem__(slice(i, j))
|
|
||||||
|
|
||||||
def _mark_as_changed(self, key=None):
|
def _mark_as_changed(self, key=None):
|
||||||
if hasattr(self._instance, "_mark_as_changed"):
|
if hasattr(self._instance, "_mark_as_changed"):
|
||||||
if key:
|
if key:
|
||||||
@ -426,7 +412,7 @@ class StrictDict(object):
|
|||||||
return len(list(iteritems(self)))
|
return len(list(iteritems(self)))
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return listitems(self) == listitems(other)
|
return list(self.items()) == list(other.items())
|
||||||
|
|
||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
return not (self == other)
|
return not (self == other)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import copy
|
import copy
|
||||||
|
|
||||||
import numbers
|
import numbers
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from bson import DBRef, ObjectId, SON, json_util
|
from bson import DBRef, ObjectId, SON, json_util
|
||||||
from future.utils import listitems
|
|
||||||
import pymongo
|
import pymongo
|
||||||
import six
|
import six
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
@ -26,7 +26,6 @@ from mongoengine.errors import (
|
|||||||
OperationError,
|
OperationError,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
)
|
)
|
||||||
from mongoengine.python_support import Hashable
|
|
||||||
|
|
||||||
__all__ = ("BaseDocument", "NON_FIELD_ERRORS")
|
__all__ = ("BaseDocument", "NON_FIELD_ERRORS")
|
||||||
|
|
||||||
@ -294,10 +293,7 @@ class BaseDocument(object):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
# TODO this could be simpler?
|
# TODO this could be simpler?
|
||||||
if hasattr(self, "__unicode__"):
|
if hasattr(self, "__unicode__"):
|
||||||
if six.PY3:
|
return self.__unicode__()
|
||||||
return self.__unicode__()
|
|
||||||
else:
|
|
||||||
return six.text_type(self).encode("utf-8")
|
|
||||||
return six.text_type("%s object" % self.__class__.__name__)
|
return six.text_type("%s object" % self.__class__.__name__)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
@ -671,7 +667,7 @@ class BaseDocument(object):
|
|||||||
del set_data["_id"]
|
del set_data["_id"]
|
||||||
|
|
||||||
# Determine if any changed items were actually unset.
|
# Determine if any changed items were actually unset.
|
||||||
for path, value in listitems(set_data):
|
for path, value in list(set_data.items()):
|
||||||
if value or isinstance(
|
if value or isinstance(
|
||||||
value, (numbers.Number, bool)
|
value, (numbers.Number, bool)
|
||||||
): # Account for 0 and True that are truthy
|
): # Account for 0 and True that are truthy
|
||||||
|
@ -5,12 +5,12 @@ import re
|
|||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
|
from io import BytesIO
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
from bson import Binary, DBRef, ObjectId, SON
|
from bson import Binary, DBRef, ObjectId, SON
|
||||||
from bson.int64 import Int64
|
from bson.int64 import Int64
|
||||||
import gridfs
|
import gridfs
|
||||||
from past.builtins import long
|
|
||||||
import pymongo
|
import pymongo
|
||||||
from pymongo import ReturnDocument
|
from pymongo import ReturnDocument
|
||||||
import six
|
import six
|
||||||
@ -39,7 +39,6 @@ from mongoengine.connection import DEFAULT_CONNECTION_NAME, get_db
|
|||||||
from mongoengine.document import Document, EmbeddedDocument
|
from mongoengine.document import Document, EmbeddedDocument
|
||||||
from mongoengine.errors import DoesNotExist, InvalidQueryError, ValidationError
|
from mongoengine.errors import DoesNotExist, InvalidQueryError, ValidationError
|
||||||
from mongoengine.mongodb_support import MONGODB_36, get_mongodb_version
|
from mongoengine.mongodb_support import MONGODB_36, get_mongodb_version
|
||||||
from mongoengine.python_support import StringIO
|
|
||||||
from mongoengine.queryset import DO_NOTHING
|
from mongoengine.queryset import DO_NOTHING
|
||||||
from mongoengine.queryset.base import BaseQuerySet
|
from mongoengine.queryset.base import BaseQuerySet
|
||||||
from mongoengine.queryset.transform import STRING_OPERATORS
|
from mongoengine.queryset.transform import STRING_OPERATORS
|
||||||
@ -338,7 +337,7 @@ class IntField(BaseField):
|
|||||||
|
|
||||||
|
|
||||||
class LongField(BaseField):
|
class LongField(BaseField):
|
||||||
"""64-bit integer field."""
|
"""64-bit integer field. (Equivalent to IntField since the support to Python2 was dropped)"""
|
||||||
|
|
||||||
def __init__(self, min_value=None, max_value=None, **kwargs):
|
def __init__(self, min_value=None, max_value=None, **kwargs):
|
||||||
self.min_value, self.max_value = min_value, max_value
|
self.min_value, self.max_value = min_value, max_value
|
||||||
@ -346,7 +345,7 @@ class LongField(BaseField):
|
|||||||
|
|
||||||
def to_python(self, value):
|
def to_python(self, value):
|
||||||
try:
|
try:
|
||||||
value = long(value)
|
value = int(value)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
pass
|
pass
|
||||||
return value
|
return value
|
||||||
@ -356,7 +355,7 @@ class LongField(BaseField):
|
|||||||
|
|
||||||
def validate(self, value):
|
def validate(self, value):
|
||||||
try:
|
try:
|
||||||
value = long(value)
|
value = int(value)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
self.error("%s could not be converted to long" % value)
|
self.error("%s could not be converted to long" % value)
|
||||||
|
|
||||||
@ -370,7 +369,7 @@ class LongField(BaseField):
|
|||||||
if value is None:
|
if value is None:
|
||||||
return value
|
return value
|
||||||
|
|
||||||
return super(LongField, self).prepare_query_value(op, long(value))
|
return super(LongField, self).prepare_query_value(op, int(value))
|
||||||
|
|
||||||
|
|
||||||
class FloatField(BaseField):
|
class FloatField(BaseField):
|
||||||
@ -1679,8 +1678,6 @@ class GridFSProxy(object):
|
|||||||
def __bool__(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
|
||||||
@ -1952,7 +1949,7 @@ class ImageGridFsProxy(GridFSProxy):
|
|||||||
|
|
||||||
w, h = img.size
|
w, h = img.size
|
||||||
|
|
||||||
io = StringIO()
|
io = BytesIO()
|
||||||
img.save(io, img_format, progressive=progressive)
|
img.save(io, img_format, progressive=progressive)
|
||||||
io.seek(0)
|
io.seek(0)
|
||||||
|
|
||||||
@ -1971,7 +1968,7 @@ class ImageGridFsProxy(GridFSProxy):
|
|||||||
def _put_thumbnail(self, thumbnail, format, progressive, **kwargs):
|
def _put_thumbnail(self, thumbnail, format, progressive, **kwargs):
|
||||||
w, h = thumbnail.size
|
w, h = thumbnail.size
|
||||||
|
|
||||||
io = StringIO()
|
io = BytesIO()
|
||||||
thumbnail.save(io, format, progressive=progressive)
|
thumbnail.save(io, format, progressive=progressive)
|
||||||
io.seek(0)
|
io.seek(0)
|
||||||
|
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
"""
|
|
||||||
Helper functions, constants, and types to aid with Python v2.7 - v3.x support
|
|
||||||
"""
|
|
||||||
import six
|
|
||||||
|
|
||||||
# six.BytesIO resolves to StringIO.StringIO in Py2 and io.BytesIO in Py3.
|
|
||||||
StringIO = six.BytesIO
|
|
||||||
|
|
||||||
# Additionally for Py2, try to use the faster cStringIO, if available
|
|
||||||
if not six.PY3:
|
|
||||||
try:
|
|
||||||
import cStringIO
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
StringIO = cStringIO.StringIO
|
|
||||||
|
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
from collections.abc import Hashable
|
|
||||||
else:
|
|
||||||
# raises DeprecationWarnings in Python >=3.7
|
|
||||||
from collections import Hashable
|
|
@ -1,5 +1,3 @@
|
|||||||
from __future__ import absolute_import
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import itertools
|
import itertools
|
||||||
import re
|
import re
|
||||||
@ -204,8 +202,6 @@ class BaseQuerySet(object):
|
|||||||
"""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):
|
||||||
|
@ -69,8 +69,6 @@ class QueryFieldList(object):
|
|||||||
def __bool__(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:
|
||||||
|
@ -10,7 +10,7 @@ from mongoengine.base import UPDATE_OPERATORS
|
|||||||
from mongoengine.common import _import_class
|
from mongoengine.common import _import_class
|
||||||
from mongoengine.errors import InvalidQueryError
|
from mongoengine.errors import InvalidQueryError
|
||||||
|
|
||||||
__all__ = ("query", "update")
|
__all__ = ("query", "update", "STRING_OPERATORS")
|
||||||
|
|
||||||
COMPARISON_OPERATORS = (
|
COMPARISON_OPERATORS = (
|
||||||
"ne",
|
"ne",
|
||||||
|
@ -143,8 +143,6 @@ class QCombination(QNode):
|
|||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return bool(self.children)
|
return bool(self.children)
|
||||||
|
|
||||||
__nonzero__ = __bool__ # For Py2 support
|
|
||||||
|
|
||||||
def accept(self, visitor):
|
def accept(self, visitor):
|
||||||
for i in range(len(self.children)):
|
for i in range(len(self.children)):
|
||||||
if isinstance(self.children[i], QNode):
|
if isinstance(self.children[i], QNode):
|
||||||
@ -180,8 +178,6 @@ class Q(QNode):
|
|||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return bool(self.query)
|
return bool(self.query)
|
||||||
|
|
||||||
__nonzero__ = __bool__ # For Py2 support
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.__class__ == other.__class__ and self.query == other.query
|
return self.__class__ == other.__class__ and self.query == other.query
|
||||||
|
|
||||||
|
17
setup.py
17
setup.py
@ -110,7 +110,6 @@ CLASSIFIERS = [
|
|||||||
|
|
||||||
PYTHON_VERSION = sys.version_info[0]
|
PYTHON_VERSION = sys.version_info[0]
|
||||||
PY3 = PYTHON_VERSION == 3
|
PY3 = PYTHON_VERSION == 3
|
||||||
PY2 = PYTHON_VERSION == 2
|
|
||||||
|
|
||||||
extra_opts = {
|
extra_opts = {
|
||||||
"packages": find_packages(exclude=["tests", "tests.*"]),
|
"packages": find_packages(exclude=["tests", "tests.*"]),
|
||||||
@ -124,14 +123,11 @@ extra_opts = {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
if PY3:
|
if "test" in sys.argv:
|
||||||
if "test" in sys.argv:
|
extra_opts["packages"] = find_packages()
|
||||||
extra_opts["packages"] = find_packages()
|
extra_opts["package_data"] = {
|
||||||
extra_opts["package_data"] = {
|
"tests": ["fields/mongoengine.png", "fields/mongodb_leaf.png"]
|
||||||
"tests": ["fields/mongoengine.png", "fields/mongodb_leaf.png"]
|
}
|
||||||
}
|
|
||||||
else:
|
|
||||||
extra_opts["tests_require"] += ["python-dateutil"]
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="mongoengine",
|
name="mongoengine",
|
||||||
@ -148,7 +144,8 @@ setup(
|
|||||||
long_description=LONG_DESCRIPTION,
|
long_description=LONG_DESCRIPTION,
|
||||||
platforms=["any"],
|
platforms=["any"],
|
||||||
classifiers=CLASSIFIERS,
|
classifiers=CLASSIFIERS,
|
||||||
install_requires=["pymongo>=3.4, <4.0", "six>=1.10.0", "future"],
|
python_requires=">=3.5",
|
||||||
|
install_requires=["pymongo>=3.4, <4.0", "six>=1.10.0"],
|
||||||
cmdclass={"test": PyTest},
|
cmdclass={"test": PyTest},
|
||||||
**extra_opts
|
**extra_opts
|
||||||
)
|
)
|
||||||
|
@ -123,10 +123,7 @@ class TestBinaryField(MongoDBTestCase):
|
|||||||
upsert=True, new=True, set__bin_field=BIN_VALUE
|
upsert=True, new=True, set__bin_field=BIN_VALUE
|
||||||
)
|
)
|
||||||
assert doc.some_field == "test"
|
assert doc.some_field == "test"
|
||||||
if six.PY3:
|
assert doc.bin_field == BIN_VALUE
|
||||||
assert doc.bin_field == BIN_VALUE
|
|
||||||
else:
|
|
||||||
assert doc.bin_field == Binary(BIN_VALUE)
|
|
||||||
|
|
||||||
def test_update_one(self):
|
def test_update_one(self):
|
||||||
"""Ensures no regression of bug #1127"""
|
"""Ensures no regression of bug #1127"""
|
||||||
@ -144,7 +141,4 @@ class TestBinaryField(MongoDBTestCase):
|
|||||||
)
|
)
|
||||||
assert n_updated == 1
|
assert n_updated == 1
|
||||||
fetched = MyDocument.objects.with_id(doc.id)
|
fetched = MyDocument.objects.with_id(doc.id)
|
||||||
if six.PY3:
|
assert fetched.bin_field == BIN_VALUE
|
||||||
assert fetched.bin_field == BIN_VALUE
|
|
||||||
else:
|
|
||||||
assert fetched.bin_field == Binary(BIN_VALUE)
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from builtins import str
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from mongoengine import (
|
from mongoengine import (
|
||||||
|
@ -3,6 +3,7 @@ import copy
|
|||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
import gridfs
|
import gridfs
|
||||||
import pytest
|
import pytest
|
||||||
@ -10,7 +11,6 @@ import six
|
|||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine.connection import get_db
|
from mongoengine.connection import get_db
|
||||||
from mongoengine.python_support import StringIO
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
@ -30,7 +30,7 @@ TEST_IMAGE2_PATH = os.path.join(os.path.dirname(__file__), "mongodb_leaf.png")
|
|||||||
def get_file(path):
|
def get_file(path):
|
||||||
"""Use a BytesIO instead of a file to allow
|
"""Use a BytesIO instead of a file to allow
|
||||||
to have a one-liner and avoid that the file remains opened"""
|
to have a one-liner and avoid that the file remains opened"""
|
||||||
bytes_io = StringIO()
|
bytes_io = BytesIO()
|
||||||
with open(path, "rb") as f:
|
with open(path, "rb") as f:
|
||||||
bytes_io.write(f.read())
|
bytes_io.write(f.read())
|
||||||
bytes_io.seek(0)
|
bytes_io.seek(0)
|
||||||
@ -80,7 +80,7 @@ class TestFileField(MongoDBTestCase):
|
|||||||
PutFile.drop_collection()
|
PutFile.drop_collection()
|
||||||
|
|
||||||
putfile = PutFile()
|
putfile = PutFile()
|
||||||
putstring = StringIO()
|
putstring = BytesIO()
|
||||||
putstring.write(text)
|
putstring.write(text)
|
||||||
putstring.seek(0)
|
putstring.seek(0)
|
||||||
putfile.the_file.put(putstring, content_type=content_type)
|
putfile.the_file.put(putstring, content_type=content_type)
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from builtins import str
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
|
@ -4470,10 +4470,7 @@ class TestQueryset(unittest.TestCase):
|
|||||||
|
|
||||||
pks = self.Person.objects.order_by("age").scalar("pk")[1:3]
|
pks = self.Person.objects.order_by("age").scalar("pk")[1:3]
|
||||||
names = self.Person.objects.scalar("name").in_bulk(list(pks)).values()
|
names = self.Person.objects.scalar("name").in_bulk(list(pks)).values()
|
||||||
if six.PY3:
|
expected = "['A1', 'A2']"
|
||||||
expected = "['A1', 'A2']"
|
|
||||||
else:
|
|
||||||
expected = "[u'A1', u'A2']"
|
|
||||||
assert expected == "%s" % sorted(names)
|
assert expected == "%s" % sorted(names)
|
||||||
|
|
||||||
def test_elem_match(self):
|
def test_elem_match(self):
|
||||||
|
@ -287,7 +287,7 @@ class TestBaseList:
|
|||||||
base_list[:] = [
|
base_list[:] = [
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
] # Will use __setslice__ under py2 and __setitem__ under py3
|
]
|
||||||
assert base_list._instance._changed_fields == ["my_name"]
|
assert base_list._instance._changed_fields == ["my_name"]
|
||||||
assert base_list == [0, 1]
|
assert base_list == [0, 1]
|
||||||
|
|
||||||
@ -296,13 +296,13 @@ class TestBaseList:
|
|||||||
base_list[0:2] = [
|
base_list[0:2] = [
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
] # Will use __setslice__ under py2 and __setitem__ under py3
|
]
|
||||||
assert base_list._instance._changed_fields == ["my_name"]
|
assert base_list._instance._changed_fields == ["my_name"]
|
||||||
assert base_list == [1, 0, 2]
|
assert base_list == [1, 0, 2]
|
||||||
|
|
||||||
def test___setitem___calls_with_step_slice_mark_as_changed(self):
|
def test___setitem___calls_with_step_slice_mark_as_changed(self):
|
||||||
base_list = self._get_baselist([0, 1, 2])
|
base_list = self._get_baselist([0, 1, 2])
|
||||||
base_list[0:3:2] = [-1, -2] # uses __setitem__ in both py2 & 3
|
base_list[0:3:2] = [-1, -2] # uses __setitem__
|
||||||
assert base_list._instance._changed_fields == ["my_name"]
|
assert base_list._instance._changed_fields == ["my_name"]
|
||||||
assert base_list == [-1, 1, -2]
|
assert base_list == [-1, 1, -2]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user