PYTHON-2133 Remove py2 support from test
Also delete bson/py3compat.py
This commit is contained in:
parent
6c2d629006
commit
a72e8b8823
@ -14,13 +14,7 @@
|
||||
|
||||
"""A BSON wrapper for long (int in python3)"""
|
||||
|
||||
from bson.py3compat import PY3
|
||||
|
||||
if PY3:
|
||||
long = int
|
||||
|
||||
|
||||
class Int64(long):
|
||||
class Int64(int):
|
||||
"""Representation of the BSON int64 type.
|
||||
|
||||
This is necessary because every integral number is an :class:`int` in
|
||||
|
||||
@ -1,107 +0,0 @@
|
||||
# Copyright 2009-present MongoDB, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you
|
||||
# may not use this file except in compliance with the License. You
|
||||
# may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# permissions and limitations under the License.
|
||||
|
||||
"""Utility functions and definitions for python3 compatibility."""
|
||||
|
||||
import sys
|
||||
|
||||
PY3 = sys.version_info[0] == 3
|
||||
|
||||
if PY3:
|
||||
import codecs
|
||||
import collections.abc as abc
|
||||
import _thread as thread
|
||||
from abc import ABC, abstractmethod
|
||||
from io import BytesIO as StringIO
|
||||
|
||||
def abstractproperty(func):
|
||||
return property(abstractmethod(func))
|
||||
|
||||
MAXSIZE = sys.maxsize
|
||||
|
||||
imap = map
|
||||
|
||||
def b(s):
|
||||
# BSON and socket operations deal in binary data. In
|
||||
# python 3 that means instances of `bytes`. In python
|
||||
# 2.7 you can create an alias for `bytes` using
|
||||
# the b prefix (e.g. b'foo').
|
||||
# See http://python3porting.com/problems.html#nicer-solutions
|
||||
return codecs.latin_1_encode(s)[0]
|
||||
|
||||
def bytes_from_hex(h):
|
||||
return bytes.fromhex(h)
|
||||
|
||||
def iteritems(d):
|
||||
return iter(d.items())
|
||||
|
||||
def itervalues(d):
|
||||
return iter(d.values())
|
||||
|
||||
def reraise(exctype, value, trace=None):
|
||||
raise exctype(str(value)).with_traceback(trace)
|
||||
|
||||
def reraise_instance(exc_instance, trace=None):
|
||||
raise exc_instance.with_traceback(trace)
|
||||
|
||||
def _unicode(s):
|
||||
return s
|
||||
|
||||
text_type = str
|
||||
string_type = str
|
||||
integer_types = int
|
||||
else:
|
||||
import collections as abc
|
||||
import thread
|
||||
from abc import ABCMeta, abstractproperty
|
||||
|
||||
from itertools import imap
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
|
||||
ABC = ABCMeta('ABC', (object,), {})
|
||||
|
||||
MAXSIZE = sys.maxint
|
||||
|
||||
def b(s):
|
||||
# See comments above. In python 2.x b('foo') is just 'foo'.
|
||||
return s
|
||||
|
||||
def bytes_from_hex(h):
|
||||
return h.decode('hex')
|
||||
|
||||
def iteritems(d):
|
||||
return d.iteritems()
|
||||
|
||||
def itervalues(d):
|
||||
return d.itervalues()
|
||||
|
||||
def reraise(exctype, value, trace=None):
|
||||
_reraise(exctype, str(value), trace)
|
||||
|
||||
def reraise_instance(exc_instance, trace=None):
|
||||
_reraise(exc_instance, None, trace)
|
||||
|
||||
# "raise x, y, z" raises SyntaxError in Python 3
|
||||
exec("""def _reraise(exc, value, trace):
|
||||
raise exc, value, trace
|
||||
""")
|
||||
|
||||
_unicode = unicode
|
||||
|
||||
string_type = basestring
|
||||
text_type = unicode
|
||||
integer_types = (int, long)
|
||||
193
test/barrier.py
193
test/barrier.py
@ -1,193 +0,0 @@
|
||||
# Backport of the threading.Barrier class from python 3.8, with small
|
||||
# changes to support python 2.7.
|
||||
# https://github.com/python/cpython/blob/v3.8.2/Lib/threading.py#L562-L728
|
||||
|
||||
from threading import (Condition,
|
||||
Lock)
|
||||
|
||||
from pymongo.monotonic import time as _time
|
||||
|
||||
|
||||
# Backport Condition.wait_for from 3.8.2
|
||||
# https://github.com/python/cpython/blob/v3.8.2/Lib/threading.py#L318-L339
|
||||
def wait_for(condition, predicate, timeout=None):
|
||||
"""Wait until a condition evaluates to True.
|
||||
|
||||
predicate should be a callable which result will be interpreted as a
|
||||
boolean value. A timeout may be provided giving the maximum time to
|
||||
wait.
|
||||
|
||||
"""
|
||||
endtime = None
|
||||
waittime = timeout
|
||||
result = predicate()
|
||||
while not result:
|
||||
if waittime is not None:
|
||||
if endtime is None:
|
||||
endtime = _time() + waittime
|
||||
else:
|
||||
waittime = endtime - _time()
|
||||
if waittime <= 0:
|
||||
break
|
||||
condition.wait(waittime)
|
||||
result = predicate()
|
||||
return result
|
||||
|
||||
|
||||
# A barrier class. Inspired in part by the pthread_barrier_* api and
|
||||
# the CyclicBarrier class from Java. See
|
||||
# http://sourceware.org/pthreads-win32/manual/pthread_barrier_init.html and
|
||||
# http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/
|
||||
# CyclicBarrier.html
|
||||
# for information.
|
||||
# We maintain two main states, 'filling' and 'draining' enabling the barrier
|
||||
# to be cyclic. Threads are not allowed into it until it has fully drained
|
||||
# since the previous cycle. In addition, a 'resetting' state exists which is
|
||||
# similar to 'draining' except that threads leave with a BrokenBarrierError,
|
||||
# and a 'broken' state in which all threads get the exception.
|
||||
class Barrier(object):
|
||||
"""Implements a Barrier.
|
||||
Useful for synchronizing a fixed number of threads at known synchronization
|
||||
points. Threads block on 'wait()' and are simultaneously awoken once they
|
||||
have all made that call.
|
||||
"""
|
||||
|
||||
def __init__(self, parties, action=None, timeout=None):
|
||||
"""Create a barrier, initialised to 'parties' threads.
|
||||
'action' is a callable which, when supplied, will be called by one of
|
||||
the threads after they have all entered the barrier and just prior to
|
||||
releasing them all. If a 'timeout' is provided, it is used as the
|
||||
default for all subsequent 'wait()' calls.
|
||||
"""
|
||||
self._cond = Condition(Lock())
|
||||
self._action = action
|
||||
self._timeout = timeout
|
||||
self._parties = parties
|
||||
self._state = 0 #0 filling, 1, draining, -1 resetting, -2 broken
|
||||
self._count = 0
|
||||
|
||||
def wait(self, timeout=None):
|
||||
"""Wait for the barrier.
|
||||
When the specified number of threads have started waiting, they are all
|
||||
simultaneously awoken. If an 'action' was provided for the barrier, one
|
||||
of the threads will have executed that callback prior to returning.
|
||||
Returns an individual index number from 0 to 'parties-1'.
|
||||
"""
|
||||
if timeout is None:
|
||||
timeout = self._timeout
|
||||
with self._cond:
|
||||
self._enter() # Block while the barrier drains.
|
||||
index = self._count
|
||||
self._count += 1
|
||||
try:
|
||||
if index + 1 == self._parties:
|
||||
# We release the barrier
|
||||
self._release()
|
||||
else:
|
||||
# We wait until someone releases us
|
||||
self._wait(timeout)
|
||||
return index
|
||||
finally:
|
||||
self._count -= 1
|
||||
# Wake up any threads waiting for barrier to drain.
|
||||
self._exit()
|
||||
|
||||
# Block until the barrier is ready for us, or raise an exception
|
||||
# if it is broken.
|
||||
def _enter(self):
|
||||
while self._state in (-1, 1):
|
||||
# It is draining or resetting, wait until done
|
||||
self._cond.wait()
|
||||
#see if the barrier is in a broken state
|
||||
if self._state < 0:
|
||||
raise BrokenBarrierError
|
||||
assert self._state == 0
|
||||
|
||||
# Optionally run the 'action' and release the threads waiting
|
||||
# in the barrier.
|
||||
def _release(self):
|
||||
try:
|
||||
if self._action:
|
||||
self._action()
|
||||
# enter draining state
|
||||
self._state = 1
|
||||
self._cond.notify_all()
|
||||
except:
|
||||
#an exception during the _action handler. Break and reraise
|
||||
self._break()
|
||||
raise
|
||||
|
||||
# Wait in the barrier until we are released. Raise an exception
|
||||
# if the barrier is reset or broken.
|
||||
def _wait(self, timeout):
|
||||
if not wait_for(self._cond, lambda : self._state != 0, timeout):
|
||||
#timed out. Break the barrier
|
||||
self._break()
|
||||
raise BrokenBarrierError
|
||||
if self._state < 0:
|
||||
raise BrokenBarrierError
|
||||
assert self._state == 1
|
||||
|
||||
# If we are the last thread to exit the barrier, signal any threads
|
||||
# waiting for the barrier to drain.
|
||||
def _exit(self):
|
||||
if self._count == 0:
|
||||
if self._state in (-1, 1):
|
||||
#resetting or draining
|
||||
self._state = 0
|
||||
self._cond.notify_all()
|
||||
|
||||
def reset(self):
|
||||
"""Reset the barrier to the initial state.
|
||||
Any threads currently waiting will get the BrokenBarrier exception
|
||||
raised.
|
||||
"""
|
||||
with self._cond:
|
||||
if self._count > 0:
|
||||
if self._state == 0:
|
||||
#reset the barrier, waking up threads
|
||||
self._state = -1
|
||||
elif self._state == -2:
|
||||
#was broken, set it to reset state
|
||||
#which clears when the last thread exits
|
||||
self._state = -1
|
||||
else:
|
||||
self._state = 0
|
||||
self._cond.notify_all()
|
||||
|
||||
def abort(self):
|
||||
"""Place the barrier into a 'broken' state.
|
||||
Useful in case of error. Any currently waiting threads and threads
|
||||
attempting to 'wait()' will have BrokenBarrierError raised.
|
||||
"""
|
||||
with self._cond:
|
||||
self._break()
|
||||
|
||||
def _break(self):
|
||||
# An internal error was detected. The barrier is set to
|
||||
# a broken state all parties awakened.
|
||||
self._state = -2
|
||||
self._cond.notify_all()
|
||||
|
||||
@property
|
||||
def parties(self):
|
||||
"""Return the number of threads required to trip the barrier."""
|
||||
return self._parties
|
||||
|
||||
@property
|
||||
def n_waiting(self):
|
||||
"""Return the number of threads currently waiting at the barrier."""
|
||||
# We don't need synchronization here since this is an ephemeral result
|
||||
# anyway. It returns the correct value in the steady state.
|
||||
if self._state == 0:
|
||||
return self._count
|
||||
return 0
|
||||
|
||||
@property
|
||||
def broken(self):
|
||||
"""Return True if the barrier is in a broken state."""
|
||||
return self._state == -2
|
||||
|
||||
# exception raised by the Barrier class
|
||||
class BrokenBarrierError(RuntimeError):
|
||||
pass
|
||||
@ -12,22 +12,18 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import random
|
||||
import traceback
|
||||
import datetime
|
||||
import random
|
||||
import re
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson.binary import Binary
|
||||
from bson.dbref import DBRef
|
||||
from bson.objectid import ObjectId
|
||||
from bson.py3compat import MAXSIZE, PY3, iteritems
|
||||
from bson.son import SON
|
||||
|
||||
if PY3:
|
||||
unichr = chr
|
||||
|
||||
gen_target = 100
|
||||
reduction_attempts = 10
|
||||
examples = 5
|
||||
@ -59,7 +55,7 @@ def gen_int():
|
||||
|
||||
|
||||
def gen_float():
|
||||
return lambda: (random.random() - 0.5) * MAXSIZE
|
||||
return lambda: (random.random() - 0.5) * sys.maxsize
|
||||
|
||||
|
||||
def gen_boolean():
|
||||
@ -74,12 +70,8 @@ def gen_printable_string(gen_length):
|
||||
return lambda: "".join(gen_list(gen_printable_char(), gen_length)())
|
||||
|
||||
|
||||
if PY3:
|
||||
def gen_char(set=None):
|
||||
return lambda: bytes([random.randint(0, 255)])
|
||||
else:
|
||||
def gen_char(set=None):
|
||||
return lambda: chr(random.randint(0, 255))
|
||||
def gen_char(set=None):
|
||||
return lambda: bytes([random.randint(0, 255)])
|
||||
|
||||
|
||||
def gen_string(gen_length):
|
||||
@ -87,7 +79,7 @@ def gen_string(gen_length):
|
||||
|
||||
|
||||
def gen_unichar():
|
||||
return lambda: unichr(random.randint(1, 0xFFF))
|
||||
return lambda: chr(random.randint(1, 0xFFF))
|
||||
|
||||
|
||||
def gen_unicode(gen_length):
|
||||
@ -150,15 +142,9 @@ def gen_dbref():
|
||||
|
||||
def gen_mongo_value(depth, ref):
|
||||
|
||||
bintype = Binary
|
||||
if PY3:
|
||||
# If we used Binary in python3 tests would fail since we
|
||||
# decode BSON binary subtype 0 to bytes. Testing this with
|
||||
# bytes in python3 makes a lot more sense.
|
||||
bintype = bytes
|
||||
choices = [gen_unicode(gen_range(0, 50)),
|
||||
gen_printable_string(gen_range(0, 50)),
|
||||
my_map(gen_string(gen_range(0, 1000)), bintype),
|
||||
my_map(gen_string(gen_range(0, 1000)), bytes),
|
||||
gen_int(),
|
||||
gen_float(),
|
||||
gen_boolean(),
|
||||
@ -195,7 +181,7 @@ def simplify(case): # TODO this is a hack
|
||||
return (True, simplified)
|
||||
else:
|
||||
# simplify a value
|
||||
simplified_items = list(iteritems(simplified))
|
||||
simplified_items = list(simplified.items())
|
||||
if not len(simplified_items):
|
||||
return (False, case)
|
||||
(key, value) = random.choice(simplified_items)
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
import array
|
||||
import base64
|
||||
import copy
|
||||
import mmap
|
||||
import pickle
|
||||
import platform
|
||||
import sys
|
||||
@ -29,11 +30,12 @@ import bson
|
||||
from bson import decode, encode
|
||||
from bson.binary import *
|
||||
from bson.codec_options import CodecOptions
|
||||
from bson.py3compat import PY3
|
||||
from bson.son import SON
|
||||
|
||||
from pymongo.common import validate_uuid_representation
|
||||
from pymongo.mongo_client import MongoClient
|
||||
from pymongo.write_concern import WriteConcern
|
||||
|
||||
from test import client_context, unittest, IntegrationTest
|
||||
from test.utils import ignore_deprecations
|
||||
|
||||
@ -328,14 +330,9 @@ class TestBinary(unittest.TestCase):
|
||||
b1 = Binary(b'123', 2)
|
||||
|
||||
# For testing backwards compatibility with pre-2.4 pymongo
|
||||
if PY3:
|
||||
p = (b"\x80\x03cbson.binary\nBinary\nq\x00C\x03123q\x01\x85q"
|
||||
b"\x02\x81q\x03}q\x04X\x10\x00\x00\x00_Binary__subtypeq"
|
||||
b"\x05K\x02sb.")
|
||||
else:
|
||||
p = (b"ccopy_reg\n_reconstructor\np0\n(cbson.binary\nBinary\np1\nc"
|
||||
b"__builtin__\nstr\np2\nS'123'\np3\ntp4\nRp5\n(dp6\nS'_Binary"
|
||||
b"__subtype'\np7\nI2\nsb.")
|
||||
p = (b"\x80\x03cbson.binary\nBinary\nq\x00C\x03123q\x01\x85q"
|
||||
b"\x02\x81q\x03}q\x04X\x10\x00\x00\x00_Binary__subtypeq"
|
||||
b"\x05K\x02sb.")
|
||||
|
||||
if not sys.version.startswith('3.0'):
|
||||
self.assertEqual(b1, pickle.loads(p))
|
||||
@ -357,16 +354,11 @@ class TestBinary(unittest.TestCase):
|
||||
|
||||
self.assertEqual(b0, Binary(memoryview(b'123'), 2))
|
||||
self.assertEqual(b0, Binary(bytearray(b'123'), 2))
|
||||
# mmap.mmap and array.array only expose the
|
||||
# buffer interface in python 3.x
|
||||
if PY3:
|
||||
# No mmap module in Jython
|
||||
import mmap
|
||||
with mmap.mmap(-1, len(b'123')) as mm:
|
||||
mm.write(b'123')
|
||||
mm.seek(0)
|
||||
self.assertEqual(b0, Binary(mm, 2))
|
||||
self.assertEqual(b0, Binary(array.array('B', b'123'), 2))
|
||||
with mmap.mmap(-1, len(b'123')) as mm:
|
||||
mm.write(b'123')
|
||||
mm.seek(0)
|
||||
self.assertEqual(b0, Binary(mm, 2))
|
||||
self.assertEqual(b0, Binary(array.array('B', b'123'), 2))
|
||||
|
||||
|
||||
class TestUuidSpecExplicitCoding(unittest.TestCase):
|
||||
@ -377,9 +369,7 @@ class TestUuidSpecExplicitCoding(unittest.TestCase):
|
||||
|
||||
@staticmethod
|
||||
def _hex_to_bytes(hexstring):
|
||||
if PY3:
|
||||
return bytes.fromhex(hexstring)
|
||||
return hexstring.decode("hex")
|
||||
return bytes.fromhex(hexstring)
|
||||
|
||||
# Explicit encoding prose test #1
|
||||
def test_encoding_1(self):
|
||||
@ -482,9 +472,7 @@ class TestUuidSpecImplicitCoding(IntegrationTest):
|
||||
|
||||
@staticmethod
|
||||
def _hex_to_bytes(hexstring):
|
||||
if PY3:
|
||||
return bytes.fromhex(hexstring)
|
||||
return hexstring.decode("hex")
|
||||
return bytes.fromhex(hexstring)
|
||||
|
||||
def _get_coll_w_uuid_rep(self, uuid_rep):
|
||||
codec_options = self.client.codec_options.with_options(
|
||||
|
||||
@ -16,14 +16,19 @@
|
||||
|
||||
"""Test the bson module."""
|
||||
|
||||
import array
|
||||
import collections
|
||||
import datetime
|
||||
import mmap
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
import uuid
|
||||
|
||||
from collections import abc, OrderedDict
|
||||
from io import BytesIO
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
import bson
|
||||
@ -42,23 +47,18 @@ from bson.codec_options import CodecOptions
|
||||
from bson.int64 import Int64
|
||||
from bson.objectid import ObjectId
|
||||
from bson.dbref import DBRef
|
||||
from bson.py3compat import abc, iteritems, PY3, StringIO, text_type
|
||||
from bson.son import SON
|
||||
from bson.timestamp import Timestamp
|
||||
from bson.errors import (InvalidBSON,
|
||||
InvalidDocument,
|
||||
InvalidStringData)
|
||||
InvalidDocument)
|
||||
from bson.max_key import MaxKey
|
||||
from bson.min_key import MinKey
|
||||
from bson.tz_util import (FixedOffset,
|
||||
utc)
|
||||
|
||||
from test import qcheck, SkipTest, unittest
|
||||
from test import qcheck, unittest
|
||||
from test.utils import ExceptionCatchingThread
|
||||
|
||||
if PY3:
|
||||
long = int
|
||||
|
||||
|
||||
class NotADict(abc.MutableMapping):
|
||||
"""Non-dict type that implements the mapping protocol."""
|
||||
@ -134,7 +134,7 @@ class TestBSON(unittest.TestCase):
|
||||
helper({})
|
||||
helper({"test": u"hello"})
|
||||
self.assertTrue(isinstance(decoder(encoder(
|
||||
{"hello": "world"}))["hello"], text_type))
|
||||
{"hello": "world"}))["hello"], str))
|
||||
helper({"mike": -10120})
|
||||
helper({"long": Int64(10)})
|
||||
helper({"really big long": 2147483648})
|
||||
@ -293,7 +293,7 @@ class TestBSON(unittest.TestCase):
|
||||
b"\x6f\x20\x77\x6F\x72\x6C\x64\x00\x00"
|
||||
b"\x05\x00\x00\x00\x00")))
|
||||
self.assertEqual([{"test": u"hello world"}, {}],
|
||||
list(decode_file_iter(StringIO(
|
||||
list(decode_file_iter(BytesIO(
|
||||
b"\x1B\x00\x00\x00\x0E\x74\x65\x73\x74"
|
||||
b"\x00\x0C\x00\x00\x00\x68\x65\x6C\x6C"
|
||||
b"\x6f\x20\x77\x6F\x72\x6C\x64\x00\x00"
|
||||
@ -305,14 +305,11 @@ class TestBSON(unittest.TestCase):
|
||||
self.assertEqual(docs, decode_all(bytearray(bs)))
|
||||
self.assertEqual(docs, decode_all(memoryview(bs)))
|
||||
self.assertEqual(docs, decode_all(memoryview(b'1' + bs + b'1')[1:-1]))
|
||||
if PY3:
|
||||
import array
|
||||
import mmap
|
||||
self.assertEqual(docs, decode_all(array.array('B', bs)))
|
||||
with mmap.mmap(-1, len(bs)) as mm:
|
||||
mm.write(bs)
|
||||
mm.seek(0)
|
||||
self.assertEqual(docs, decode_all(mm))
|
||||
self.assertEqual(docs, decode_all(array.array('B', bs)))
|
||||
with mmap.mmap(-1, len(bs)) as mm:
|
||||
mm.write(bs)
|
||||
mm.seek(0)
|
||||
self.assertEqual(docs, decode_all(mm))
|
||||
|
||||
def test_decode_buffer_protocol(self):
|
||||
doc = {'foo': 'bar'}
|
||||
@ -321,21 +318,18 @@ class TestBSON(unittest.TestCase):
|
||||
self.assertEqual(doc, decode(bytearray(bs)))
|
||||
self.assertEqual(doc, decode(memoryview(bs)))
|
||||
self.assertEqual(doc, decode(memoryview(b'1' + bs + b'1')[1:-1]))
|
||||
if PY3:
|
||||
import array
|
||||
import mmap
|
||||
self.assertEqual(doc, decode(array.array('B', bs)))
|
||||
with mmap.mmap(-1, len(bs)) as mm:
|
||||
mm.write(bs)
|
||||
mm.seek(0)
|
||||
self.assertEqual(doc, decode(mm))
|
||||
self.assertEqual(doc, decode(array.array('B', bs)))
|
||||
with mmap.mmap(-1, len(bs)) as mm:
|
||||
mm.write(bs)
|
||||
mm.seek(0)
|
||||
self.assertEqual(doc, decode(mm))
|
||||
|
||||
def test_invalid_decodes(self):
|
||||
# Invalid object size (not enough bytes in document for even
|
||||
# an object size of first object.
|
||||
# NOTE: decode_all and decode_iter don't care, not sure if they should?
|
||||
self.assertRaises(InvalidBSON, list,
|
||||
decode_file_iter(StringIO(b"\x1B")))
|
||||
decode_file_iter(BytesIO(b"\x1B")))
|
||||
|
||||
bad_bsons = [
|
||||
# An object size that's too small to even include the object size,
|
||||
@ -366,7 +360,7 @@ class TestBSON(unittest.TestCase):
|
||||
with self.assertRaises(InvalidBSON, msg=msg):
|
||||
list(decode_iter(data))
|
||||
with self.assertRaises(InvalidBSON, msg=msg):
|
||||
list(decode_file_iter(StringIO(data)))
|
||||
list(decode_file_iter(BytesIO(data)))
|
||||
with tempfile.TemporaryFile() as scratch:
|
||||
scratch.write(data)
|
||||
scratch.seek(0, os.SEEK_SET)
|
||||
@ -498,10 +492,7 @@ class TestBSON(unittest.TestCase):
|
||||
# Since `bytes` are stored as Binary you can't use them
|
||||
# as keys in python 3.x. Using binary data as a key makes
|
||||
# no sense in BSON anyway and little sense in python.
|
||||
if PY3:
|
||||
self.assertRaises(InvalidDocument, encode, doc)
|
||||
else:
|
||||
self.assertTrue(encode(doc))
|
||||
self.assertRaises(InvalidDocument, encode, doc)
|
||||
|
||||
def test_datetime_encode_decode(self):
|
||||
# Negative timestamps
|
||||
@ -604,13 +595,6 @@ class TestBSON(unittest.TestCase):
|
||||
self.assertEqual(d, decode(encode(d)))
|
||||
|
||||
def test_bad_encode(self):
|
||||
if not PY3:
|
||||
# Python3 treats this as a unicode string which won't raise
|
||||
# an exception. If we passed the string as bytes instead we
|
||||
# still wouldn't get an error since we store bytes as BSON
|
||||
# binary subtype 0.
|
||||
self.assertRaises(InvalidStringData, encode,
|
||||
{"lalala": '\xf4\xe0\xf0\xe1\xc0 Color Touch'})
|
||||
# Work around what seems like a regression in python 3.5.0.
|
||||
# See http://bugs.python.org/issue25222
|
||||
if sys.version_info[:2] < (3, 5):
|
||||
@ -622,13 +606,13 @@ class TestBSON(unittest.TestCase):
|
||||
self.assertRaises(Exception, encode, evil_data)
|
||||
|
||||
def test_overflow(self):
|
||||
self.assertTrue(encode({"x": long(9223372036854775807)}))
|
||||
self.assertTrue(encode({"x": 9223372036854775807}))
|
||||
self.assertRaises(OverflowError, encode,
|
||||
{"x": long(9223372036854775808)})
|
||||
{"x": 9223372036854775808})
|
||||
|
||||
self.assertTrue(encode({"x": long(-9223372036854775808)}))
|
||||
self.assertTrue(encode({"x": -9223372036854775808}))
|
||||
self.assertRaises(OverflowError, encode,
|
||||
{"x": long(-9223372036854775809)})
|
||||
{"x": -9223372036854775809})
|
||||
|
||||
def test_small_long_encode_decode(self):
|
||||
encoded1 = encode({'x': 256})
|
||||
@ -682,25 +666,10 @@ class TestBSON(unittest.TestCase):
|
||||
# b'a\xe9' == u"aé".encode("iso-8859-1")
|
||||
iso8859_bytes = b'a\xe9'
|
||||
y = {"hello": iso8859_bytes}
|
||||
if PY3:
|
||||
# Stored as BSON binary subtype 0.
|
||||
out = decode(encode(y))
|
||||
self.assertTrue(isinstance(out['hello'], bytes))
|
||||
self.assertEqual(out['hello'], iso8859_bytes)
|
||||
else:
|
||||
# Python 2.
|
||||
try:
|
||||
encode(y)
|
||||
except InvalidStringData as e:
|
||||
self.assertTrue(repr(iso8859_bytes) in str(e))
|
||||
|
||||
# The next two tests only make sense in python 2.x since
|
||||
# you can't use `bytes` type as document keys in python 3.x.
|
||||
x = {u"aéあ".encode("utf-8"): u"aéあ".encode("utf-8")}
|
||||
self.assertEqual(w, decode(encode(x)))
|
||||
|
||||
z = {iso8859_bytes: "hello"}
|
||||
self.assertRaises(InvalidStringData, encode, z)
|
||||
# Stored as BSON binary subtype 0.
|
||||
out = decode(encode(y))
|
||||
self.assertTrue(isinstance(out['hello'], bytes))
|
||||
self.assertEqual(out['hello'], iso8859_bytes)
|
||||
|
||||
def test_null_character(self):
|
||||
doc = {"a": "\x00"}
|
||||
@ -767,24 +736,20 @@ class TestBSON(unittest.TestCase):
|
||||
class _myfloat(float):
|
||||
pass
|
||||
|
||||
class _myunicode(text_type):
|
||||
class _myunicode(str):
|
||||
pass
|
||||
|
||||
d = {'a': _myint(42), 'b': _myfloat(63.9),
|
||||
'c': _myunicode('hello world')
|
||||
}
|
||||
d2 = decode(encode(d))
|
||||
for key, value in iteritems(d2):
|
||||
for key, value in d2.items():
|
||||
orig_value = d[key]
|
||||
orig_type = orig_value.__class__.__bases__[0]
|
||||
self.assertEqual(type(value), orig_type)
|
||||
self.assertEqual(value, orig_type(value))
|
||||
|
||||
def test_ordered_dict(self):
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
raise SkipTest("No OrderedDict")
|
||||
d = OrderedDict([("one", 1), ("two", 2), ("three", 3), ("four", 4)])
|
||||
self.assertEqual(
|
||||
d, decode(encode(d), CodecOptions(document_class=OrderedDict)))
|
||||
|
||||
@ -33,7 +33,6 @@ from bson.decimal128 import Decimal128
|
||||
from bson.dbref import DBRef
|
||||
from bson.errors import InvalidBSON, InvalidId
|
||||
from bson.json_util import JSONMode
|
||||
from bson.py3compat import text_type, b
|
||||
from bson.son import SON
|
||||
|
||||
from test import unittest
|
||||
@ -56,7 +55,7 @@ _NON_PARSE_ERRORS = set([
|
||||
|
||||
_DEPRECATED_BSON_TYPES = {
|
||||
# Symbol
|
||||
'0x0E': text_type,
|
||||
'0x0E': str,
|
||||
# Undefined
|
||||
'0x06': type(None),
|
||||
# DBPointer
|
||||
@ -122,7 +121,7 @@ def create_test(case_spec):
|
||||
encode_extjson = to_extjson
|
||||
encode_bson = to_bson
|
||||
|
||||
cB = binascii.unhexlify(b(valid_case['canonical_bson']))
|
||||
cB = binascii.unhexlify(valid_case['canonical_bson'].encode('utf8'))
|
||||
cEJ = valid_case['canonical_extjson']
|
||||
rEJ = valid_case.get('relaxed_extjson')
|
||||
dEJ = valid_case.get('degenerate_extjson')
|
||||
@ -139,7 +138,7 @@ def create_test(case_spec):
|
||||
if deprecated:
|
||||
if 'converted_bson' in valid_case:
|
||||
converted_bson = binascii.unhexlify(
|
||||
b(valid_case['converted_bson']))
|
||||
valid_case['converted_bson'].encode('utf8'))
|
||||
self.assertEqual(encode_bson(decoded_bson), converted_bson)
|
||||
self.assertJsonEqual(
|
||||
encode_extjson(decode_bson(converted_bson)),
|
||||
@ -167,7 +166,7 @@ def create_test(case_spec):
|
||||
|
||||
# Test round-tripping degenerate bson.
|
||||
if 'degenerate_bson' in valid_case:
|
||||
dB = binascii.unhexlify(b(valid_case['degenerate_bson']))
|
||||
dB = binascii.unhexlify(valid_case['degenerate_bson'].encode('utf8'))
|
||||
self.assertEqual(encode_bson(decode_bson(dB)), cB)
|
||||
|
||||
# Test round-tripping degenerate extended json.
|
||||
@ -186,7 +185,7 @@ def create_test(case_spec):
|
||||
for decode_error_case in case_spec.get('decodeErrors', []):
|
||||
with self.assertRaises(InvalidBSON):
|
||||
decode_bson(
|
||||
binascii.unhexlify(b(decode_error_case['bson'])))
|
||||
binascii.unhexlify(decode_error_case['bson'].encode('utf8')))
|
||||
|
||||
for parse_error_case in case_spec.get('parseErrors', []):
|
||||
if bson_type == '0x13':
|
||||
|
||||
@ -23,7 +23,6 @@ import threading
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from contextlib import contextmanager
|
||||
from itertools import product
|
||||
|
||||
sys.path[0:0] = ['']
|
||||
@ -33,7 +32,6 @@ from bson.binary import (ALL_UUID_REPRESENTATIONS,
|
||||
Binary,
|
||||
STANDARD,
|
||||
PYTHON_LEGACY)
|
||||
from bson.py3compat import iteritems
|
||||
from bson.raw_bson import DEFAULT_RAW_BSON_OPTIONS, RawBSONDocument
|
||||
|
||||
from pymongo import MongoClient
|
||||
@ -1093,7 +1091,7 @@ class TestAllScenarios(unittest.TestCase):
|
||||
def assert_dict_is_subset(self, superdict, subdict):
|
||||
"""Check that subdict is a subset of superdict."""
|
||||
exempt_fields = ["documentKey", "_id", "getMore"]
|
||||
for key, value in iteritems(subdict):
|
||||
for key, value in subdict.items():
|
||||
if key not in superdict:
|
||||
self.fail('Key %s not found in %s' % (key, superdict))
|
||||
if isinstance(value, dict):
|
||||
@ -1111,7 +1109,7 @@ class TestAllScenarios(unittest.TestCase):
|
||||
def check_event(self, event, expectation_dict):
|
||||
if event is None:
|
||||
self.fail()
|
||||
for key, value in iteritems(expectation_dict):
|
||||
for key, value in expectation_dict.items():
|
||||
if isinstance(value, dict):
|
||||
self.assert_dict_is_subset(getattr(event, key), value)
|
||||
else:
|
||||
@ -1149,9 +1147,9 @@ def get_change_stream(client, scenario_def, test):
|
||||
cs_pipeline = test["changeStreamPipeline"]
|
||||
options = test["changeStreamOptions"]
|
||||
cs_options = {}
|
||||
for key, value in iteritems(options):
|
||||
for key, value in options.items():
|
||||
cs_options[camel_to_snake(key)] = value
|
||||
|
||||
|
||||
# Create and return change stream
|
||||
return cs_target.watch(pipeline=cs_pipeline, **cs_options)
|
||||
|
||||
@ -1203,12 +1201,12 @@ def create_test(scenario_def, test):
|
||||
for change, expected_changes in zip(changes, test["result"]["success"]):
|
||||
self.assert_dict_is_subset(change, expected_changes)
|
||||
self.assertEqual(len(changes), len(test["result"]["success"]))
|
||||
|
||||
|
||||
finally:
|
||||
# Check for expected events
|
||||
results = self.listener.results
|
||||
for idx, expectation in enumerate(test.get("expectations", [])):
|
||||
for event_type, event_desc in iteritems(expectation):
|
||||
for event_type, event_desc in expectation.items():
|
||||
results_key = event_type.split("_")[1]
|
||||
event = results[results_key][idx] if len(results[results_key]) > idx else None
|
||||
self.check_event(event, event_desc)
|
||||
|
||||
@ -24,6 +24,7 @@ import socket
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
import _thread as thread
|
||||
import threading
|
||||
import warnings
|
||||
|
||||
@ -31,7 +32,6 @@ sys.path[0:0] = [""]
|
||||
|
||||
from bson import encode
|
||||
from bson.codec_options import CodecOptions, TypeEncoder, TypeRegistry
|
||||
from bson.py3compat import thread
|
||||
from bson.son import SON
|
||||
from bson.tz_util import utc
|
||||
import pymongo
|
||||
@ -90,7 +90,6 @@ from test.utils import (assertRaisesExactly,
|
||||
rs_client,
|
||||
rs_or_single_client,
|
||||
rs_or_single_client_noauth,
|
||||
server_is_master_with_slave,
|
||||
single_client,
|
||||
wait_until)
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
import contextlib
|
||||
import re
|
||||
import sys
|
||||
import threading
|
||||
|
||||
from codecs import utf_8_decode
|
||||
from collections import defaultdict
|
||||
@ -32,7 +31,6 @@ from bson.regex import Regex
|
||||
from bson.code import Code
|
||||
from bson.codec_options import CodecOptions
|
||||
from bson.objectid import ObjectId
|
||||
from bson.py3compat import itervalues
|
||||
from bson.son import SON
|
||||
from pymongo import (ASCENDING, DESCENDING, GEO2D,
|
||||
GEOHAYSTACK, GEOSPHERE, HASHED, TEXT)
|
||||
@ -376,7 +374,7 @@ class TestCollection(IntegrationTest):
|
||||
reindexed = db.test.reindex()
|
||||
if 'raw' in reindexed:
|
||||
# mongos
|
||||
for result in itervalues(reindexed['raw']):
|
||||
for result in reindexed['raw'].values():
|
||||
check_result(result)
|
||||
else:
|
||||
check_result(reindexed)
|
||||
@ -1349,12 +1347,6 @@ class TestCollection(IntegrationTest):
|
||||
self.assertIn('E11000 duplicate key error',
|
||||
str(ctx.exception))
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
# Test unicode(error) conversion.
|
||||
self.assertIn('E11000 duplicate key error',
|
||||
unicode(ctx.exception))
|
||||
|
||||
|
||||
def test_wtimeout(self):
|
||||
# Ensure setting wtimeout doesn't disable write concern altogether.
|
||||
# See SERVER-12596.
|
||||
|
||||
@ -14,14 +14,11 @@
|
||||
|
||||
"""Test the collection module."""
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson.py3compat import iteritems
|
||||
from pymongo import operations, WriteConcern
|
||||
from pymongo.command_cursor import CommandCursor
|
||||
from pymongo.cursor import Cursor
|
||||
@ -35,7 +32,7 @@ from pymongo.operations import (InsertOne,
|
||||
UpdateOne,
|
||||
UpdateMany)
|
||||
|
||||
from test import unittest, client_context, IntegrationTest
|
||||
from test import unittest, IntegrationTest
|
||||
from test.utils import (camel_to_snake, camel_to_upper_camel,
|
||||
camel_to_snake_args, drop_collections, TestCreator)
|
||||
|
||||
@ -113,7 +110,7 @@ def run_operation(collection, test):
|
||||
# PyMongo accepts sort as list of tuples.
|
||||
if arg_name == "sort":
|
||||
sort_dict = arguments[arg_name]
|
||||
arguments[arg_name] = list(iteritems(sort_dict))
|
||||
arguments[arg_name] = list(sort_dict.items())
|
||||
# Named "key" instead not fieldName.
|
||||
if arg_name == "fieldName":
|
||||
arguments["key"] = arguments.pop(arg_name)
|
||||
|
||||
@ -27,7 +27,6 @@ sys.path[0:0] = [""]
|
||||
|
||||
from bson import decode_all
|
||||
from bson.code import Code
|
||||
from bson.py3compat import PY3
|
||||
from bson.son import SON
|
||||
from pymongo import (ASCENDING,
|
||||
DESCENDING,
|
||||
@ -40,7 +39,6 @@ from pymongo.errors import (ConfigurationError,
|
||||
InvalidOperation,
|
||||
OperationFailure)
|
||||
from pymongo.read_concern import ReadConcern
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from test import (client_context,
|
||||
unittest,
|
||||
IntegrationTest)
|
||||
@ -49,9 +47,6 @@ from test.utils import (EventListener,
|
||||
rs_or_single_client,
|
||||
WhiteListEventListener)
|
||||
|
||||
if PY3:
|
||||
long = int
|
||||
|
||||
|
||||
class TestCursor(IntegrationTest):
|
||||
def test_deepcopy_cursor_littered_with_regexes(self):
|
||||
@ -167,7 +162,7 @@ class TestCursor(IntegrationTest):
|
||||
coll.insert_one({"amalia": 2})
|
||||
|
||||
coll.find().max_time_ms(None)
|
||||
coll.find().max_time_ms(long(1))
|
||||
coll.find().max_time_ms(1)
|
||||
|
||||
cursor = coll.find().max_time_ms(999)
|
||||
self.assertEqual(999, cursor._Cursor__max_time_ms)
|
||||
@ -215,7 +210,7 @@ class TestCursor(IntegrationTest):
|
||||
coll.insert_one({"amalia": 2})
|
||||
|
||||
coll.find().max_await_time_ms(None)
|
||||
coll.find().max_await_time_ms(long(1))
|
||||
coll.find().max_await_time_ms(1)
|
||||
|
||||
# When cursor is not tailable_await
|
||||
cursor = coll.find()
|
||||
@ -414,7 +409,7 @@ class TestCursor(IntegrationTest):
|
||||
self.assertRaises(TypeError, db.test.find().limit, None)
|
||||
self.assertRaises(TypeError, db.test.find().limit, "hello")
|
||||
self.assertRaises(TypeError, db.test.find().limit, 5.5)
|
||||
self.assertTrue(db.test.find().limit(long(5)))
|
||||
self.assertTrue(db.test.find().limit(5))
|
||||
|
||||
db.test.drop()
|
||||
db.test.insert_many([{"x": i} for i in range(100)])
|
||||
@ -560,7 +555,7 @@ class TestCursor(IntegrationTest):
|
||||
self.assertRaises(TypeError, db.test.find().batch_size, "hello")
|
||||
self.assertRaises(TypeError, db.test.find().batch_size, 5.5)
|
||||
self.assertRaises(ValueError, db.test.find().batch_size, -1)
|
||||
self.assertTrue(db.test.find().batch_size(long(5)))
|
||||
self.assertTrue(db.test.find().batch_size(5))
|
||||
a = db.test.find()
|
||||
for _ in a:
|
||||
break
|
||||
@ -684,7 +679,7 @@ class TestCursor(IntegrationTest):
|
||||
self.assertRaises(TypeError, db.test.find().skip, "hello")
|
||||
self.assertRaises(TypeError, db.test.find().skip, 5.5)
|
||||
self.assertRaises(ValueError, db.test.find().skip, -5)
|
||||
self.assertTrue(db.test.find().skip(long(5)))
|
||||
self.assertTrue(db.test.find().skip(5))
|
||||
|
||||
db.drop_collection("test")
|
||||
|
||||
@ -1059,7 +1054,7 @@ class TestCursor(IntegrationTest):
|
||||
|
||||
self.assertEqual(5, len(list(self.db.test.find()[20:25])))
|
||||
self.assertEqual(5, len(list(
|
||||
self.db.test.find()[long(20):long(25)])))
|
||||
self.db.test.find()[20:25])))
|
||||
for a, b in zip(count(20), self.db.test.find()[20:25]):
|
||||
self.assertEqual(a, b['i'])
|
||||
|
||||
@ -1104,7 +1099,7 @@ class TestCursor(IntegrationTest):
|
||||
self.assertEqual(50, self.db.test.find()[50]['i'])
|
||||
self.assertEqual(50, self.db.test.find().skip(50)[0]['i'])
|
||||
self.assertEqual(50, self.db.test.find().skip(49)[1]['i'])
|
||||
self.assertEqual(50, self.db.test.find()[long(50)]['i'])
|
||||
self.assertEqual(50, self.db.test.find()[50]['i'])
|
||||
self.assertEqual(99, self.db.test.find()[99]['i'])
|
||||
|
||||
self.assertRaises(IndexError, lambda x: self.db.test.find()[x], -1)
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
import datetime
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from collections import OrderedDict
|
||||
from decimal import Decimal
|
||||
from random import random
|
||||
@ -39,7 +40,6 @@ from bson.codec_options import (CodecOptions, TypeCodec, TypeDecoder,
|
||||
from bson.errors import InvalidDocument
|
||||
from bson.int64 import Int64
|
||||
from bson.raw_bson import RawBSONDocument
|
||||
from bson.py3compat import text_type
|
||||
|
||||
from gridfs import GridIn, GridOut
|
||||
|
||||
@ -110,7 +110,7 @@ UNINT_CODECOPTS = CodecOptions(type_registry=TypeRegistry(
|
||||
|
||||
|
||||
class UppercaseTextDecoder(TypeDecoder):
|
||||
bson_type = text_type
|
||||
bson_type = str
|
||||
def transform_bson(self, value):
|
||||
return value.upper()
|
||||
|
||||
|
||||
@ -21,13 +21,11 @@ import warnings
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson.code import Code
|
||||
from bson.codec_options import CodecOptions
|
||||
from bson.int64 import Int64
|
||||
from bson.regex import Regex
|
||||
from bson.dbref import DBRef
|
||||
from bson.objectid import ObjectId
|
||||
from bson.py3compat import string_type, text_type, PY3
|
||||
from bson.son import SON
|
||||
from pymongo import (ALL,
|
||||
auth,
|
||||
@ -63,10 +61,6 @@ from test.utils import (EventListener,
|
||||
from test.test_custom_types import DECIMAL_CODECOPTS
|
||||
|
||||
|
||||
if PY3:
|
||||
long = int
|
||||
|
||||
|
||||
class TestDatabaseNoConnect(unittest.TestCase):
|
||||
"""Test Database features on a client that does not connect.
|
||||
"""
|
||||
@ -432,10 +426,10 @@ class TestDatabase(IntegrationTest):
|
||||
# These basically clue us in to server changes.
|
||||
self.assertTrue(isinstance(info[0]['responseLength'], int))
|
||||
self.assertTrue(isinstance(info[0]['millis'], int))
|
||||
self.assertTrue(isinstance(info[0]['client'], string_type))
|
||||
self.assertTrue(isinstance(info[0]['user'], string_type))
|
||||
self.assertTrue(isinstance(info[0]['ns'], string_type))
|
||||
self.assertTrue(isinstance(info[0]['op'], string_type))
|
||||
self.assertTrue(isinstance(info[0]['client'], str))
|
||||
self.assertTrue(isinstance(info[0]['user'], str))
|
||||
self.assertTrue(isinstance(info[0]['ns'], str))
|
||||
self.assertTrue(isinstance(info[0]['op'], str))
|
||||
self.assertTrue(isinstance(info[0]["ts"], datetime.datetime))
|
||||
|
||||
@client_context.require_no_mongos
|
||||
@ -513,7 +507,7 @@ class TestDatabase(IntegrationTest):
|
||||
self.assertRaises(TypeError, auth._password_digest, None)
|
||||
|
||||
self.assertTrue(isinstance(auth._password_digest("mike", "password"),
|
||||
text_type))
|
||||
str))
|
||||
self.assertEqual(auth._password_digest("mike", "password"),
|
||||
u"cd7e45b3b2767dc2fa9b6b548457ed00")
|
||||
self.assertEqual(auth._password_digest("mike", "password"),
|
||||
@ -828,7 +822,7 @@ class TestDatabase(IntegrationTest):
|
||||
def test_long(self):
|
||||
db = self.client.pymongo_test
|
||||
db.test.drop()
|
||||
db.test.insert_one({"x": long(9223372036854775807)})
|
||||
db.test.insert_one({"x": 9223372036854775807})
|
||||
retrieved = db.test.find_one()['x']
|
||||
self.assertEqual(Int64(9223372036854775807), retrieved)
|
||||
self.assertIsInstance(retrieved, Int64)
|
||||
|
||||
@ -14,22 +14,14 @@
|
||||
|
||||
"""Tests for Decimal128."""
|
||||
|
||||
import codecs
|
||||
import glob
|
||||
import json
|
||||
import os.path
|
||||
import pickle
|
||||
import sys
|
||||
|
||||
from binascii import unhexlify
|
||||
from decimal import Decimal, DecimalException
|
||||
from decimal import Decimal
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson import BSON
|
||||
from bson.decimal128 import Decimal128, create_decimal128_context
|
||||
from bson.json_util import dumps, loads
|
||||
from bson.py3compat import b
|
||||
from test import client_context, unittest
|
||||
|
||||
class TestDecimal128(unittest.TestCase):
|
||||
|
||||
@ -41,7 +41,6 @@ from test.utils import (assertion_context,
|
||||
cdecimal_patched,
|
||||
CMAPListener,
|
||||
client_context,
|
||||
Barrier,
|
||||
get_pool,
|
||||
HeartbeatEventListener,
|
||||
server_name_to_type,
|
||||
@ -263,7 +262,7 @@ class TestIgnoreStaleErrors(IntegrationTest):
|
||||
|
||||
def test_ignore_stale_connection_errors(self):
|
||||
N_THREADS = 5
|
||||
barrier = Barrier(N_THREADS, timeout=30)
|
||||
barrier = threading.Barrier(N_THREADS, timeout=30)
|
||||
client = rs_or_single_client(minPoolSize=N_THREADS)
|
||||
self.addCleanup(client.close)
|
||||
|
||||
|
||||
@ -31,7 +31,6 @@ from bson.binary import (Binary,
|
||||
STANDARD,
|
||||
UUID_SUBTYPE)
|
||||
from bson.codec_options import CodecOptions
|
||||
from bson.py3compat import _unicode
|
||||
from bson.errors import BSONError
|
||||
from bson.json_util import JSONOptions
|
||||
from bson.son import SON
|
||||
@ -455,7 +454,7 @@ AZURE_CREDS = {
|
||||
|
||||
GCP_CREDS = {
|
||||
'email': os.environ.get('FLE_GCP_EMAIL', ''),
|
||||
'privateKey': _unicode(os.environ.get('FLE_GCP_PRIVATEKEY', ''))}
|
||||
'privateKey': os.environ.get('FLE_GCP_PRIVATEKEY', '')}
|
||||
|
||||
|
||||
class TestSpec(SpecRunner):
|
||||
@ -1307,7 +1306,7 @@ class TestAzureEncryption(AzureGCPEncryptionTestMixin,
|
||||
'AQGVERPgAAAAAAAAAAAAAAAC5DbBSwPwfSlBrDtRuglvNvCXD1KzDuCKY2P+4bRFtHDjpTOE2XuytPAUaAbXf1orsPq59PVZmsbTZbt2CB8qaQ==')
|
||||
|
||||
def test_automatic(self):
|
||||
expected_document_extjson = textwrap.dedent("""
|
||||
expected_document_extjson = textwrap.dedent("""
|
||||
{"secret_azure": {
|
||||
"$binary": {
|
||||
"base64": "AQGVERPgAAAAAAAAAAAAAAAC5DbBSwPwfSlBrDtRuglvNvCXD1KzDuCKY2P+4bRFtHDjpTOE2XuytPAUaAbXf1orsPq59PVZmsbTZbt2CB8qaQ==",
|
||||
@ -1333,7 +1332,7 @@ class TestGCPEncryption(AzureGCPEncryptionTestMixin,
|
||||
'ARgj/gAAAAAAAAAAAAAAAAACwFd+Y5Ojw45GUXNvbcIpN9YkRdoHDHkR4kssdn0tIMKlDQOLFkWFY9X07IRlXsxPD8DcTiKnl6XINK28vhcGlg==')
|
||||
|
||||
def test_automatic(self):
|
||||
expected_document_extjson = textwrap.dedent("""
|
||||
expected_document_extjson = textwrap.dedent("""
|
||||
{"secret_gcp": {
|
||||
"$binary": {
|
||||
"base64": "ARgj/gAAAAAAAAAAAAAAAAACwFd+Y5Ojw45GUXNvbcIpN9YkRdoHDHkR4kssdn0tIMKlDQOLFkWFY9X07IRlXsxPD8DcTiKnl6XINK28vhcGlg==",
|
||||
|
||||
@ -45,10 +45,7 @@ class TestErrors(PyMongoTestCase):
|
||||
self.assertIn("full error", traceback.format_exc())
|
||||
|
||||
def _test_unicode_strs(self, exc):
|
||||
if sys.version_info[0] == 2:
|
||||
self.assertEqual("unicode \xf0\x9f\x90\x8d, full error: {"
|
||||
"'errmsg': u'unicode \\U0001f40d'}", str(exc))
|
||||
elif 'PyPy' in sys.version:
|
||||
if 'PyPy' in sys.version:
|
||||
# PyPy displays unicode in repr differently.
|
||||
self.assertEqual("unicode \U0001f40d, full error: {"
|
||||
"'errmsg': 'unicode \\U0001f40d'}", str(exc))
|
||||
|
||||
@ -20,10 +20,12 @@
|
||||
import datetime
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson.objectid import ObjectId
|
||||
from bson.py3compat import StringIO
|
||||
from gridfs import GridFS
|
||||
from gridfs.grid_file import (DEFAULT_CHUNK_SIZE,
|
||||
_SEEK_CUR,
|
||||
@ -234,7 +236,7 @@ class TestGridFile(IntegrationTest):
|
||||
|
||||
cursor = GridOutCursor(self.db.fs, {})
|
||||
cursor_clone = cursor.clone()
|
||||
|
||||
|
||||
cursor_dict = cursor.__dict__.copy()
|
||||
cursor_dict.pop('_Cursor__session')
|
||||
cursor_clone_dict = cursor_clone.__dict__.copy()
|
||||
@ -301,7 +303,7 @@ class TestGridFile(IntegrationTest):
|
||||
|
||||
five = GridIn(self.db.fs, chunk_size=2)
|
||||
five.write(b"hello")
|
||||
buffer = StringIO(b" world")
|
||||
buffer = BytesIO(b" world")
|
||||
five.write(buffer)
|
||||
five.write(b" and mongodb")
|
||||
five.close()
|
||||
@ -567,7 +569,7 @@ Bye"""))
|
||||
def test_prechunked_string(self):
|
||||
|
||||
def write_me(s, chunk_size):
|
||||
buf = StringIO(s)
|
||||
buf = BytesIO(s)
|
||||
infile = GridIn(self.db.fs)
|
||||
while True:
|
||||
to_write = buf.read(chunk_size)
|
||||
@ -646,7 +648,7 @@ Bye"""))
|
||||
self.assertIn("getMore", listener.started_command_names())
|
||||
|
||||
def test_zip(self):
|
||||
zf = StringIO()
|
||||
zf = BytesIO()
|
||||
z = zipfile.ZipFile(zf, "w")
|
||||
z.writestr("test.txt", b"hello world")
|
||||
z.close()
|
||||
|
||||
@ -16,21 +16,23 @@
|
||||
|
||||
"""Tests for the gridfs package.
|
||||
"""
|
||||
import sys
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
import datetime
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import gridfs
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson.binary import Binary
|
||||
from bson.py3compat import StringIO, string_type
|
||||
from pymongo.mongo_client import MongoClient
|
||||
from pymongo.errors import (ConfigurationError,
|
||||
NotMasterError,
|
||||
ServerSelectionTimeoutError)
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
import gridfs
|
||||
from gridfs.errors import CorruptGridFile, FileExists, NoFile
|
||||
from test import (client_context,
|
||||
unittest,
|
||||
@ -156,7 +158,7 @@ class TestGridfs(IntegrationTest):
|
||||
self.assertEqual(oid, raw["_id"])
|
||||
self.assertTrue(isinstance(raw["uploadDate"], datetime.datetime))
|
||||
self.assertEqual(255 * 1024, raw["chunkSize"])
|
||||
self.assertTrue(isinstance(raw["md5"], string_type))
|
||||
self.assertTrue(isinstance(raw["md5"], str))
|
||||
|
||||
def test_corrupt_chunk(self):
|
||||
files_id = self.fs.put(b'foobar')
|
||||
@ -311,23 +313,38 @@ class TestGridfs(IntegrationTest):
|
||||
time.sleep(0.01)
|
||||
three = self.fs.put(b"baz", filename="test", author="author2")
|
||||
|
||||
self.assertEqual(b"foo", self.fs.get_version(filename="test", author="author1", version=-2).read())
|
||||
self.assertEqual(b"bar", self.fs.get_version(filename="test", author="author1", version=-1).read())
|
||||
self.assertEqual(b"foo", self.fs.get_version(filename="test", author="author1", version=0).read())
|
||||
self.assertEqual(b"bar", self.fs.get_version(filename="test", author="author1", version=1).read())
|
||||
self.assertEqual(b"baz", self.fs.get_version(filename="test", author="author2", version=0).read())
|
||||
self.assertEqual(b"baz", self.fs.get_version(filename="test", version=-1).read())
|
||||
self.assertEqual(b"baz", self.fs.get_version(filename="test", version=2).read())
|
||||
self.assertEqual(
|
||||
b"foo",
|
||||
self.fs.get_version(
|
||||
filename="test", author="author1", version=-2).read())
|
||||
self.assertEqual(
|
||||
b"bar", self.fs.get_version(
|
||||
filename="test", author="author1", version=-1).read())
|
||||
self.assertEqual(
|
||||
b"foo", self.fs.get_version(
|
||||
filename="test", author="author1", version=0).read())
|
||||
self.assertEqual(
|
||||
b"bar", self.fs.get_version(
|
||||
filename="test", author="author1", version=1).read())
|
||||
self.assertEqual(
|
||||
b"baz", self.fs.get_version(
|
||||
filename="test", author="author2", version=0).read())
|
||||
self.assertEqual(
|
||||
b"baz", self.fs.get_version(filename="test", version=-1).read())
|
||||
self.assertEqual(
|
||||
b"baz", self.fs.get_version(filename="test", version=2).read())
|
||||
|
||||
self.assertRaises(NoFile, self.fs.get_version, filename="test", author="author3")
|
||||
self.assertRaises(NoFile, self.fs.get_version, filename="test", author="author1", version=2)
|
||||
self.assertRaises(
|
||||
NoFile, self.fs.get_version, filename="test", author="author3")
|
||||
self.assertRaises(
|
||||
NoFile, self.fs.get_version, filename="test", author="author1", version=2)
|
||||
|
||||
self.fs.delete(one)
|
||||
self.fs.delete(two)
|
||||
self.fs.delete(three)
|
||||
|
||||
def test_put_filelike(self):
|
||||
oid = self.fs.put(StringIO(b"hello world"), chunk_size=1)
|
||||
oid = self.fs.put(BytesIO(b"hello world"), chunk_size=1)
|
||||
self.assertEqual(11, self.db.fs.chunks.count_documents({}))
|
||||
self.assertEqual(b"hello world", self.fs.get(oid).read())
|
||||
|
||||
|
||||
@ -21,13 +21,13 @@ import itertools
|
||||
import threading
|
||||
import time
|
||||
|
||||
import gridfs
|
||||
from io import BytesIO
|
||||
|
||||
from bson.binary import Binary
|
||||
from bson.int64 import Int64
|
||||
from bson.objectid import ObjectId
|
||||
from bson.py3compat import StringIO, string_type
|
||||
from bson.son import SON
|
||||
import gridfs
|
||||
from gridfs.errors import NoFile, CorruptGridFile
|
||||
from pymongo.errors import (ConfigurationError,
|
||||
NotMasterError,
|
||||
@ -131,7 +131,7 @@ class TestGridfs(IntegrationTest):
|
||||
self.assertEqual(oid, raw["_id"])
|
||||
self.assertTrue(isinstance(raw["uploadDate"], datetime.datetime))
|
||||
self.assertEqual(255 * 1024, raw["chunkSize"])
|
||||
self.assertTrue(isinstance(raw["md5"], string_type))
|
||||
self.assertTrue(isinstance(raw["md5"], str))
|
||||
|
||||
def test_corrupt_chunk(self):
|
||||
files_id = self.fs.upload_from_stream("test_filename",
|
||||
@ -293,7 +293,7 @@ class TestGridfs(IntegrationTest):
|
||||
|
||||
def test_upload_from_stream(self):
|
||||
oid = self.fs.upload_from_stream("test_file",
|
||||
StringIO(b"hello world"),
|
||||
BytesIO(b"hello world"),
|
||||
chunk_size_bytes=1)
|
||||
self.assertEqual(11, self.db.fs.chunks.count_documents({}))
|
||||
self.assertEqual(b"hello world",
|
||||
@ -303,7 +303,7 @@ class TestGridfs(IntegrationTest):
|
||||
oid = ObjectId()
|
||||
self.fs.upload_from_stream_with_id(oid,
|
||||
"test_file_custom_id",
|
||||
StringIO(b"custom id"),
|
||||
BytesIO(b"custom id"),
|
||||
chunk_size_bytes=1)
|
||||
self.assertEqual(b"custom id",
|
||||
self.fs.open_download_stream(oid).read())
|
||||
@ -416,11 +416,11 @@ class TestGridfs(IntegrationTest):
|
||||
{"files_id": gin._id}))
|
||||
|
||||
def test_download_to_stream(self):
|
||||
file1 = StringIO(b"hello world")
|
||||
file1 = BytesIO(b"hello world")
|
||||
# Test with one chunk.
|
||||
oid = self.fs.upload_from_stream("one_chunk", file1)
|
||||
self.assertEqual(1, self.db.fs.chunks.count_documents({}))
|
||||
file2 = StringIO()
|
||||
file2 = BytesIO()
|
||||
self.fs.download_to_stream(oid, file2)
|
||||
file1.seek(0)
|
||||
file2.seek(0)
|
||||
@ -434,18 +434,18 @@ class TestGridfs(IntegrationTest):
|
||||
file1,
|
||||
chunk_size_bytes=1)
|
||||
self.assertEqual(11, self.db.fs.chunks.count_documents({}))
|
||||
file2 = StringIO()
|
||||
file2 = BytesIO()
|
||||
self.fs.download_to_stream(oid, file2)
|
||||
file1.seek(0)
|
||||
file2.seek(0)
|
||||
self.assertEqual(file1.read(), file2.read())
|
||||
|
||||
def test_download_to_stream_by_name(self):
|
||||
file1 = StringIO(b"hello world")
|
||||
file1 = BytesIO(b"hello world")
|
||||
# Test with one chunk.
|
||||
oid = self.fs.upload_from_stream("one_chunk", file1)
|
||||
self.assertEqual(1, self.db.fs.chunks.count_documents({}))
|
||||
file2 = StringIO()
|
||||
file2 = BytesIO()
|
||||
self.fs.download_to_stream_by_name("one_chunk", file2)
|
||||
file1.seek(0)
|
||||
file2.seek(0)
|
||||
@ -458,7 +458,7 @@ class TestGridfs(IntegrationTest):
|
||||
self.fs.upload_from_stream("many_chunks", file1, chunk_size_bytes=1)
|
||||
self.assertEqual(11, self.db.fs.chunks.count_documents({}))
|
||||
|
||||
file2 = StringIO()
|
||||
file2 = BytesIO()
|
||||
self.fs.download_to_stream_by_name("many_chunks", file2)
|
||||
file1.seek(0)
|
||||
file2.seek(0)
|
||||
|
||||
@ -13,22 +13,21 @@
|
||||
# limitations under the License.
|
||||
|
||||
"""Test GridFSBucket class."""
|
||||
|
||||
import copy
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import sys
|
||||
|
||||
from json import loads
|
||||
|
||||
import gridfs
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson import Binary
|
||||
from bson.int64 import Int64
|
||||
from bson.json_util import object_hook
|
||||
from bson.py3compat import bytes_from_hex
|
||||
import gridfs
|
||||
from gridfs.errors import NoFile, CorruptGridFile
|
||||
from test import (unittest,
|
||||
IntegrationTest)
|
||||
@ -210,7 +209,7 @@ def create_tests():
|
||||
for key, val in jsn.items():
|
||||
if key in ("data", "source", "result"):
|
||||
if "$hex" in val:
|
||||
jsn[key] = Binary(bytes_from_hex(val['$hex']))
|
||||
jsn[key] = Binary(bytes.fromhex(val['$hex']))
|
||||
if isinstance(jsn[key], dict):
|
||||
str2hex(jsn[key])
|
||||
if isinstance(jsn[key], list):
|
||||
|
||||
@ -39,8 +39,6 @@ from bson.tz_util import FixedOffset, utc
|
||||
|
||||
from test import unittest, IntegrationTest
|
||||
|
||||
PY3 = sys.version_info[0] == 3
|
||||
|
||||
|
||||
class TestJsonUtil(unittest.TestCase):
|
||||
def round_tripped(self, doc, **kwargs):
|
||||
@ -336,10 +334,7 @@ class TestJsonUtil(unittest.TestCase):
|
||||
doc, json_util.loads(ext_json_str, json_options=options))
|
||||
|
||||
def test_binary(self):
|
||||
if PY3:
|
||||
bin_type_dict = {"bin": b"\x00\x01\x02\x03\x04"}
|
||||
else:
|
||||
bin_type_dict = {"bin": Binary(b"\x00\x01\x02\x03\x04")}
|
||||
bin_type_dict = {"bin": b"\x00\x01\x02\x03\x04"}
|
||||
md5_type_dict = {
|
||||
"md5": Binary(b' n7\x18\xaf\t/\xd1\xd1/\x80\xca\xe7q\xcc\xac',
|
||||
MD5_SUBTYPE)}
|
||||
@ -352,10 +347,7 @@ class TestJsonUtil(unittest.TestCase):
|
||||
# Binary with subtype 0 is decoded into bytes in Python 3.
|
||||
bin = json_util.loads(
|
||||
'{"bin": {"$binary": "AAECAwQ=", "$type": "00"}}')['bin']
|
||||
if PY3:
|
||||
self.assertEqual(type(bin), bytes)
|
||||
else:
|
||||
self.assertEqual(type(bin), Binary)
|
||||
self.assertEqual(type(bin), bytes)
|
||||
|
||||
# PYTHON-443 ensure old type formats are supported
|
||||
json_bin_dump = json_util.dumps(bin_type_dict)
|
||||
|
||||
@ -19,7 +19,6 @@ import sys
|
||||
import threading
|
||||
import time
|
||||
import uuid
|
||||
import warnings
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
@ -27,14 +26,11 @@ from bson.binary import PYTHON_LEGACY, STANDARD
|
||||
from bson.code import Code
|
||||
from bson.codec_options import CodecOptions
|
||||
from bson.objectid import ObjectId
|
||||
from bson.py3compat import string_type
|
||||
from bson.son import SON
|
||||
from pymongo import ASCENDING, DESCENDING, GEOHAYSTACK
|
||||
from pymongo.database import Database
|
||||
from pymongo.common import partition_node
|
||||
from pymongo.errors import (BulkWriteError,
|
||||
ConfigurationError,
|
||||
CursorNotFound,
|
||||
DocumentTooLarge,
|
||||
DuplicateKeyError,
|
||||
InvalidDocument,
|
||||
@ -42,7 +38,6 @@ from pymongo.errors import (BulkWriteError,
|
||||
OperationFailure,
|
||||
WriteConcernError,
|
||||
WTimeoutError)
|
||||
from pymongo.message import _CursorAddress
|
||||
from pymongo.operations import IndexModel
|
||||
from pymongo.son_manipulator import (AutoReference,
|
||||
NamespaceInjector,
|
||||
@ -143,14 +138,8 @@ class TestLegacy(IntegrationTest):
|
||||
self.assertEqual(doc["_id"], _id)
|
||||
self.assertTrue(isinstance(_id, ObjectId))
|
||||
|
||||
doc_class = dict
|
||||
# Work around http://bugs.jython.org/issue1728
|
||||
if (sys.platform.startswith('java') and
|
||||
sys.version_info[:3] >= (2, 5, 2)):
|
||||
doc_class = SON
|
||||
|
||||
db = self.client.get_database(
|
||||
db.name, codec_options=CodecOptions(document_class=doc_class))
|
||||
db.name, codec_options=CodecOptions(document_class=dict))
|
||||
|
||||
def remove_insert_find_one(doc):
|
||||
db.test.remove({})
|
||||
@ -2315,7 +2304,7 @@ class TestLegacyBulkWriteConcern(BulkTestBase):
|
||||
|
||||
failed = result['writeConcernErrors'][0]
|
||||
self.assertEqual(64, failed['code'])
|
||||
self.assertTrue(isinstance(failed['errmsg'], string_type))
|
||||
self.assertTrue(isinstance(failed['errmsg'], str))
|
||||
|
||||
self.coll.delete_many({})
|
||||
self.coll.create_index('a', unique=True)
|
||||
@ -2413,12 +2402,12 @@ class TestLegacyBulkWriteConcern(BulkTestBase):
|
||||
failed = result['writeErrors'][0]
|
||||
self.assertEqual(2, failed['index'])
|
||||
self.assertEqual(11000, failed['code'])
|
||||
self.assertTrue(isinstance(failed['errmsg'], string_type))
|
||||
self.assertTrue(isinstance(failed['errmsg'], str))
|
||||
self.assertEqual(1, failed['op']['a'])
|
||||
|
||||
failed = result['writeConcernErrors'][0]
|
||||
self.assertEqual(64, failed['code'])
|
||||
self.assertTrue(isinstance(failed['errmsg'], string_type))
|
||||
self.assertTrue(isinstance(failed['errmsg'], str))
|
||||
|
||||
upserts = result['upserted']
|
||||
self.assertEqual(1, len(upserts))
|
||||
|
||||
@ -21,7 +21,6 @@ import warnings
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson.objectid import ObjectId
|
||||
from bson.py3compat import text_type
|
||||
from bson.son import SON
|
||||
from pymongo import CursorType, monitoring, InsertOne, UpdateOne, DeleteOne
|
||||
from pymongo.command_cursor import CommandCursor
|
||||
@ -37,10 +36,8 @@ from test import (client_context,
|
||||
unittest)
|
||||
from test.utils import (EventListener,
|
||||
get_pool,
|
||||
ignore_deprecations,
|
||||
rs_or_single_client,
|
||||
single_client,
|
||||
wait_until)
|
||||
single_client)
|
||||
|
||||
|
||||
class TestCommandMonitoring(PyMongoTestCase):
|
||||
@ -821,7 +818,7 @@ class TestCommandMonitoring(PyMongoTestCase):
|
||||
error = errors[0]
|
||||
self.assertEqual(0, error.get('index'))
|
||||
self.assertIsInstance(error.get('code'), int)
|
||||
self.assertIsInstance(error.get('errmsg'), text_type)
|
||||
self.assertIsInstance(error.get('errmsg'), str)
|
||||
|
||||
def test_legacy_writes(self):
|
||||
with warnings.catch_warnings():
|
||||
|
||||
@ -23,7 +23,6 @@ sys.path[0:0] = [""]
|
||||
|
||||
from bson.errors import InvalidId
|
||||
from bson.objectid import ObjectId, _MAX_COUNTER_VALUE
|
||||
from bson.py3compat import PY3, _unicode
|
||||
from bson.tz_util import (FixedOffset,
|
||||
utc)
|
||||
from test import SkipTest, unittest
|
||||
@ -50,7 +49,7 @@ class TestObjectId(unittest.TestCase):
|
||||
|
||||
def test_unicode(self):
|
||||
a = ObjectId()
|
||||
self.assertEqual(a, ObjectId(_unicode(a)))
|
||||
self.assertEqual(a, ObjectId(a))
|
||||
self.assertEqual(ObjectId("123456789012123456789012"),
|
||||
ObjectId(u"123456789012123456789012"))
|
||||
self.assertRaises(InvalidId, ObjectId, u"hello")
|
||||
@ -139,13 +138,9 @@ class TestObjectId(unittest.TestCase):
|
||||
b"object\np2\nNtp3\nRp4\n"
|
||||
b"S'M\\x9afV\\x13v\\xc0\\x0b\\x88\\x00\\x00\\x00'\np5\nb.")
|
||||
|
||||
if PY3:
|
||||
# Have to load using 'latin-1' since these were pickled in python2.x.
|
||||
oid_1_9 = pickle.loads(pickled_with_1_9, encoding='latin-1')
|
||||
oid_1_10 = pickle.loads(pickled_with_1_10, encoding='latin-1')
|
||||
else:
|
||||
oid_1_9 = pickle.loads(pickled_with_1_9)
|
||||
oid_1_10 = pickle.loads(pickled_with_1_10)
|
||||
# Have to load using 'latin-1' since these were pickled in python2.x.
|
||||
oid_1_9 = pickle.loads(pickled_with_1_9, encoding='latin-1')
|
||||
oid_1_10 = pickle.loads(pickled_with_1_10, encoding='latin-1')
|
||||
|
||||
self.assertEqual(oid_1_9, ObjectId("4d9a66561376c00b88000000"))
|
||||
self.assertEqual(oid_1_9, oid_1_10)
|
||||
|
||||
@ -23,7 +23,6 @@ import warnings
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson.py3compat import MAXSIZE
|
||||
from bson.son import SON
|
||||
from pymongo.errors import ConfigurationError, OperationFailure
|
||||
from pymongo.message import _maybe_add_read_preference
|
||||
@ -430,7 +429,7 @@ class TestCommandAndReadPreference(IntegrationTest):
|
||||
# the collection already exists.
|
||||
self._test_primary_helper(
|
||||
lambda: self.c.pymongo_test.create_collection(
|
||||
'some_collection%s' % random.randint(0, MAXSIZE)))
|
||||
'some_collection%s' % random.randint(0, sys.maxsize)))
|
||||
|
||||
@client_context.require_version_max(4, 1, 0, -1)
|
||||
def test_group(self):
|
||||
|
||||
@ -18,8 +18,9 @@ import copy
|
||||
import os
|
||||
import sys
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
from bson import DBRef
|
||||
from bson.py3compat import StringIO
|
||||
from gridfs import GridFS, GridFSBucket
|
||||
from pymongo import ASCENDING, InsertOne, IndexModel, OFF, monitoring
|
||||
from pymongo.common import _MAX_END_SESSIONS
|
||||
@ -465,7 +466,7 @@ class TestSession(IntegrationTest):
|
||||
for f in files:
|
||||
f.read()
|
||||
|
||||
sio = StringIO()
|
||||
sio = BytesIO()
|
||||
|
||||
self._test_ops(
|
||||
client,
|
||||
|
||||
@ -21,9 +21,8 @@ import sys
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson.py3compat import b
|
||||
from bson.son import SON
|
||||
from test import SkipTest, unittest
|
||||
from test import unittest
|
||||
|
||||
|
||||
class TestSON(unittest.TestCase):
|
||||
@ -107,11 +106,10 @@ class TestSON(unittest.TestCase):
|
||||
def test_pickle_backwards_compatability(self):
|
||||
# This string was generated by pickling a SON object in pymongo
|
||||
# version 2.1.1
|
||||
pickled_with_2_1_1 = b(
|
||||
pickled_with_2_1_1 = (
|
||||
"ccopy_reg\n_reconstructor\np0\n(cbson.son\nSON\np1\n"
|
||||
"c__builtin__\ndict\np2\n(dp3\ntp4\nRp5\n(dp6\n"
|
||||
"S'_SON__keys'\np7\n(lp8\nsb."
|
||||
)
|
||||
"S'_SON__keys'\np7\n(lp8\nsb.").encode('utf8')
|
||||
son_2_1_1 = pickle.loads(pickled_with_2_1_1)
|
||||
self.assertEqual(son_2_1_1, SON([]))
|
||||
|
||||
|
||||
@ -450,9 +450,6 @@ class TestSSL(IntegrationTest):
|
||||
if sys.platform == "win32":
|
||||
raise SkipTest("Can't test system ca certs on Windows.")
|
||||
|
||||
if sys.version_info < (2, 7, 9):
|
||||
raise SkipTest("Can't load system CA certificates.")
|
||||
|
||||
if (ssl.OPENSSL_VERSION.lower().startswith('libressl') and
|
||||
sys.platform == 'darwin' and not _ssl.IS_PYOPENSSL):
|
||||
raise SkipTest(
|
||||
|
||||
@ -18,7 +18,6 @@ import sys
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson.py3compat import imap
|
||||
from pymongo import common
|
||||
from pymongo.read_preferences import ReadPreference, Secondary
|
||||
from pymongo.server_type import SERVER_TYPE
|
||||
@ -52,7 +51,7 @@ def create_mock_topology(
|
||||
seeds=None,
|
||||
replica_set_name=None,
|
||||
monitor_class=DummyMonitor):
|
||||
partitioned_seeds = list(imap(common.partition_node, seeds or ['a']))
|
||||
partitioned_seeds = list(map(common.partition_node, seeds or ['a']))
|
||||
topology_settings = TopologySettings(
|
||||
partitioned_seeds,
|
||||
replica_set_name=replica_set_name,
|
||||
|
||||
@ -17,9 +17,9 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
from io import BytesIO
|
||||
|
||||
from bson.py3compat import StringIO
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from pymongo import client_session, WriteConcern
|
||||
from pymongo.client_session import TransactionOptions
|
||||
@ -270,8 +270,8 @@ class TestTransactions(TransactionsBase):
|
||||
(gfs.exists, ()),
|
||||
(gridfs_open_upload_stream, ('name',)),
|
||||
(bucket.upload_from_stream, ('name', b'data',)),
|
||||
(bucket.download_to_stream, (1, StringIO(),)),
|
||||
(bucket.download_to_stream_by_name, ('name', StringIO(),)),
|
||||
(bucket.download_to_stream, (1, BytesIO(),)),
|
||||
(bucket.download_to_stream_by_name, ('name', BytesIO(),)),
|
||||
(bucket.delete, (1,)),
|
||||
(bucket.find, ()),
|
||||
(bucket.open_download_stream, (1,)),
|
||||
|
||||
@ -26,7 +26,6 @@ except ImportError:
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson.binary import JAVA_LEGACY
|
||||
from bson.py3compat import string_type, _unicode
|
||||
from pymongo import ReadPreference
|
||||
from pymongo.errors import ConfigurationError, InvalidURI
|
||||
from pymongo.uri_parser import (parse_userinfo,
|
||||
@ -169,7 +168,7 @@ class TestURI(unittest.TestCase):
|
||||
split_options('connectTimeoutMS=0.1'))
|
||||
self.assertTrue(split_options('connectTimeoutMS=300'))
|
||||
self.assertTrue(isinstance(split_options('w=5')['w'], int))
|
||||
self.assertTrue(isinstance(split_options('w=5.5')['w'], string_type))
|
||||
self.assertTrue(isinstance(split_options('w=5.5')['w'], str))
|
||||
self.assertTrue(split_options('w=foo'))
|
||||
self.assertTrue(split_options('w=majority'))
|
||||
self.assertTrue(split_options('wtimeoutms=500'))
|
||||
|
||||
@ -4,7 +4,6 @@ sys.path[0:0] = [""]
|
||||
|
||||
from bson import encode
|
||||
from bson.errors import InvalidStringData
|
||||
from bson.py3compat import PY3
|
||||
from test import unittest
|
||||
|
||||
class TestUTF8(unittest.TestCase):
|
||||
@ -26,51 +25,5 @@ class TestUTF8(unittest.TestCase):
|
||||
|
||||
self.assertEqual(py_is_legal, bson_is_legal, data)
|
||||
|
||||
@unittest.skipIf(PY3, "python3 has strong separation between bytes/unicode")
|
||||
def test_legal_utf8_full_coverage(self):
|
||||
# This test takes 400 seconds. Which is too long to run each time.
|
||||
# However it is the only one which covers all possible bit combinations
|
||||
# in the 244 space.
|
||||
b1 = chr(0xf4)
|
||||
|
||||
for b2 in map(chr, range(255)):
|
||||
m2 = b1 + b2
|
||||
self._assert_same_utf8_validation(m2)
|
||||
|
||||
for b3 in map(chr, range(255)):
|
||||
m3 = m2 + b3
|
||||
self._assert_same_utf8_validation(m3)
|
||||
|
||||
for b4 in map(chr, range(255)):
|
||||
m4 = m3 + b4
|
||||
self._assert_same_utf8_validation(m4)
|
||||
|
||||
# In python3:
|
||||
# - 'bytes' are not checked with isLegalutf
|
||||
# - 'unicode' We cannot create unicode objects with invalid utf8, since it
|
||||
# would result in non valid code-points.
|
||||
@unittest.skipIf(PY3, "python3 has strong separation between bytes/unicode")
|
||||
def test_legal_utf8_few_samples(self):
|
||||
good_samples = [
|
||||
'\xf4\x80\x80\x80',
|
||||
'\xf4\x8a\x80\x80',
|
||||
'\xf4\x8e\x80\x80',
|
||||
'\xf4\x81\x80\x80',
|
||||
]
|
||||
|
||||
for data in good_samples:
|
||||
self._assert_same_utf8_validation(data)
|
||||
|
||||
bad_samples = [
|
||||
'\xf4\x00\x80\x80',
|
||||
'\xf4\x3a\x80\x80',
|
||||
'\xf4\x7f\x80\x80',
|
||||
'\xf4\x90\x80\x80',
|
||||
'\xf4\xff\x80\x80',
|
||||
]
|
||||
|
||||
for data in bad_samples:
|
||||
self._assert_same_utf8_validation(data)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@ -25,10 +25,11 @@ import re
|
||||
import sys
|
||||
import types
|
||||
|
||||
from collections import abc
|
||||
|
||||
from bson import json_util, Code, Decimal128, DBRef, SON, Int64, MaxKey, MinKey
|
||||
from bson.binary import Binary
|
||||
from bson.objectid import ObjectId
|
||||
from bson.py3compat import abc, integer_types, iteritems, text_type, PY3
|
||||
from bson.regex import Regex, RE_TYPE
|
||||
|
||||
from gridfs import GridFSBucket
|
||||
@ -182,7 +183,7 @@ class EntityMapUtil(object):
|
||||
item,))
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if not isinstance(key, text_type):
|
||||
if not isinstance(key, str):
|
||||
self._test_class.fail(
|
||||
'Expected entity name of type str, got %s' % (type(key)))
|
||||
|
||||
@ -197,7 +198,7 @@ class EntityMapUtil(object):
|
||||
"Entity spec %s did not contain exactly one top-level key" % (
|
||||
entity_spec,))
|
||||
|
||||
entity_type, spec = next(iteritems(entity_spec))
|
||||
entity_type, spec = next(iter(entity_spec.items()))
|
||||
if entity_type == 'client':
|
||||
kwargs = {}
|
||||
observe_events = spec.get('observeEvents', [])
|
||||
@ -298,21 +299,16 @@ class EntityMapUtil(object):
|
||||
return self._session_lsids[session_name]
|
||||
|
||||
|
||||
if not PY3:
|
||||
binary_types = (Binary,)
|
||||
long_types = (Int64, long)
|
||||
unicode_type = unicode
|
||||
else:
|
||||
binary_types = (Binary, bytes)
|
||||
long_types = (Int64,)
|
||||
unicode_type = str
|
||||
binary_types = (Binary, bytes)
|
||||
long_types = (Int64,)
|
||||
unicode_type = str
|
||||
|
||||
|
||||
BSON_TYPE_ALIAS_MAP = {
|
||||
# https://docs.mongodb.com/manual/reference/operator/query/type/
|
||||
# https://pymongo.readthedocs.io/en/stable/api/bson/index.html
|
||||
'double': (float,),
|
||||
'string': (text_type,),
|
||||
'string': (str,),
|
||||
'object': (abc.Mapping,),
|
||||
'array': (abc.MutableSequence,),
|
||||
'binData': binary_types,
|
||||
@ -421,11 +417,11 @@ class MatchEvaluatorUtil(object):
|
||||
else:
|
||||
nested = expectation[key_to_compare]
|
||||
if isinstance(nested, abc.Mapping) and len(nested) == 1:
|
||||
opname, spec = next(iteritems(nested))
|
||||
opname, spec = next(iter(nested.items()))
|
||||
if opname.startswith('$$'):
|
||||
is_special_op = True
|
||||
elif len(expectation) == 1:
|
||||
opname, spec = next(iteritems(expectation))
|
||||
opname, spec = next(iter(expectation.items()))
|
||||
if opname.startswith('$$'):
|
||||
is_special_op = True
|
||||
key_to_compare = None
|
||||
@ -445,7 +441,7 @@ class MatchEvaluatorUtil(object):
|
||||
return
|
||||
|
||||
self._test_class.assertIsInstance(actual, abc.Mapping)
|
||||
for key, value in iteritems(expectation):
|
||||
for key, value in expectation.items():
|
||||
if self._evaluate_if_special_operation(expectation, actual, key):
|
||||
continue
|
||||
|
||||
@ -473,7 +469,7 @@ class MatchEvaluatorUtil(object):
|
||||
return
|
||||
|
||||
# account for flexible numerics in element-wise comparison
|
||||
if (isinstance(expectation, integer_types) or
|
||||
if (isinstance(expectation, int) or
|
||||
isinstance(expectation, float)):
|
||||
self._test_class.assertEqual(expectation, actual)
|
||||
else:
|
||||
@ -481,7 +477,7 @@ class MatchEvaluatorUtil(object):
|
||||
self._test_class.assertEqual(expectation, actual)
|
||||
|
||||
def match_event(self, expectation, actual):
|
||||
event_type, spec = next(iteritems(expectation))
|
||||
event_type, spec = next(iter(expectation.items()))
|
||||
|
||||
# every event type has the commandName field
|
||||
command_name = spec.get('commandName')
|
||||
|
||||
@ -30,18 +30,16 @@ import warnings
|
||||
from collections import defaultdict
|
||||
from functools import partial
|
||||
|
||||
from bson import json_util, py3compat
|
||||
from bson import json_util
|
||||
from bson.objectid import ObjectId
|
||||
from bson.py3compat import iteritems, string_type
|
||||
from bson.son import SON
|
||||
|
||||
from pymongo import (MongoClient,
|
||||
monitoring, operations, read_preferences)
|
||||
from pymongo.collection import ReturnDocument
|
||||
from pymongo.errors import ConfigurationError, OperationFailure
|
||||
from pymongo.monitoring import _SENSITIVE_COMMANDS, ConnectionPoolListener
|
||||
from pymongo.pool import (_CancellationContext,
|
||||
PoolOptions)
|
||||
from pymongo.monitoring import _SENSITIVE_COMMANDS
|
||||
from pymongo.pool import _CancellationContext
|
||||
from pymongo.read_concern import ReadConcern
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from pymongo.server_selectors import (any_server_selector,
|
||||
@ -53,12 +51,6 @@ from test import (client_context,
|
||||
db_user,
|
||||
db_pwd)
|
||||
|
||||
if sys.version_info[0] < 3:
|
||||
# Python 2.7, use our backport.
|
||||
from test.barrier import Barrier
|
||||
else:
|
||||
from threading import Barrier
|
||||
|
||||
|
||||
IMPOSSIBLE_WRITE_CONCERN = WriteConcern(w=50)
|
||||
|
||||
@ -289,7 +281,7 @@ class ScenarioDict(dict):
|
||||
def convert(v):
|
||||
if isinstance(v, collections.Mapping):
|
||||
return ScenarioDict(v)
|
||||
if isinstance(v, (py3compat.string_type, bytes)):
|
||||
if isinstance(v, (str, bytes)):
|
||||
return v
|
||||
if isinstance(v, collections.Sequence):
|
||||
return [convert(item) for item in v]
|
||||
@ -974,7 +966,8 @@ def assertion_context(msg):
|
||||
yield
|
||||
except AssertionError as exc:
|
||||
msg = '%s (%s)' % (exc, msg)
|
||||
py3compat.reraise(type(exc), msg, sys.exc_info()[2])
|
||||
exc_type, exc_val, exc_tb = sys.exc_info()
|
||||
raise exc_type(exc_val).with_traceback(exc_tb)
|
||||
|
||||
|
||||
def parse_spec_options(opts):
|
||||
@ -998,8 +991,8 @@ def parse_spec_options(opts):
|
||||
|
||||
if 'hint' in opts:
|
||||
hint = opts.pop('hint')
|
||||
if not isinstance(hint, string_type):
|
||||
hint = list(iteritems(hint))
|
||||
if not isinstance(hint, str):
|
||||
hint = list(hint.items())
|
||||
opts['hint'] = hint
|
||||
|
||||
# Properly format 'hint' arguments for the Bulk API tests.
|
||||
@ -1011,17 +1004,17 @@ def parse_spec_options(opts):
|
||||
args = req.pop('arguments', {})
|
||||
if 'hint' in args:
|
||||
hint = args.pop('hint')
|
||||
if not isinstance(hint, string_type):
|
||||
hint = list(iteritems(hint))
|
||||
if not isinstance(hint, str):
|
||||
hint = list(hint.items())
|
||||
args['hint'] = hint
|
||||
req['arguments'] = args
|
||||
else:
|
||||
# Unified test format
|
||||
bulk_model, spec = next(iteritems(req))
|
||||
bulk_model, spec = next(iter(req.items()))
|
||||
if 'hint' in spec:
|
||||
hint = spec.pop('hint')
|
||||
if not isinstance(hint, string_type):
|
||||
hint = list(iteritems(hint))
|
||||
if not isinstance(hint, str):
|
||||
hint = list(hint.items())
|
||||
spec['hint'] = hint
|
||||
opts['requests'] = reqs
|
||||
|
||||
@ -1035,7 +1028,7 @@ def prepare_spec_arguments(spec, arguments, opname, entity_map,
|
||||
# PyMongo accepts sort as list of tuples.
|
||||
if arg_name == "sort":
|
||||
sort_dict = arguments[arg_name]
|
||||
arguments[arg_name] = list(iteritems(sort_dict))
|
||||
arguments[arg_name] = list(sort_dict.items())
|
||||
# Named "key" instead not fieldName.
|
||||
if arg_name == "fieldName":
|
||||
arguments["key"] = arguments.pop(arg_name)
|
||||
@ -1057,7 +1050,7 @@ def prepare_spec_arguments(spec, arguments, opname, entity_map,
|
||||
bulk_arguments = camel_to_snake_args(request["arguments"])
|
||||
else:
|
||||
# Unified test format
|
||||
bulk_model, spec = next(iteritems(request))
|
||||
bulk_model, spec = next(iter(request.items()))
|
||||
bulk_class = getattr(operations, camel_to_upper_camel(bulk_model))
|
||||
bulk_arguments = camel_to_snake_args(spec)
|
||||
requests.append(bulk_class(**dict(bulk_arguments)))
|
||||
|
||||
@ -14,23 +14,20 @@
|
||||
|
||||
"""Utilities for testing driver specs."""
|
||||
|
||||
import copy
|
||||
import functools
|
||||
import threading
|
||||
|
||||
from collections import abc
|
||||
|
||||
from bson import decode, encode
|
||||
from bson.binary import Binary, STANDARD
|
||||
from bson.codec_options import CodecOptions
|
||||
from bson.int64 import Int64
|
||||
from bson.py3compat import iteritems, abc, string_type, text_type
|
||||
from bson.son import SON
|
||||
|
||||
from gridfs import GridFSBucket
|
||||
|
||||
from pymongo import (client_session,
|
||||
helpers,
|
||||
operations)
|
||||
from pymongo import client_session
|
||||
from pymongo.command_cursor import CommandCursor
|
||||
from pymongo.cursor import Cursor
|
||||
from pymongo.errors import (BulkWriteError,
|
||||
@ -43,20 +40,16 @@ from pymongo.write_concern import WriteConcern
|
||||
|
||||
from test import (client_context,
|
||||
client_knobs,
|
||||
IntegrationTest,
|
||||
unittest)
|
||||
IntegrationTest)
|
||||
from test.utils import (camel_to_snake,
|
||||
camel_to_snake_args,
|
||||
camel_to_upper_camel,
|
||||
CompareType,
|
||||
CMAPListener,
|
||||
OvertCommandListener,
|
||||
parse_spec_options,
|
||||
parse_read_preference,
|
||||
prepare_spec_arguments,
|
||||
rs_client,
|
||||
ServerAndTopologyEventListener,
|
||||
HeartbeatEventListener)
|
||||
ServerAndTopologyEventListener)
|
||||
|
||||
|
||||
class SpecRunnerThread(threading.Thread):
|
||||
@ -594,7 +587,7 @@ def expect_any_error(op):
|
||||
|
||||
def expect_error_message(expected_result):
|
||||
if isinstance(expected_result, dict):
|
||||
return isinstance(expected_result['errorContains'], text_type)
|
||||
return isinstance(expected_result['errorContains'], str)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user