PYTHON-856 - as_class -> document_class

This commit changes the name of the as_class option
in CodecOptions to document_class, to match the name
of the MongoClient option.
This commit is contained in:
Bernie Hackett 2015-03-09 14:32:42 -07:00
parent fa1466179f
commit c87424e7af
10 changed files with 56 additions and 54 deletions

View File

@ -123,7 +123,7 @@ def _get_string(data, position, obj_end, dummy):
def _get_object(data, position, obj_end, opts):
"""Decode a BSON subdocument to opts.as_class or bson.dbref.DBRef."""
"""Decode a BSON subdocument to opts.document_class or bson.dbref.DBRef."""
obj_size = _UNPACK_INT(data[position:position + 4])[0]
end = position + obj_size - 1
if data[end:position + obj_size] != b"\x00":
@ -235,7 +235,7 @@ def _get_code_w_scope(data, position, obj_end, opts):
return Code(code, scope), position
def _get_regex(data, position, dummy, opts):
def _get_regex(data, position, dummy0, dummy1):
"""Decode a BSON regex to bson.regex.Regex or a python pattern object."""
pattern, position = _get_c_string(data, position)
bson_flags, position = _get_c_string(data, position)
@ -303,7 +303,7 @@ def _element_to_dict(data, position, obj_end, opts):
def _elements_to_dict(data, position, obj_end, opts):
"""Decode a BSON document."""
result = opts.as_class()
result = opts.document_class()
end = obj_end - 1
while position < end:
(key, value, position) = _element_to_dict(data, position, obj_end, opts)
@ -312,11 +312,11 @@ def _elements_to_dict(data, position, obj_end, opts):
def _bson_to_dict(data, opts):
"""Decode a BSON string to as_class."""
"""Decode a BSON string to document_class."""
try:
obj_size = _UNPACK_INT(data[:4])[0]
except struct.error as e:
raise InvalidBSON(str(e))
except struct.error as exc:
raise InvalidBSON(str(exc))
if obj_size != len(data):
raise InvalidBSON("invalid object size")
if data[obj_size - 1:obj_size] != b"\x00":
@ -900,7 +900,7 @@ class BSON(bytes):
>>> data = bson.BSON.encode({'a': 1})
>>> decoded_doc = bson.BSON.decode(data)
<type 'dict'>
>>> options = CodecOptions(as_class=collections.OrderedDict)
>>> options = CodecOptions(document_class=collections.OrderedDict)
>>> decoded_doc = bson.BSON.decode(data, codec_options=options)
>>> type(decoded_doc)
<class 'collections.OrderedDict'>

View File

@ -113,26 +113,26 @@ _downcast_and_check(Py_ssize_t size, int extra) {
/* Fill out a codec_options_t* from a CodecOptions object. Use with the "O&"
* format spec in PyArg_ParseTuple.
*
* Return 1 on success. options->as_class is a new reference.
* Return 1 on success. options->document_class is a new reference.
* Return 0 on failure.
*/
int convert_codec_options(PyObject* options_obj, void* p) {
codec_options_t* options = (codec_options_t*)p;
if (!PyArg_ParseTuple(options_obj, "Obb",
&options->as_class,
&options->document_class,
&options->tz_aware,
&options->uuid_rep)) {
return 0;
}
Py_INCREF(options->as_class);
Py_INCREF(options->document_class);
return 1;
}
/* Fill out a codec_options_t* with default options. */
void default_codec_options(codec_options_t* options) {
options->as_class = (PyObject*)&PyDict_Type;
Py_INCREF(options->as_class);
options->document_class = (PyObject*)&PyDict_Type;
Py_INCREF(options->document_class);
// TODO: set to "1". PYTHON-526, setting tz_aware=True by default.
options->tz_aware = 0;
@ -140,7 +140,7 @@ void default_codec_options(codec_options_t* options) {
}
void destroy_codec_options(codec_options_t* options) {
Py_CLEAR(options->as_class);
Py_CLEAR(options->document_class);
}
static PyObject* elements_to_dict(PyObject* self, const char* string,
@ -2223,7 +2223,7 @@ static PyObject* _elements_to_dict(PyObject* self, const char* string,
unsigned max,
const codec_options_t* options) {
unsigned position = 0;
PyObject* dict = PyObject_CallObject(options->as_class, NULL);
PyObject* dict = PyObject_CallObject(options->document_class, NULL);
if (!dict) {
return NULL;
}

View File

@ -53,7 +53,7 @@ typedef int Py_ssize_t;
#endif
typedef struct codec_options_t {
PyObject* as_class;
PyObject* document_class;
unsigned char tz_aware;
unsigned char uuid_rep;
} codec_options_t;

View File

@ -21,15 +21,15 @@ from bson.binary import (ALL_UUID_REPRESENTATIONS,
UUID_REPRESENTATION_NAMES)
_options_base = namedtuple('CodecOptions',
('as_class', 'tz_aware', 'uuid_representation'))
_options_base = namedtuple(
'CodecOptions', ('document_class', 'tz_aware', 'uuid_representation'))
class CodecOptions(_options_base):
"""Encapsulates BSON options used in CRUD operations.
:Parameters:
- `as_class`: BSON documents returned in queries will be decoded
- `document_class`: BSON documents returned in queries will be decoded
to an instance of this class. Must be a subclass of
:class:`~collections.MutableMapping`. Defaults to :class:`dict`.
- `tz_aware`: If ``True``, BSON datetimes will be decoded to timezone
@ -40,10 +40,10 @@ class CodecOptions(_options_base):
:data:`~bson.binary.PYTHON_LEGACY`.
"""
def __new__(cls, as_class=dict,
def __new__(cls, document_class=dict,
tz_aware=False, uuid_representation=PYTHON_LEGACY):
if not issubclass(as_class, MutableMapping):
raise TypeError("as_class must be dict, bson.son.SON, or "
if not issubclass(document_class, MutableMapping):
raise TypeError("document_class must be dict, bson.son.SON, or "
"another subclass of collections.MutableMapping")
if not isinstance(tz_aware, bool):
raise TypeError("tz_aware must be True or False")
@ -51,18 +51,20 @@ class CodecOptions(_options_base):
raise ValueError("uuid_representation must be a value "
"from bson.binary.ALL_UUID_REPRESENTATIONS")
return tuple.__new__(cls, (as_class, tz_aware, uuid_representation))
return tuple.__new__(
cls, (document_class, tz_aware, uuid_representation))
def __repr__(self):
as_class_repr = (
'dict' if self.as_class is dict else repr(self.as_class))
document_class_repr = (
'dict' if self.document_class is dict
else repr(self.document_class))
uuid_rep_repr = UUID_REPRESENTATION_NAMES.get(self.uuid_representation,
self.uuid_representation)
return (
'CodecOptions(as_class=%s, tz_aware=%r, uuid_representation=%s)'
% (as_class_repr, self.tz_aware, uuid_rep_repr))
'CodecOptions(document_class=%s, tz_aware=%r, uuid_representation='
'%s)' % (document_class_repr, self.tz_aware, uuid_rep_repr))
DEFAULT_CODEC_OPTIONS = CodecOptions()
@ -71,8 +73,8 @@ DEFAULT_CODEC_OPTIONS = CodecOptions()
def _parse_codec_options(options):
"""Parse BSON codec options."""
return CodecOptions(
as_class=options.get(
'document_class', DEFAULT_CODEC_OPTIONS.as_class),
document_class=options.get(
'document_class', DEFAULT_CODEC_OPTIONS.document_class),
tz_aware=options.get(
'tz_aware', DEFAULT_CODEC_OPTIONS.tz_aware),
uuid_representation=options.get(

View File

@ -141,9 +141,9 @@ collection, configured to use :class:`~bson.son.SON` instead of dict:
.. doctest:: key-order
>>> from bson import CodecOptions, SON
>>> opts = CodecOptions(as_class=SON)
>>> opts = CodecOptions(document_class=SON)
>>> opts # doctest: +NORMALIZE_WHITESPACE
CodecOptions(as_class=<class 'bson.son.SON'>,
CodecOptions(document_class=<class 'bson.son.SON'>,
tz_aware=False,
uuid_representation=PYTHON_LEGACY)
>>> collection_son = collection.with_options(codec_options=opts)

View File

@ -1288,7 +1288,7 @@ class Collection(common.BaseObject):
cmd = SON([("listIndexes", self.__name), ("cursor", {})])
res, addr = self._command(cmd,
ReadPreference.PRIMARY,
CodecOptions(as_class=SON))
CodecOptions(document_class=SON))
# MongoDB 2.8rc2
if "indexes" in res:
raw = res["indexes"]
@ -1298,7 +1298,7 @@ class Collection(common.BaseObject):
else:
raw = self.__database.get_collection(
"system.indexes",
codec_options=CodecOptions(as_class=SON),
codec_options=CodecOptions(document_class=SON),
read_preference=ReadPreference.PRIMARY).find(
{"ns": self.__full_name}, {"ns": 0})
info = {}

View File

@ -132,7 +132,7 @@ class TestBSON(unittest.TestCase):
def encode_then_decode(doc):
return doc_class(doc) == BSON.encode(doc).decode(
CodecOptions(as_class=doc_class))
CodecOptions(document_class=doc_class))
qcheck.check_unittest(self, encode_then_decode,
qcheck.gen_mongo_dict(3))
@ -590,16 +590,17 @@ class TestBSON(unittest.TestCase):
self.assertIsInstance(BSON.encode({}).decode(), dict)
self.assertNotIsInstance(BSON.encode({}).decode(), SON)
self.assertIsInstance(
BSON.encode({}).decode(CodecOptions(as_class=SON)),
BSON.encode({}).decode(CodecOptions(document_class=SON)),
SON)
self.assertEqual(
1,
BSON.encode({"x": 1}).decode(CodecOptions(as_class=SON))["x"])
BSON.encode({"x": 1}).decode(
CodecOptions(document_class=SON))["x"])
x = BSON.encode({"x": [{"y": 1}]})
self.assertIsInstance(x.decode(CodecOptions(as_class=SON))["x"][0],
SON)
self.assertIsInstance(
x.decode(CodecOptions(document_class=SON))["x"][0], SON)
def test_subclasses(self):
# make sure we can serialize subclasses of native Python types.
@ -630,7 +631,7 @@ class TestBSON(unittest.TestCase):
d = OrderedDict([("one", 1), ("two", 2), ("three", 3), ("four", 4)])
self.assertEqual(
d,
BSON.encode(d).decode(CodecOptions(as_class=OrderedDict)))
BSON.encode(d).decode(CodecOptions(document_class=OrderedDict)))
def test_bson_regex(self):
# Invalid Python regex, though valid PCRE.
@ -764,9 +765,9 @@ class TestBSON(unittest.TestCase):
class TestCodecOptions(unittest.TestCase):
def test_as_class(self):
self.assertRaises(TypeError, CodecOptions, as_class=object)
self.assertIs(SON, CodecOptions(as_class=SON).as_class)
def test_document_class(self):
self.assertRaises(TypeError, CodecOptions, document_class=object)
self.assertIs(SON, CodecOptions(document_class=SON).document_class)
def test_tz_aware(self):
self.assertRaises(TypeError, CodecOptions, tz_aware=1)
@ -779,15 +780,15 @@ class TestCodecOptions(unittest.TestCase):
self.assertRaises(ValueError, CodecOptions, uuid_representation=2)
def test_codec_options_repr(self):
r = ('CodecOptions(as_class=dict, tz_aware=False, '
r = ('CodecOptions(document_class=dict, tz_aware=False, '
'uuid_representation=PYTHON_LEGACY)')
self.assertEqual(r, repr(CodecOptions()))
def test_decode_all_defaults(self):
# Test decode_all()'s default as_class is dict and tz_aware is False.
# The default uuid_representation is PYTHON_LEGACY but this decodes
# same as STANDARD, so all this test proves about UUID decoding is
# that it's not CSHARP_LEGACY or JAVA_LEGACY.
# Test decode_all()'s default document_class is dict and tz_aware is
# False. The default uuid_representation is PYTHON_LEGACY but this
# decodes same as STANDARD, so all this test proves about UUID decoding
# is that it's not CSHARP_LEGACY or JAVA_LEGACY.
doc = {'sub_document': {},
'uuid': uuid.uuid4(),
'dt': datetime.datetime.utcnow()}

View File

@ -41,8 +41,7 @@ from pymongo.errors import (AutoReconnect,
OperationFailure,
CursorNotFound,
NetworkTimeout,
InvalidURI,
ServerSelectionTimeoutError)
InvalidURI)
from pymongo.mongo_client import MongoClient
from pymongo.pool import SocketInfo
from pymongo.read_preferences import ReadPreference
@ -462,14 +461,14 @@ class TestClient(IntegrationTest):
db = c.pymongo_test
db.test.insert_one({"x": 1})
self.assertEqual(dict, c.codec_options.as_class)
self.assertEqual(dict, c.codec_options.document_class)
self.assertTrue(isinstance(db.test.find_one(), dict))
self.assertFalse(isinstance(db.test.find_one(), SON))
c = rs_or_single_client(document_class=SON)
db = c.pymongo_test
self.assertEqual(SON, c.codec_options.as_class)
self.assertEqual(SON, c.codec_options.document_class)
self.assertTrue(isinstance(db.test.find_one(), SON))

View File

@ -544,7 +544,7 @@ class TestDatabase(IntegrationTest):
("_id", 5)]))
db = self.client.get_database(
"pymongo_test", codec_options=CodecOptions(as_class=SON))
"pymongo_test", codec_options=CodecOptions(document_class=SON))
cursor = db.test.find()
for x in cursor:
for (k, v) in x.items():
@ -579,7 +579,7 @@ class TestDatabase(IntegrationTest):
db.test.insert_one({"_id": 4, "foo": "bar"})
db = self.client.get_database(
"pymongo_test", codec_options=CodecOptions(as_class=SON))
"pymongo_test", codec_options=CodecOptions(document_class=SON))
self.assertEqual(SON([("foo", "bar")]),
db.dereference(DBRef("test", 4),
projection={"_id": False}))

View File

@ -120,7 +120,7 @@ class TestLegacy(IntegrationTest):
doc_class = SON
db = self.client.get_database(
db.name, codec_options=CodecOptions(as_class=doc_class))
db.name, codec_options=CodecOptions(document_class=doc_class))
def remove_insert_find_one(doc):
db.test.remove({})
@ -770,7 +770,7 @@ class TestLegacy(IntegrationTest):
new=True, fields={'i': 1})
self.assertFalse(isinstance(result, ExtendedDict))
c = self.db.get_collection(
"test", codec_options=CodecOptions(as_class=ExtendedDict))
"test", codec_options=CodecOptions(document_class=ExtendedDict))
result = c.find_and_modify({'_id': 1}, {'$inc': {'i': 1}},
new=True, fields={'i': 1})
self.assertTrue(isinstance(result, ExtendedDict))