@@ -356,7 +356,8 @@ static PyObject* datetime_ms_from_millis(PyObject* self, long long millis){
356356 if (!(ll_millis = PyLong_FromLongLong (millis ))){
357357 return NULL ;
358358 }
359- dt = PyObject_CallFunctionObjArgs (state -> DatetimeMS , ll_millis , NULL );
359+ PyObject * args [1 ] = {ll_millis };
360+ dt = PyObject_Vectorcall (state -> DatetimeMS , args , 1 , NULL );
360361 Py_DECREF (ll_millis );
361362 return dt ;
362363}
@@ -401,7 +402,9 @@ static PyObject* decode_datetime(PyObject* self, long long millis, const codec_o
401402 int64_t min_millis_offset = 0 ;
402403 int64_t max_millis_offset = 0 ;
403404 if (options -> tz_aware && options -> tzinfo && options -> tzinfo != Py_None ) {
404- PyObject * utcoffset = PyObject_CallMethodObjArgs (options -> tzinfo , state -> _utcoffset_str , state -> min_datetime , NULL );
405+ PyObject * utcoffset_args [2 ] = {options -> tzinfo , state -> min_datetime };
406+ PyObject * utcoffset = PyObject_VectorcallMethod (
407+ state -> _utcoffset_str , utcoffset_args , 2 , NULL );
405408 if (utcoffset == NULL ) {
406409 return 0 ;
407410 }
@@ -420,7 +423,9 @@ static PyObject* decode_datetime(PyObject* self, long long millis, const codec_o
420423 (PyDateTime_DELTA_GET_MICROSECONDS (utcoffset ) / 1000 );
421424 }
422425 Py_DECREF (utcoffset );
423- utcoffset = PyObject_CallMethodObjArgs (options -> tzinfo , state -> _utcoffset_str , state -> max_datetime , NULL );
426+ utcoffset_args [1 ] = state -> max_datetime ;
427+ utcoffset = PyObject_VectorcallMethod (
428+ state -> _utcoffset_str , utcoffset_args , 2 , NULL );
424429 if (utcoffset == NULL ) {
425430 return 0 ;
426431 }
@@ -481,7 +486,9 @@ static PyObject* decode_datetime(PyObject* self, long long millis, const codec_o
481486
482487 /* convert to local time */
483488 if (options -> tzinfo != Py_None ) {
484- PyObject * temp = PyObject_CallMethodObjArgs (value , state -> _astimezone_str , options -> tzinfo , NULL );
489+ PyObject * astimezone_args [2 ] = {value , options -> tzinfo };
490+ PyObject * temp = PyObject_VectorcallMethod (
491+ state -> _astimezone_str , astimezone_args , 2 , NULL );
485492 Py_DECREF (value );
486493 value = temp ;
487494 }
@@ -688,7 +695,8 @@ static int _load_python_objects(PyObject* module) {
688695 return 1 ;
689696 }
690697
691- compiled = PyObject_CallFunction (re_compile , "O" , empty_string );
698+ PyObject * compile_args [1 ] = {empty_string };
699+ compiled = PyObject_Vectorcall (re_compile , compile_args , 1 , NULL );
692700 Py_DECREF (re_compile );
693701 if (compiled == NULL ) {
694702 state -> REType = NULL ;
@@ -1244,7 +1252,9 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer,
12441252 case 100 :
12451253 {
12461254 /* DBRef */
1247- PyObject * as_doc = PyObject_CallMethodObjArgs (value , state -> _as_doc_str , NULL );
1255+ PyObject * as_doc_args [1 ] = {value };
1256+ PyObject * as_doc = PyObject_VectorcallMethod (
1257+ state -> _as_doc_str , as_doc_args , 1 , NULL );
12481258 if (!as_doc ) {
12491259 return 0 ;
12501260 }
@@ -1400,7 +1410,9 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer,
14001410 return write_unicode (buffer , value );
14011411 } else if (PyDateTime_Check (value )) {
14021412 long long millis ;
1403- PyObject * utcoffset = PyObject_CallMethodObjArgs (value , state -> _utcoffset_str , NULL );
1413+ PyObject * utcoffset_args [1 ] = {value };
1414+ PyObject * utcoffset = PyObject_VectorcallMethod (
1415+ state -> _utcoffset_str , utcoffset_args , 1 , NULL );
14041416 if (utcoffset == NULL )
14051417 return 0 ;
14061418 if (utcoffset != Py_None ) {
@@ -1439,7 +1451,9 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer,
14391451 if (!(uuid_rep_obj = PyLong_FromLong (options -> uuid_rep ))) {
14401452 return 0 ;
14411453 }
1442- binary_value = PyObject_CallMethodObjArgs (state -> Binary , state -> _from_uuid_str , value , uuid_rep_obj , NULL );
1454+ PyObject * from_uuid_args [3 ] = {state -> Binary , value , uuid_rep_obj };
1455+ binary_value = PyObject_VectorcallMethod (
1456+ state -> _from_uuid_str , from_uuid_args , 3 , NULL );
14431457 Py_DECREF (uuid_rep_obj );
14441458
14451459 if (binary_value == NULL ) {
@@ -1469,7 +1483,8 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer,
14691483 if (converter != NULL ) {
14701484 /* Transform types that have a registered converter.
14711485 * A new reference is created upon transformation. */
1472- new_value = PyObject_CallFunctionObjArgs (converter , value , NULL );
1486+ PyObject * converter_args [1 ] = {value };
1487+ new_value = PyObject_Vectorcall (converter , converter_args , 1 , NULL );
14731488 if (new_value == NULL ) {
14741489 return 0 ;
14751490 }
@@ -1483,8 +1498,9 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer,
14831498 /* Try the fallback encoder if one is provided and we have not already
14841499 * attempted to use the fallback encoder. */
14851500 if (!in_fallback_call && options -> type_registry .has_fallback_encoder ) {
1486- new_value = PyObject_CallFunctionObjArgs (
1487- options -> type_registry .fallback_encoder , value , NULL );
1501+ PyObject * fallback_args [1 ] = {value };
1502+ new_value = PyObject_Vectorcall (
1503+ options -> type_registry .fallback_encoder , fallback_args , 1 , NULL );
14881504 if (new_value == NULL ) {
14891505 // propagate any exception raised by the callback
14901506 return 0 ;
@@ -1685,7 +1701,8 @@ void handle_invalid_doc_error(PyObject* dict) {
16851701 goto cleanup ;
16861702 }
16871703 // Add doc to the error instance as a property.
1688- new_evalue = PyObject_CallFunctionObjArgs (InvalidDocument , new_msg , dict , NULL );
1704+ PyObject * exc_args [2 ] = {new_msg , dict };
1705+ new_evalue = PyObject_Vectorcall (InvalidDocument , exc_args , 2 , NULL );
16891706 Py_DECREF (evalue );
16901707 Py_DECREF (etype );
16911708 etype = InvalidDocument ;
@@ -1961,7 +1978,8 @@ static PyObject *_dbref_hook(PyObject* self, PyObject* value) {
19611978 PyMapping_DelItem (value , state -> _dollar_db_str );
19621979 }
19631980
1964- ret = PyObject_CallFunctionObjArgs (state -> DBRef , ref , id , database , value , NULL );
1981+ PyObject * dbref_args [4 ] = {ref , id , database , value };
1982+ ret = PyObject_Vectorcall (state -> DBRef , dbref_args , 4 , NULL );
19651983 Py_DECREF (value );
19661984 } else {
19671985 ret = value ;
@@ -2177,7 +2195,13 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
21772195 goto uuiderror ;
21782196 }
21792197
2180- binary_value = PyObject_CallFunction (state -> Binary , "(Oi)" , data , subtype );
2198+ PyObject * subtype_obj = PyLong_FromLong (subtype );
2199+ if (!subtype_obj ) {
2200+ goto uuiderror ;
2201+ }
2202+ PyObject * binary_args [2 ] = {data , subtype_obj };
2203+ binary_value = PyObject_Vectorcall (state -> Binary , binary_args , 2 , NULL );
2204+ Py_DECREF (subtype_obj );
21812205 if (binary_value == NULL ) {
21822206 goto uuiderror ;
21832207 }
@@ -2192,7 +2216,9 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
21922216 if (!uuid_rep_obj ) {
21932217 goto uuiderror ;
21942218 }
2195- value = PyObject_CallMethodObjArgs (binary_value , state -> _as_uuid_str , uuid_rep_obj , NULL );
2219+ PyObject * as_uuid_args [2 ] = {binary_value , uuid_rep_obj };
2220+ value = PyObject_VectorcallMethod (
2221+ state -> _as_uuid_str , as_uuid_args , 2 , NULL );
21962222 Py_DECREF (uuid_rep_obj );
21972223 }
21982224
@@ -2211,7 +2237,8 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
22112237 Py_DECREF (data );
22122238 goto invalid ;
22132239 }
2214- value = PyObject_CallFunctionObjArgs (state -> Binary , data , st , NULL );
2240+ PyObject * binary_args [2 ] = {data , st };
2241+ value = PyObject_Vectorcall (state -> Binary , binary_args , 2 , NULL );
22152242 Py_DECREF (st );
22162243 Py_DECREF (data );
22172244 if (!value ) {
@@ -2232,7 +2259,13 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
22322259 if (max < 12 ) {
22332260 goto invalid ;
22342261 }
2235- value = PyObject_CallFunction (state -> ObjectId , "y#" , buffer + * position , (Py_ssize_t )12 );
2262+ PyObject * oid_bytes = PyBytes_FromStringAndSize (buffer + * position , 12 );
2263+ if (!oid_bytes ) {
2264+ goto invalid ;
2265+ }
2266+ PyObject * oid_args [1 ] = {oid_bytes };
2267+ value = PyObject_Vectorcall (state -> ObjectId , oid_args , 1 , NULL );
2268+ Py_DECREF (oid_bytes );
22362269 * position += 12 ;
22372270 break ;
22382271 }
@@ -2311,7 +2344,14 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
23112344 }
23122345 * position += (unsigned )flags_length + 1 ;
23132346
2314- value = PyObject_CallFunction (state -> Regex , "Oi" , pattern , flags );
2347+ PyObject * flags_obj = PyLong_FromLong (flags );
2348+ if (!flags_obj ) {
2349+ Py_DECREF (pattern );
2350+ goto invalid ;
2351+ }
2352+ PyObject * regex_args [2 ] = {pattern , flags_obj };
2353+ value = PyObject_Vectorcall (state -> Regex , regex_args , 2 , NULL );
2354+ Py_DECREF (flags_obj );
23152355 Py_DECREF (pattern );
23162356 break ;
23172357 }
@@ -2344,13 +2384,21 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
23442384 }
23452385 * position += coll_length ;
23462386
2347- id = PyObject_CallFunction (state -> ObjectId , "y#" , buffer + * position , (Py_ssize_t )12 );
2387+ PyObject * oid_bytes = PyBytes_FromStringAndSize (buffer + * position , 12 );
2388+ if (!oid_bytes ) {
2389+ Py_DECREF (collection );
2390+ goto invalid ;
2391+ }
2392+ PyObject * oid_args [1 ] = {oid_bytes };
2393+ id = PyObject_Vectorcall (state -> ObjectId , oid_args , 1 , NULL );
2394+ Py_DECREF (oid_bytes );
23482395 if (!id ) {
23492396 Py_DECREF (collection );
23502397 goto invalid ;
23512398 }
23522399 * position += 12 ;
2353- value = PyObject_CallFunctionObjArgs (state -> DBRef , collection , id , NULL );
2400+ PyObject * dbref_args [2 ] = {collection , id };
2401+ value = PyObject_Vectorcall (state -> DBRef , dbref_args , 2 , NULL );
23542402 Py_DECREF (collection );
23552403 Py_DECREF (id );
23562404 break ;
@@ -2380,7 +2428,8 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
23802428 goto invalid ;
23812429 }
23822430 * position += value_length ;
2383- value = PyObject_CallFunctionObjArgs (state -> Code , code , NULL , NULL );
2431+ PyObject * code_args [1 ] = {code };
2432+ value = PyObject_Vectorcall (state -> Code , code_args , 1 , NULL );
23842433 Py_DECREF (code );
23852434 break ;
23862435 }
@@ -2446,7 +2495,8 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
24462495 }
24472496 * position += scope_size ;
24482497
2449- value = PyObject_CallFunctionObjArgs (state -> Code , code , scope , NULL );
2498+ PyObject * code_scope_args [2 ] = {code , scope };
2499+ value = PyObject_Vectorcall (state -> Code , code_scope_args , 2 , NULL );
24502500 Py_DECREF (code );
24512501 Py_DECREF (scope );
24522502 break ;
@@ -2476,7 +2526,19 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
24762526 memcpy (& time , buffer + * position + 4 , 4 );
24772527 inc = BSON_UINT32_FROM_LE (inc );
24782528 time = BSON_UINT32_FROM_LE (time );
2479- value = PyObject_CallFunction (state -> Timestamp , "II" , time , inc );
2529+ PyObject * time_obj = PyLong_FromUnsignedLong (time );
2530+ if (!time_obj ) {
2531+ goto invalid ;
2532+ }
2533+ PyObject * inc_obj = PyLong_FromUnsignedLong (inc );
2534+ if (!inc_obj ) {
2535+ Py_DECREF (time_obj );
2536+ goto invalid ;
2537+ }
2538+ PyObject * ts_args [2 ] = {time_obj , inc_obj };
2539+ value = PyObject_Vectorcall (state -> Timestamp , ts_args , 2 , NULL );
2540+ Py_DECREF (time_obj );
2541+ Py_DECREF (inc_obj );
24802542 * position += 8 ;
24812543 break ;
24822544 }
@@ -2488,7 +2550,13 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
24882550 }
24892551 memcpy (& ll , buffer + * position , 8 );
24902552 ll = (int64_t )BSON_UINT64_FROM_LE (ll );
2491- value = PyObject_CallFunction (state -> BSONInt64 , "L" , ll );
2553+ PyObject * ll_obj = PyLong_FromLongLong (ll );
2554+ if (!ll_obj ) {
2555+ goto invalid ;
2556+ }
2557+ PyObject * int64_args [1 ] = {ll_obj };
2558+ value = PyObject_Vectorcall (state -> BSONInt64 , int64_args , 1 , NULL );
2559+ Py_DECREF (ll_obj );
24922560 * position += 8 ;
24932561 break ;
24942562 }
@@ -2501,19 +2569,21 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
25012569 if (!_bytes_obj ) {
25022570 goto invalid ;
25032571 }
2504- value = PyObject_CallMethodObjArgs (state -> Decimal128 , state -> _from_bid_str , _bytes_obj , NULL );
2572+ PyObject * dec128_args [2 ] = {state -> Decimal128 , _bytes_obj };
2573+ value = PyObject_VectorcallMethod (
2574+ state -> _from_bid_str , dec128_args , 2 , NULL );
25052575 Py_DECREF (_bytes_obj );
25062576 * position += 16 ;
25072577 break ;
25082578 }
25092579 case 255 :
25102580 {
2511- value = PyObject_CallFunctionObjArgs (state -> MinKey , NULL );
2581+ value = PyObject_Vectorcall (state -> MinKey , NULL , 0 , NULL );
25122582 break ;
25132583 }
25142584 case 127 :
25152585 {
2516- value = PyObject_CallFunctionObjArgs (state -> MaxKey , NULL );
2586+ value = PyObject_Vectorcall (state -> MaxKey , NULL , 0 , NULL );
25172587 break ;
25182588 }
25192589 default :
@@ -2565,7 +2635,8 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
25652635 }
25662636 converter = PyDict_GetItem (options -> type_registry .decoder_map , value_type );
25672637 if (converter != NULL ) {
2568- PyObject * new_value = PyObject_CallFunctionObjArgs (converter , value , NULL );
2638+ PyObject * converter_args [1 ] = {value };
2639+ PyObject * new_value = PyObject_Vectorcall (converter , converter_args , 1 , NULL );
25692640 Py_DECREF (value_type );
25702641 Py_DECREF (value );
25712642 return new_value ;
@@ -2790,9 +2861,14 @@ static PyObject* elements_to_dict(PyObject* self, const char* string,
27902861 const codec_options_t * options ) {
27912862 PyObject * result ;
27922863 if (options -> is_raw_bson ) {
2793- return PyObject_CallFunction (
2794- options -> document_class , "y#O" ,
2795- string , max , options -> options_obj );
2864+ PyObject * bson_bytes = PyBytes_FromStringAndSize (string , max );
2865+ if (!bson_bytes ) {
2866+ return NULL ;
2867+ }
2868+ PyObject * raw_args [2 ] = {bson_bytes , options -> options_obj };
2869+ result = PyObject_Vectorcall (options -> document_class , raw_args , 2 , NULL );
2870+ Py_DECREF (bson_bytes );
2871+ return result ;
27962872 }
27972873 if (Py_EnterRecursiveCall (" while decoding a BSON document" ))
27982874 return NULL ;
0 commit comments