From 352b7871a072a51f32bcb6bc1541cabbc447d5c4 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 12 Mar 2019 17:45:29 +0100 Subject: MAINT: Prevent traceback chaining in _wrapfunc. The traceback of `np.reshape([1, 2, 3], 2)` is shortened from ``` Traceback (most recent call last): File ".../numpy/core/fromnumeric.py", line 56, in _wrapfunc return getattr(obj, method)(*args, **kwds) AttributeError: 'list' object has no attribute 'reshape' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "", line 1, in File ".../numpy/core/overrides.py", line 151, in public_api implementation, public_api, relevant_args, args, kwargs) File ".../numpy/core/fromnumeric.py", line 296, in reshape return _wrapfunc(a, 'reshape', newshape, order=order) File ".../numpy/core/fromnumeric.py", line 66, in _wrapfunc return _wrapit(obj, method, *args, **kwds) File ".../numpy/core/fromnumeric.py", line 46, in _wrapit result = getattr(asarray(obj), method)(*args, **kwds) ValueError: cannot reshape array of size 3 into shape (2,) ``` to ``` Traceback (most recent call last): File "", line 1, in File ".../numpy/core/overrides.py", line 151, in public_api implementation, public_api, relevant_args, args, kwargs) File ".../numpy/core/fromnumeric.py", line 300, in reshape return _wrapfunc(a, 'reshape', newshape, order=order) File ".../numpy/core/fromnumeric.py", line 70, in _wrapfunc return _wrapit(obj, method, *args, **kwds) File ".../numpy/core/fromnumeric.py", line 46, in _wrapit result = getattr(asarray(obj), method)(*args, **kwds) ValueError: cannot reshape array of size 3 into shape (2,) ``` (The chained exception is really just an implementation detail.) --- numpy/core/fromnumeric.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'numpy/core/fromnumeric.py') diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 04b1e9fae..760577890 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -52,17 +52,20 @@ def _wrapit(obj, method, *args, **kwds): def _wrapfunc(obj, method, *args, **kwds): - try: - return getattr(obj, method)(*args, **kwds) - - # An AttributeError occurs if the object does not have - # such a method in its class. + bound = getattr(obj, method, None) + if bound is None: + return _wrapit(obj, method, *args, **kwds) - # A TypeError occurs if the object does have such a method - # in its class, but its signature is not identical to that - # of NumPy's. This situation has occurred in the case of - # a downstream library like 'pandas'. - except (AttributeError, TypeError): + try: + return bound(*args, **kwds) + except TypeError: + # A TypeError occurs if the object does have such a method in its + # class, but its signature is not identical to that of NumPy's. This + # situation has occurred in the case of a downstream library like + # 'pandas'. + # + # Call _wrapit from within the except clause to ensure a potential + # exception has a traceback chain. return _wrapit(obj, method, *args, **kwds) -- cgit v1.2.1