@@ -5129,6 +5129,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
51295129 bool has_keywords = false ;
51305130 vector_string pexprs;
51315131 LineStream extra_convert;
5132+ ostringstream extra_type_check;
51325133 ostringstream extra_param_check;
51335134 LineStream extra_cleanup;
51345135 int min_version = 0 ;
@@ -5589,42 +5590,45 @@ write_function_instance(ostream &out, FunctionRemap *remap,
55895590 only_pyobjects = false ;
55905591
55915592 } else if (TypeManager::is_size (type)) {
5593+ // There is no default format specifier mapping to size_t.
55925594 if (args_type == AT_single_arg) {
5595+ param_name = " arg" ;
55935596 type_check = " PyLongOrInt_Check(arg)" ;
5597+ } else {
5598+ indent (out, indent_level) << " PyObject *" << param_name << null_assign << " ;\n " ;
5599+ if (is_optional) {
5600+ extra_type_check << " && (" << param_name << " == nullptr || PyLongOrInt_Check(" << param_name << " ))" ;
5601+ } else {
5602+ extra_type_check << " && PyLongOrInt_Check(" << param_name << " )" ;
5603+ }
5604+ format_specifiers += " O" ;
5605+ parameter_list += " , &" + param_name;
5606+ }
5607+ expected_params += " int" ;
5608+ pexpr_string = param_name + " _val" ;
55945609
5610+ if (is_optional) {
55955611 extra_convert <<
5596- " size_t arg_val = PyLongOrInt_AsSize_t(arg);\n "
5612+ " size_t " << param_name << " _val" << default_expr << " ;\n "
5613+ " if (" << param_name << " != nullptr) {\n "
5614+ " " << param_name << " _val = PyLongOrInt_AsSize_t(" << param_name << " );\n "
55975615 " #ifndef NDEBUG\n "
5598- " if (arg_val == (size_t)-1 && PyErr_Occurred()) {\n " ;
5616+ " if (" << param_name << " _val == (size_t)-1 && PyErr_Occurred()) {\n " ;
5617+ error_return (extra_convert, 5 , return_flags);
5618+ extra_convert <<
5619+ " }\n "
5620+ " #endif\n "
5621+ " }" ;
5622+ } else {
5623+ extra_convert <<
5624+ " size_t " << param_name << " _val = PyLongOrInt_AsSize_t(" << param_name << " );\n "
5625+ " #ifndef NDEBUG\n "
5626+ " if (" << param_name << " _val == (size_t)-1 && PyErr_Occurred()) {\n " ;
55995627 error_return (extra_convert, 2 , return_flags);
56005628 extra_convert <<
56015629 " }\n "
56025630 " #endif\n " ;
5603-
5604- pexpr_string = " arg_val" ;
5605-
5606- } else {
5607- // It certainly isn't the exact same thing as size_t, but Py_ssize_t
5608- // should at least be the same size. The problem with mapping this to
5609- // unsigned int is that that doesn't work well on 64-bit systems, on
5610- // which size_t is a 64-bit integer.
5611- indent (out, indent_level) << " Py_ssize_t " << param_name << default_expr << " ;\n " ;
5612- format_specifiers += " n" ;
5613- parameter_list += " , &" + param_name;
5614-
5615- extra_convert
5616- << " #ifndef NDEBUG\n "
5617- << " if (" << param_name << " < 0) {\n " ;
5618-
5619- error_raise_return (extra_convert, 2 , return_flags, " OverflowError" ,
5620- " can't convert negative value %zd to size_t" ,
5621- param_name);
5622- extra_convert
5623- << " }\n "
5624- << " #endif\n " ;
56255631 }
5626- expected_params += " int" ;
5627- only_pyobjects = false ;
56285632
56295633 } else if (TypeManager::is_longlong (type)) {
56305634 // It's not trivial to do overflow checking for a long long, so we
@@ -6331,6 +6335,15 @@ write_function_instance(ostream &out, FunctionRemap *remap,
63316335 // Track how many curly braces we've opened.
63326336 short open_scopes = 0 ;
63336337
6338+ // extra_type_check is done before extra_convert, extra_param_check after.
6339+ string extra_type_check_str = extra_type_check.str ();
6340+ if (!extra_type_check_str.empty () && args_type == AT_single_arg) {
6341+ if (type_check.empty ()) {
6342+ type_check = " true" ;
6343+ }
6344+ type_check += extra_type_check_str;
6345+ }
6346+
63346347 if (!type_check.empty () && args_type == AT_single_arg) {
63356348 indent (out, indent_level)
63366349 << " if (" << type_check << " ) {\n " ;
@@ -6350,10 +6363,12 @@ write_function_instance(ostream &out, FunctionRemap *remap,
63506363 // case we have implemented ourselves.
63516364 if (min_num_args == 1 ) {
63526365 indent (out, indent_level)
6353- << " if (Dtool_ExtractArg(&" << param_name << " , args, kwds, " << keyword_list_new << " )) {\n " ;
6366+ << " if (Dtool_ExtractArg(&" << param_name << " , args, kwds, " << keyword_list_new << " )"
6367+ << extra_type_check_str << " ) {\n " ;
63546368 } else {
63556369 indent (out, indent_level)
6356- << " if (Dtool_ExtractOptionalArg(&" << param_name << " , args, kwds, " << keyword_list_new << " )) {\n " ;
6370+ << " if (Dtool_ExtractOptionalArg(&" << param_name << " , args, kwds, " << keyword_list_new << " )"
6371+ << extra_type_check_str << " ) {\n " ;
63576372 }
63586373 } else {
63596374 // We have to use the more expensive PyArg_ParseTupleAndKeywords.
@@ -6373,7 +6388,8 @@ write_function_instance(ostream &out, FunctionRemap *remap,
63736388 indent (out, indent_level)
63746389 << " if (PyArg_ParseTupleAndKeywords(args, kwds, \" "
63756390 << format_specifiers << " :" << method_name
6376- << " \" , (char **)keyword_list" << parameter_list << " )) {\n " ;
6391+ << " \" , (char **)keyword_list" << parameter_list << " )"
6392+ << extra_type_check_str << " ) {\n " ;
63776393 }
63786394
63796395 } else if (only_pyobjects) {
@@ -6382,29 +6398,31 @@ write_function_instance(ostream &out, FunctionRemap *remap,
63826398 if (max_num_args == 1 ) {
63836399 if (min_num_args == 1 ) {
63846400 indent (out, indent_level)
6385- << " if (Dtool_ExtractArg(&" << param_name << " , args, kwds)) {\n " ;
6401+ << " if (Dtool_ExtractArg(&" << param_name << " , args, kwds)"
6402+ << extra_type_check_str << " ) {\n " ;
63866403 } else {
63876404 indent (out, indent_level)
6388- << " if (Dtool_ExtractOptionalArg(&" << param_name << " , args, kwds)) {\n " ;
6405+ << " if (Dtool_ExtractOptionalArg(&" << param_name << " , args, kwds)"
6406+ << extra_type_check_str << " ) {\n " ;
63896407 }
63906408 } else if (max_num_args == 0 ) {
63916409 indent (out, indent_level)
6392- << " if (Dtool_CheckNoArgs(args, kwds)) {\n " ;
6410+ << " if (Dtool_CheckNoArgs(args, kwds)" << extra_type_check_str << " ) {\n " ;
63936411 } else {
63946412 clear_error = true ;
63956413 indent (out, indent_level)
63966414 << " if ((kwds == nullptr || PyDict_Size(kwds) == 0) && PyArg_UnpackTuple(args, \" "
63976415 << methodNameFromCppName (remap, " " , false )
63986416 << " \" , " << min_num_args << " , " << max_num_args
6399- << parameter_list << " )) {\n " ;
6417+ << parameter_list << " )" << extra_type_check_str << " ) {\n " ;
64006418 }
64016419
64026420 } else {
64036421 clear_error = true ;
64046422 indent (out, indent_level)
64056423 << " if ((kwds == nullptr || PyDict_Size(kwds) == 0) && PyArg_ParseTuple(args, \" "
64066424 << format_specifiers << " :" << method_name
6407- << " \" " << parameter_list << " )) {\n " ;
6425+ << " \" " << parameter_list << " )" << extra_type_check_str << " ) {\n " ;
64086426 }
64096427
64106428 ++open_scopes;
@@ -6421,21 +6439,27 @@ write_function_instance(ostream &out, FunctionRemap *remap,
64216439 << " if (PyTuple_GET_SIZE(args) == 1) {\n " ;
64226440 indent (out, indent_level + 2 )
64236441 << param_name << " = PyTuple_GET_ITEM(args, 0);\n " ;
6442+
6443+ if (!extra_type_check_str.empty ()) {
6444+ indent (out, indent_level + 2 )
6445+ << " if (true" << extra_type_check_str << " ) {\n " ;
6446+ ++open_scopes;
6447+ }
64246448 } else {
64256449 clear_error = true ;
64266450 indent (out, indent_level)
64276451 << " if (PyArg_UnpackTuple(args, \" "
64286452 << methodNameFromCppName (remap, " " , false )
64296453 << " \" , " << min_num_args << " , " << max_num_args
6430- << parameter_list << " )) {\n " ;
6454+ << parameter_list << " )" << extra_type_check_str << " ) {\n " ;
64316455 }
64326456
64336457 } else {
64346458 clear_error = true ;
64356459 indent (out, indent_level)
64366460 << " if (PyArg_ParseTuple(args, \" "
64376461 << format_specifiers << " :" << method_name
6438- << " \" " << parameter_list << " )) {\n " ;
6462+ << " \" " << parameter_list << " )" << extra_type_check_str << " ) {\n " ;
64396463 }
64406464 ++open_scopes;
64416465 indent_level += 2 ;
@@ -6446,14 +6470,20 @@ write_function_instance(ostream &out, FunctionRemap *remap,
64466470 if (!only_pyobjects && format_specifiers != " O" ) {
64476471 indent (out, indent_level)
64486472 << " if (PyArg_Parse(arg, \" " << format_specifiers << " :"
6449- << method_name << " \" " << parameter_list << " )) {\n " ;
6473+ << method_name << " \" " << parameter_list << " )"
6474+ << extra_type_check_str << " ) {\n " ;
64506475
64516476 ++open_scopes;
64526477 clear_error = true ;
64536478 indent_level += 2 ;
64546479 }
64556480
64566481 default :
6482+ if (!extra_type_check_str.empty ()) {
6483+ indent (out, indent_level)
6484+ << " if (true" << extra_type_check_str << " ) {\n " ;
6485+ ++open_scopes;
6486+ }
64576487 break ;
64586488 }
64596489 }
0 commit comments