@@ -4316,20 +4316,27 @@ ufunc_generic_fastcall(PyUFuncObject *ufunc,
4316
4316
* Outputs and inputs are stored in `full_args.in` and `full_args.out`
4317
4317
* as tuples (or NULL when no outputs are passed).
4318
4318
*/
4319
-
4320
4319
/* Check number of arguments */
4321
- if (NPY_UNLIKELY ((len_args < nin ) || (len_args > nop ))) {
4320
+ // 1 Bounds check: common case, fails quickly
4321
+ if (NPY_UNLIKELY (len_args < nin ) || (len_args > nop )) {
4322
4322
PyErr_Format (PyExc_TypeError ,
4323
- "%s() takes from %d to %d positional arguments but "
4324
- "%zd were given" ,
4325
- ufunc_get_name_cstr (ufunc ) , nin , nop , len_args );
4323
+ "%s() takes from %d to %d positional arguments by %zd were given" ,
4324
+ ufunc_get_name_cstr (ufunc ), nin , nop , len_args );
4326
4325
goto fail ;
4327
4326
}
4328
-
4329
- /* Fetch input arguments. */
4330
- full_args .in = PyArray_TupleFromItems (ufunc -> nin , args , 0 );
4331
- if (full_args .in == NULL ) {
4332
- goto fail ;
4327
+
4328
+ // 2 Only when there are extra pos args and no keywords
4329
+ if (len_args > nin && (kwnames == NULL || PyTuple_Size (kwnames )== 0 )) {
4330
+ // 3 Check if it's the maximum ufunc
4331
+ if (strcmp (ufunc -> name , "maximum" ) == 0 ) {
4332
+ PyErr_WarnFormat (PyExc_DeprecationWarning , 1 ,
4333
+ "Passing more than 2 positional arguments to np.maximum "
4334
+ "is deprecaated; use out=keywords or np.maximum.reduce." );
4335
+ PyErr_Format (PyExc_TypeError ,
4336
+ "np.maximum() takes exactly 2 input arguments (%zd given)." ,
4337
+ len_args );
4338
+ goto fail ;
4339
+ }
4333
4340
}
4334
4341
4335
4342
/*
@@ -4598,12 +4605,12 @@ static PyObject *
4598
4605
ufunc_generic_vectorcall (PyObject * ufunc ,
4599
4606
PyObject * const * args , size_t len_args , PyObject * kwnames )
4600
4607
{
4601
- /*
4602
- * Unlike METH_FASTCALL, `len_args` may have a flag to signal that
4603
- * args[-1] may be (temporarily) used. So normalize it here.
4604
- */
4605
- return ufunc_generic_fastcall (( PyUFuncObject * ) ufunc ,
4606
- args , PyVectorcall_NARGS ( len_args ), kwnames , NPY_FALSE );
4608
+ return ufunc_generic_fastcall (
4609
+ ( PyUFuncObject * ) ufunc ,
4610
+ args ,
4611
+ PyVectorcall_NARGS ( len_args ),
4612
+ kwnames ,
4613
+ NPY_FALSE );
4607
4614
}
4608
4615
4609
4616
0 commit comments