@@ -2383,15 +2383,15 @@ def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
2383
2383
return "ufunc"
2384
2384
else :
2385
2385
inputs = list (inputs )
2386
- inputs [i ] = np .asarray (self )
2386
+ if i < len (inputs ):
2387
+ inputs [i ] = np .asarray (self )
2387
2388
func = getattr (ufunc , method )
2389
+ if ('out' in kw ) and (kw ['out' ] is not None ):
2390
+ kw ['out' ] = np .asarray (kw ['out' ])
2388
2391
r = func (* inputs , ** kw )
2389
- if 'out' in kw :
2390
- return r
2391
- else :
2392
- x = self .__class__ (r .shape , dtype = r .dtype )
2393
- x [...] = r
2394
- return x
2392
+ x = self .__class__ (r .shape , dtype = r .dtype )
2393
+ x [...] = r
2394
+ return x
2395
2395
2396
2396
class SomeClass3 (SomeClass2 ):
2397
2397
def __rsub__ (self , other ):
@@ -2475,6 +2475,64 @@ def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
2475
2475
assert_ ('sig' not in kw and 'signature' in kw )
2476
2476
assert_equal (kw ['signature' ], 'ii->i' )
2477
2477
2478
+ def test_numpy_ufunc_index (self ):
2479
+ # Check that index is set appropriately, also if only an output
2480
+ # is passed on (latter is another regression tests for github bug 4753)
2481
+ class CheckIndex (object ):
2482
+ def __numpy_ufunc__ (self , ufunc , method , i , inputs , ** kw ):
2483
+ return i
2484
+
2485
+ a = CheckIndex ()
2486
+ dummy = np .arange (2. )
2487
+ # 1 input, 1 output
2488
+ assert_equal (np .sin (a ), 0 )
2489
+ assert_equal (np .sin (dummy , a ), 1 )
2490
+ assert_equal (np .sin (dummy , out = a ), 1 )
2491
+ assert_equal (np .sin (dummy , out = (a ,)), 1 )
2492
+ assert_equal (np .sin (a , a ), 0 )
2493
+ assert_equal (np .sin (a , out = a ), 0 )
2494
+ assert_equal (np .sin (a , out = (a ,)), 0 )
2495
+ # 1 input, 2 outputs
2496
+ assert_equal (np .modf (dummy , a ), 1 )
2497
+ assert_equal (np .modf (dummy , None , a ), 2 )
2498
+ assert_equal (np .modf (dummy , dummy , a ), 2 )
2499
+ assert_equal (np .modf (dummy , out = a ), 1 )
2500
+ assert_equal (np .modf (dummy , out = (a ,)), 1 )
2501
+ assert_equal (np .modf (dummy , out = (a , None )), 1 )
2502
+ assert_equal (np .modf (dummy , out = (a , dummy )), 1 )
2503
+ assert_equal (np .modf (dummy , out = (None , a )), 2 )
2504
+ assert_equal (np .modf (dummy , out = (dummy , a )), 2 )
2505
+ assert_equal (np .modf (a , out = (dummy , a )), 0 )
2506
+ # 2 inputs, 1 output
2507
+ assert_equal (np .add (a , dummy ), 0 )
2508
+ assert_equal (np .add (dummy , a ), 1 )
2509
+ assert_equal (np .add (dummy , dummy , a ), 2 )
2510
+ assert_equal (np .add (dummy , a , a ), 1 )
2511
+ assert_equal (np .add (dummy , dummy , out = a ), 2 )
2512
+ assert_equal (np .add (dummy , dummy , out = (a ,)), 2 )
2513
+ assert_equal (np .add (a , dummy , out = a ), 0 )
2514
+
2515
+ def test_out_override (self ):
2516
+ # regression test for github bug 4753
2517
+ class OutClass (ndarray ):
2518
+ def __numpy_ufunc__ (self , ufunc , method , i , inputs , ** kw ):
2519
+ if 'out' in kw :
2520
+ tmp_kw = kw .copy ()
2521
+ tmp_kw .pop ('out' )
2522
+ func = getattr (ufunc , method )
2523
+ kw ['out' ][...] = func (* inputs , ** tmp_kw )
2524
+
2525
+ A = np .array ([0 ]).view (OutClass )
2526
+ B = np .array ([5 ])
2527
+ C = np .array ([6 ])
2528
+ np .multiply (C , B , A )
2529
+ assert_equal (A [0 ], 30 )
2530
+ assert_ (isinstance (A , OutClass ))
2531
+ A [0 ] = 0
2532
+ np .multiply (C , B , out = A )
2533
+ assert_equal (A [0 ], 30 )
2534
+ assert_ (isinstance (A , OutClass ))
2535
+
2478
2536
2479
2537
class TestCAPI (TestCase ):
2480
2538
def test_IsPythonScalar (self ):