3131from bson .max_key import MaxKey
3232from bson .min_key import MinKey
3333from bson .objectid import ObjectId
34- from bson .py3compat import b , binary_type
34+ from bson .py3compat import (b ,
35+ PY3 ,
36+ binary_type ,
37+ iteritems ,
38+ text_type ,
39+ string_type ,
40+ reraise )
3541from bson .regex import Regex
3642from bson .son import SON , RE_TYPE
3743from bson .timestamp import Timestamp
5056except ImportError :
5157 _use_uuid = False
5258
53- PY3 = sys . version_info [ 0 ] == 3
54-
59+ if PY3 :
60+ long = int
5561
5662MAX_INT32 = 2147483647
5763MIN_INT32 = - 2147483648
6167EPOCH_AWARE = datetime .datetime .fromtimestamp (0 , utc )
6268EPOCH_NAIVE = datetime .datetime .utcfromtimestamp (0 )
6369
64- # Create constants compatible with all versions of
65- # python from 2.4 forward. In 2.x b("foo") is just
66- # "foo". In 3.x it becomes b"foo".
67- EMPTY = b ("" )
68- ZERO = b ("\x00 " )
69- ONE = b ("\x01 " )
70-
71- BSONNUM = b ("\x01 " ) # Floating point
72- BSONSTR = b ("\x02 " ) # UTF-8 string
73- BSONOBJ = b ("\x03 " ) # Embedded document
74- BSONARR = b ("\x04 " ) # Array
75- BSONBIN = b ("\x05 " ) # Binary
76- BSONUND = b ("\x06 " ) # Undefined
77- BSONOID = b ("\x07 " ) # ObjectId
78- BSONBOO = b ("\x08 " ) # Boolean
79- BSONDAT = b ("\x09 " ) # UTC Datetime
80- BSONNUL = b ("\x0A " ) # Null
81- BSONRGX = b ("\x0B " ) # Regex
82- BSONREF = b ("\x0C " ) # DBRef
83- BSONCOD = b ("\x0D " ) # Javascript code
84- BSONSYM = b ("\x0E " ) # Symbol
85- BSONCWS = b ("\x0F " ) # Javascript code with scope
86- BSONINT = b ("\x10 " ) # 32bit int
87- BSONTIM = b ("\x11 " ) # Timestamp
88- BSONLON = b ("\x12 " ) # 64bit int
89- BSONMIN = b ("\xFF " ) # Min key
90- BSONMAX = b ("\x7F " ) # Max key
70+ EMPTY = b""
71+ ZERO = b"\x00 "
72+ ONE = b"\x01 "
73+
74+ BSONNUM = b"\x01 " # Floating point
75+ BSONSTR = b"\x02 " # UTF-8 string
76+ BSONOBJ = b"\x03 " # Embedded document
77+ BSONARR = b"\x04 " # Array
78+ BSONBIN = b"\x05 " # Binary
79+ BSONUND = b"\x06 " # Undefined
80+ BSONOID = b"\x07 " # ObjectId
81+ BSONBOO = b"\x08 " # Boolean
82+ BSONDAT = b"\x09 " # UTC Datetime
83+ BSONNUL = b"\x0A " # Null
84+ BSONRGX = b"\x0B " # Regex
85+ BSONREF = b"\x0C " # DBRef
86+ BSONCOD = b"\x0D " # Javascript code
87+ BSONSYM = b"\x0E " # Symbol
88+ BSONCWS = b"\x0F " # Javascript code with scope
89+ BSONINT = b"\x10 " # 32bit int
90+ BSONTIM = b"\x11 " # Timestamp
91+ BSONLON = b"\x12 " # 64bit int
92+ BSONMIN = b"\xFF " # Min key
93+ BSONMAX = b"\x7F " # Max key
9194
9295
9396def _get_int (data , position , as_class = None ,
@@ -117,12 +120,7 @@ def _get_c_string(data, position, length=None):
117120
118121
119122def _make_c_string (string , check_null = False ):
120- if isinstance (string , unicode ):
121- if check_null and "\x00 " in string :
122- raise InvalidDocument ("BSON keys / regex patterns must not "
123- "contain a NULL character" )
124- return string .encode ("utf-8" ) + ZERO
125- else :
123+ if isinstance (string , bytes ):
126124 if check_null and ZERO in string :
127125 raise InvalidDocument ("BSON keys / regex patterns must not "
128126 "contain a NULL character" )
@@ -132,6 +130,11 @@ def _make_c_string(string, check_null=False):
132130 except UnicodeError :
133131 raise InvalidStringData ("strings in documents must be valid "
134132 "UTF-8: %r" % string )
133+ else :
134+ if check_null and "\x00 " in string :
135+ raise InvalidDocument ("BSON keys / regex patterns must not "
136+ "contain a NULL character" )
137+ return string .encode ("utf-8" ) + ZERO
135138
136139
137140def _get_number (data , position , as_class , tz_aware , uuid_subtype , compile_re ):
@@ -349,7 +352,7 @@ def _bson_to_dict(data, as_class, tz_aware, uuid_subtype, compile_re):
349352
350353
351354def _element_to_bson (key , value , check_keys , uuid_subtype ):
352- if not isinstance (key , basestring ):
355+ if not isinstance (key , string_type ):
353356 raise InvalidDocument ("documents must have only string keys, "
354357 "key was %r" % key )
355358
@@ -405,7 +408,7 @@ def _element_to_bson(key, value, check_keys, uuid_subtype):
405408 cstring = _make_c_string (value )
406409 length = struct .pack ("<i" , len (cstring ))
407410 return BSONSTR + name + length + cstring
408- if isinstance (value , unicode ):
411+ if isinstance (value , text_type ):
409412 cstring = _make_c_string (value )
410413 length = struct .pack ("<i" , len (cstring ))
411414 return BSONSTR + name + length + cstring
@@ -429,7 +432,7 @@ def _element_to_bson(key, value, check_keys, uuid_subtype):
429432 return BSONINT + name + struct .pack ("<i" , value )
430433 # 2to3 will convert long to int here since there is no long in python3.
431434 # That's OK. The previous if block will match instead.
432- if isinstance (value , long ):
435+ if not PY3 and isinstance (value , long ):
433436 if value > MAX_INT64 or value < MIN_INT64 :
434437 raise OverflowError ("BSON can only handle up to 8-byte ints" )
435438 return BSONLON + name + struct .pack ("<q" , value )
@@ -479,7 +482,7 @@ def _dict_to_bson(dict, check_keys, uuid_subtype, top_level=True):
479482 if top_level and "_id" in dict :
480483 elements .append (_element_to_bson ("_id" , dict ["_id" ],
481484 check_keys , uuid_subtype ))
482- for (key , value ) in dict . iteritems ():
485+ for (key , value ) in iteritems (dict ):
483486 if not top_level or key != "_id" :
484487 elements .append (_element_to_bson (key , value ,
485488 check_keys , uuid_subtype ))
@@ -537,7 +540,9 @@ def decode_all(data, as_class=dict,
537540 except Exception :
538541 # Change exception type to InvalidBSON but preserve traceback.
539542 exc_type , exc_value , exc_tb = sys .exc_info ()
540- raise InvalidBSON , str (exc_value ), exc_tb
543+ reraise (InvalidBSON , exc_value , exc_tb )
544+
545+
541546if _use_c :
542547 decode_all = _cbson .decode_all
543548
0 commit comments