@@ -55,6 +55,7 @@ struct module_state {
55
55
PyObject * DatetimeMS ;
56
56
PyObject * _min_datetime_ms ;
57
57
PyObject * _max_datetime_ms ;
58
+ PyObject * _type_marker_str ;
58
59
};
59
60
60
61
#define GETSTATE (m ) ((struct module_state*)PyModule_GetState(m))
@@ -378,6 +379,9 @@ static int _load_python_objects(PyObject* module) {
378
379
PyObject * compiled = NULL ;
379
380
struct module_state * state = GETSTATE (module );
380
381
382
+ /* Python str for faster _type_marker check */
383
+ state -> _type_marker_str = PyUnicode_FromString ("_type_marker" );
384
+
381
385
if (_load_object (& state -> Binary , "bson.binary" , "Binary" ) ||
382
386
_load_object (& state -> Code , "bson.code" , "Code" ) ||
383
387
_load_object (& state -> ObjectId , "bson.objectid" , "ObjectId" ) ||
@@ -428,13 +432,12 @@ static int _load_python_objects(PyObject* module) {
428
432
*
429
433
* Return the type marker, 0 if there is no marker, or -1 on failure.
430
434
*/
431
- static PyObject * TYPEMARKERSTR ;
432
- static long _type_marker (PyObject * object ) {
435
+ static long _type_marker (PyObject * object , PyObject * _type_marker_str ) {
433
436
PyObject * type_marker = NULL ;
434
437
long type = 0 ;
435
438
436
- if (PyObject_HasAttr (object , TYPEMARKERSTR )) {
437
- type_marker = PyObject_GetAttr (object , TYPEMARKERSTR );
439
+ if (PyObject_HasAttr (object , _type_marker_str )) {
440
+ type_marker = PyObject_GetAttr (object , _type_marker_str );
438
441
if (type_marker == NULL ) {
439
442
return -1 ;
440
443
}
@@ -498,13 +501,12 @@ int cbson_convert_type_registry(PyObject* registry_obj, type_registry_t* registr
498
501
return 0 ;
499
502
}
500
503
501
- /* Fill out a codec_options_t* from a CodecOptions object. Use with the "O&"
502
- * format spec in PyArg_ParseTuple.
504
+ /* Fill out a codec_options_t* from a CodecOptions object.
503
505
*
504
506
* Return 1 on success. options->document_class is a new reference.
505
507
* Return 0 on failure.
506
508
*/
507
- int convert_codec_options (PyObject * options_obj , void * p ) {
509
+ int convert_codec_options (PyObject * self , PyObject * options_obj , void * p ) {
508
510
codec_options_t * options = (codec_options_t * )p ;
509
511
PyObject * type_registry_obj = NULL ;
510
512
long type_marker ;
@@ -521,7 +523,8 @@ int convert_codec_options(PyObject* options_obj, void* p) {
521
523
& options -> datetime_conversion ))
522
524
return 0 ;
523
525
524
- type_marker = _type_marker (options -> document_class );
526
+ type_marker = _type_marker (options -> document_class ,
527
+ GETSTATE (self )-> _type_marker_str );
525
528
if (type_marker < 0 ) {
526
529
return 0 ;
527
530
}
@@ -724,7 +727,7 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer,
724
727
* problems with python sub interpreters. Our custom types should
725
728
* have a _type_marker attribute, which we can switch on instead.
726
729
*/
727
- long type = _type_marker (value );
730
+ long type = _type_marker (value , state -> _type_marker_str );
728
731
if (type < 0 ) {
729
732
return 0 ;
730
733
}
@@ -1376,7 +1379,7 @@ int write_dict(PyObject* self, buffer_t buffer,
1376
1379
long type_marker ;
1377
1380
1378
1381
/* check for RawBSONDocument */
1379
- type_marker = _type_marker (dict );
1382
+ type_marker = _type_marker (dict , state -> _type_marker_str );
1380
1383
if (type_marker < 0 ) {
1381
1384
return 0 ;
1382
1385
}
@@ -1498,18 +1501,20 @@ static PyObject* _cbson_dict_to_bson(PyObject* self, PyObject* args) {
1498
1501
PyObject * result ;
1499
1502
unsigned char check_keys ;
1500
1503
unsigned char top_level = 1 ;
1504
+ PyObject * options_obj ;
1501
1505
codec_options_t options ;
1502
1506
buffer_t buffer ;
1503
1507
PyObject * raw_bson_document_bytes_obj ;
1504
1508
long type_marker ;
1505
1509
1506
- if (!PyArg_ParseTuple (args , "ObO&|b" , & dict , & check_keys ,
1507
- convert_codec_options , & options , & top_level )) {
1510
+ if (!(PyArg_ParseTuple (args , "ObO|b" , & dict , & check_keys ,
1511
+ & options_obj , & top_level ) &&
1512
+ convert_codec_options (self , options_obj , & options ))) {
1508
1513
return NULL ;
1509
1514
}
1510
1515
1511
1516
/* check for RawBSONDocument */
1512
- type_marker = _type_marker (dict );
1517
+ type_marker = _type_marker (dict , GETSTATE ( self ) -> _type_marker_str );
1513
1518
if (type_marker < 0 ) {
1514
1519
destroy_codec_options (& options );
1515
1520
return NULL ;
@@ -2520,6 +2525,7 @@ static PyObject* _cbson_element_to_dict(PyObject* self, PyObject* args) {
2520
2525
/* TODO: Support buffer protocol */
2521
2526
char * string ;
2522
2527
PyObject * bson ;
2528
+ PyObject * options_obj ;
2523
2529
codec_options_t options ;
2524
2530
unsigned position ;
2525
2531
unsigned max ;
@@ -2529,8 +2535,9 @@ static PyObject* _cbson_element_to_dict(PyObject* self, PyObject* args) {
2529
2535
PyObject * value ;
2530
2536
PyObject * result_tuple ;
2531
2537
2532
- if (!PyArg_ParseTuple (args , "OIIO&p" , & bson , & position , & max ,
2533
- convert_codec_options , & options , & raw_array )) {
2538
+ if (!(PyArg_ParseTuple (args , "OIIOp" , & bson , & position , & max ,
2539
+ & options_obj , & raw_array ) &&
2540
+ convert_codec_options (self , options_obj , & options ))) {
2534
2541
return NULL ;
2535
2542
}
2536
2543
@@ -2632,7 +2639,7 @@ static PyObject* _cbson_bson_to_dict(PyObject* self, PyObject* args) {
2632
2639
Py_buffer view = {0 };
2633
2640
2634
2641
if (! (PyArg_ParseTuple (args , "OO" , & bson , & options_obj ) &&
2635
- convert_codec_options (options_obj , & options ))) {
2642
+ convert_codec_options (self , options_obj , & options ))) {
2636
2643
return result ;
2637
2644
}
2638
2645
@@ -2709,10 +2716,8 @@ static PyObject* _cbson_decode_all(PyObject* self, PyObject* args) {
2709
2716
PyObject * options_obj = NULL ;
2710
2717
Py_buffer view = {0 };
2711
2718
2712
- if (!PyArg_ParseTuple (args , "OO" , & bson , & options_obj )) {
2713
- return NULL ;
2714
- }
2715
- if (!convert_codec_options (options_obj , & options )) {
2719
+ if (!(PyArg_ParseTuple (args , "OO" , & bson , & options_obj ) &&
2720
+ convert_codec_options (self , options_obj , & options ))) {
2716
2721
return NULL ;
2717
2722
}
2718
2723
@@ -3025,7 +3030,5 @@ PyInit__cbson(void)
3025
3030
INITERROR ;
3026
3031
}
3027
3032
3028
- TYPEMARKERSTR = PyUnicode_FromString ("_type_marker" );
3029
-
3030
3033
return m ;
3031
3034
}
0 commit comments