PYTHON-673 - Use bytes and remove binary_type

The binary_type alias was added to support python
2.4 and 2.5, which we no longer support.
This commit is contained in:
Bernie Hackett 2014-04-23 13:25:00 -07:00
parent 91d6b5b5d4
commit bd8d4a3b10
6 changed files with 27 additions and 40 deletions

View File

@ -33,7 +33,6 @@ from bson.min_key import MinKey
from bson.objectid import ObjectId
from bson.py3compat import (b,
PY3,
binary_type,
iteritems,
text_type,
string_type,
@ -370,20 +369,17 @@ def _element_to_bson(key, value, check_keys, uuid_subtype):
if isinstance(value, uuid.UUID):
# Java Legacy
if uuid_subtype == JAVA_LEGACY:
# Python 3.0(.1) returns a bytearray instance for bytes (3.1
# and newer just return a bytes instance). Convert that to
# binary_type (here and below) for compatibility.
from_uuid = binary_type(value.bytes)
from_uuid = value.bytes
as_legacy_java = from_uuid[0:8][::-1] + from_uuid[8:16][::-1]
value = Binary(as_legacy_java, subtype=OLD_UUID_SUBTYPE)
# C# legacy
elif uuid_subtype == CSHARP_LEGACY:
# Microsoft GUID representation.
value = Binary(binary_type(value.bytes_le),
value = Binary(value.bytes_le,
subtype=OLD_UUID_SUBTYPE)
# Python
else:
value = Binary(binary_type(value.bytes), subtype=uuid_subtype)
value = Binary(value.bytes, subtype=uuid_subtype)
if isinstance(value, Binary):
subtype = value.subtype
@ -400,7 +396,7 @@ def _element_to_bson(key, value, check_keys, uuid_subtype):
full_length = struct.pack("<i", 8 + len(cstring) + len(scope))
length = struct.pack("<i", len(cstring))
return BSONCWS + name + full_length + length + cstring + scope
if isinstance(value, binary_type):
if isinstance(value, bytes):
if PY3:
# Python3 special case. Store 'bytes' as BSON binary subtype 0.
return (BSONBIN + name +
@ -557,9 +553,8 @@ def is_valid(bson):
:Parameters:
- `bson`: the data to be validated
"""
if not isinstance(bson, binary_type):
raise TypeError("BSON data must be an instance "
"of a subclass of %s" % (binary_type.__name__,))
if not isinstance(bson, bytes):
raise TypeError("BSON data must be an instance of a subclass of bytes")
try:
(_, remainder) = _bson_to_dict(bson, dict, True, OLD_UUID_SUBTYPE, True)
@ -568,7 +563,7 @@ def is_valid(bson):
return False
class BSON(binary_type):
class BSON(bytes):
"""BSON (Binary JSON) data.
"""

View File

@ -18,7 +18,7 @@ except ImportError:
# Python2.4 doesn't have a uuid module.
pass
from bson.py3compat import PY3, binary_type
from bson.py3compat import PY3
"""Tools for representing BSON binary data.
"""
@ -104,7 +104,7 @@ USER_DEFINED_SUBTYPE = 128
"""
class Binary(binary_type):
class Binary(bytes):
"""Representation of BSON binary data.
This is necessary because we want to represent Python strings as
@ -130,14 +130,13 @@ class Binary(binary_type):
_type_marker = 5
def __new__(cls, data, subtype=BINARY_SUBTYPE):
if not isinstance(data, binary_type):
raise TypeError("data must be an "
"instance of %s" % (binary_type.__name__,))
if not isinstance(data, bytes):
raise TypeError("data must be an instance of bytes")
if not isinstance(subtype, int):
raise TypeError("subtype must be an instance of int")
if subtype >= 256 or subtype < 0:
raise ValueError("subtype must be contained in [0, 256)")
self = binary_type.__new__(cls, data)
self = bytes.__new__(cls, data)
self.__subtype = subtype
return self
@ -150,14 +149,14 @@ class Binary(binary_type):
def __getnewargs__(self):
# Work around http://bugs.python.org/issue7382
data = super(Binary, self).__getnewargs__()[0]
if PY3 and not isinstance(data, binary_type):
if PY3 and not isinstance(data, bytes):
data = data.encode('latin-1')
return data, self.__subtype
def __eq__(self, other):
if isinstance(other, Binary):
return ((self.__subtype, binary_type(self)) ==
(other.subtype, binary_type(other)))
return ((self.__subtype, bytes(self)) ==
(other.subtype, bytes(other)))
# We don't return NotImplemented here because if we did then
# Binary("foo") == "foo" would return True, since Binary is a
# subclass of str...
@ -167,7 +166,7 @@ class Binary(binary_type):
return not self == other
def __repr__(self):
return "Binary(%s, %s)" % (binary_type.__repr__(self), self.__subtype)
return "Binary(%s, %s)" % (bytes.__repr__(self), self.__subtype)
class UUIDLegacy(Binary):
@ -210,10 +209,7 @@ class UUIDLegacy(Binary):
def __new__(cls, obj):
if not isinstance(obj, UUID):
raise TypeError("obj must be an instance of uuid.UUID")
# Python 3.0(.1) returns a bytearray instance for bytes (3.1 and
# newer just return a bytes instance). Convert that to binary_type
# for compatibility.
self = Binary.__new__(cls, binary_type(obj.bytes), OLD_UUID_SUBTYPE)
self = Binary.__new__(cls, obj.bytes, OLD_UUID_SUBTYPE)
self.__uuid = obj
return self

View File

@ -97,7 +97,7 @@ from bson.objectid import ObjectId
from bson.regex import Regex
from bson.timestamp import Timestamp
from bson.py3compat import PY3, binary_type, iteritems, text_type
from bson.py3compat import PY3, iteritems, text_type
_RE_OPT_TABLE = {
@ -152,8 +152,7 @@ def _json_convert(obj):
"""
if hasattr(obj, 'iteritems') or hasattr(obj, 'items'): # PY3 support
return SON(((k, _json_convert(v)) for k, v in iteritems(obj)))
elif hasattr(obj, '__iter__') and not isinstance(obj, (text_type,
binary_type)):
elif hasattr(obj, '__iter__') and not isinstance(obj, (text_type, bytes)):
return list((_json_convert(v) for v in obj))
try:
return default(obj)
@ -248,7 +247,7 @@ def default(obj):
return SON([
('$binary', base64.b64encode(obj).decode()),
('$type', "%02x" % obj.subtype)])
if PY3 and isinstance(obj, binary_type):
if PY3 and isinstance(obj, bytes):
return SON([
('$binary', base64.b64encode(obj).decode()),
('$type', "00")])

View File

@ -33,7 +33,7 @@ import threading
import time
from bson.errors import InvalidId
from bson.py3compat import PY3, binary_type, text_type, bytes_from_hex
from bson.py3compat import PY3, bytes_from_hex, text_type
from bson.tz_util import utc
EMPTY = b""
@ -180,9 +180,9 @@ class ObjectId(object):
"""
if isinstance(oid, ObjectId):
self.__id = oid.__id
elif isinstance(oid, (text_type, binary_type)):
elif isinstance(oid, (bytes, text_type)):
if len(oid) == 12:
if isinstance(oid, binary_type):
if isinstance(oid, bytes):
self.__id = oid
else:
raise InvalidId("%s is not a valid ObjectId" % oid)
@ -194,9 +194,8 @@ class ObjectId(object):
else:
raise InvalidId("%s is not a valid ObjectId" % oid)
else:
raise TypeError("id must be an instance of (%s, %s, ObjectId), "
"not %s" % (binary_type.__name__,
text_type.__name__, type(oid)))
raise TypeError("id must be an instance of (bytes, %s, ObjectId), "
"not %s" % (text_type.__name__, type(oid)))
@property
def binary(self):

View File

@ -53,7 +53,6 @@ if PY3:
def _unicode(s):
return s
binary_type = bytes
text_type = str
string_type = str
integer_types = int
@ -89,7 +88,6 @@ else:
_unicode = unicode
binary_type = str
string_type = basestring
text_type = unicode
integer_types = (int, long)

View File

@ -18,7 +18,7 @@
import re
from bson.son import RE_TYPE
from bson.py3compat import text_type, binary_type, string_type
from bson.py3compat import string_type, text_type
def str_flags_to_int(str_flags):
@ -86,7 +86,7 @@ class Regex(object):
- `flags`: (optional) an integer bitmask, or a string of flag
characters like "im" for IGNORECASE and MULTILINE
"""
if not isinstance(pattern, (text_type, binary_type)):
if not isinstance(pattern, (text_type, bytes)):
raise TypeError("pattern must be a string, not %s" % type(pattern))
self.pattern = pattern