The pure Python implementation of _dict_to_bson in fact accepts
arbitrary mapping types, while the C implementation only accepts
mapping types based on `dict`.
The attached BUG-arbitrary-mapping.patch (see
https://github.com/wolfmanx/mongo-python-driver/commit/6eb4cc47e35c3fc8bb17a81bf9189c3d4fa7b4a4)
provides a possible solution that allows to enable/disable this feature.
IMHO, the default should be either to break existing code or at list
issue a warning, since there is no easy way to fix code, that depends
on the behavior of the pure Python implementation and suddenly won't
run with the C extension enabled.
With the following test case in test_zz_bson.py (see attachment, only
excerpt shown here)::
class TestBSON(unittest.TestCase): def setUp(self): pass def test_arbitrary_mapping_type(self): class ArbitrayMapping(object): def __init__(self): self._arbitrary_mapping_dict_ = dict() def __getattr__(self, attr): try: return getattr(self._arbitrary_mapping_dict_, attr) except AttributeError: return super(ArbitrayMapping, self).__getattribute__(attr) def __iter__(self): return self._arbitrary_mapping_dict_.__iter__() def __getitem__(self, key): return self._arbitrary_mapping_dict_.__getitem__(key) def __setitem__(self, key, val): return self._arbitrary_mapping_dict_.__setitem__(key, val) am = ArbitrayMapping() self.assertRaises(TypeError, BSON.encode, am) am['_id'] = 'FFFFFFFFFFFFFFFFFFFFFFFF' self.assertRaises(TypeError, BSON.encode, am)
Running the test with the C extension, a `TypeError` is raised, since
_cbson._dict_to_bson only accepts real `dict` objects. Therefore,
the test passes::
$ python setup.py test -s test.test_zz_bson test_arbitrary_mapping_type (test.test_zz_bson.TestBSON) ... ok
But without the C Extension, the test fails, since the Python version
of _dict_to_bson indeed accepts arbitrary mapping types::
$ find -name '*.so' | xargs -r rm; python setup.py --without-c-ext test -s test.test_zz_bson test_arbitrary_mapping_type (test.test_zz_bson.TestBSON) ... FAIL ====================================================================== FAIL: test_arbitrary_mapping_type (test.test_zz_bson.TestBSON) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/ws/project/ws-util/mongodb/pymongo/mongo-python-driver-git/test/test_zz_bson.py", line 85, in test_arbitrary_mapping_type self.assertRaises(TypeError, BSON.encode, am) AssertionError: TypeError not raised ----------------------------------------------------------------------
- is depended on by
-
PYTHON-505 Allow PyMongo to work with any object that implements mapping protocol, not just dicts
- Closed