-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
tp_compare warning on sort in Python 2.6/2.7 with OSX with object array of length >= 20 with objects that raise TypeError #3879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Occurs with numpy 1.7.1 and 1.6 |
Occurs on '1.9.0.dev-ec3603f' too. |
when its done comparing the objects which always fail (and set PyErr) it starts comparing the integers which returns -1, 0, 1. But the PyErr is still set which causes python warn on the also happens on linux if one reverses the integer list (mac quicksort probably compares in reverse order sometimes) |
clearing the error in OBJECT_compare obviously can't be done just for quicksort, maybe one should disable runtime warnings in before npy_quicksort and restore later, or add a special OBJECT_compare which clears python errors to be used by only by quicksort. |
Why do we want to clear the error? Shouldn't we just bail out early if a
|
Your comment made me wonder if sorting that causes an error causes the array to be left in a different state than it was before (at least on Windows with numpy 1.6, it does). Not sure if that's an issue. Apologies that it's a bit hard to read - just note that the integers move. import numpy as np
import random
class Raiser(object):
def raises_anything(*args, **kwargs):
raise TypeError("SOMETHING ERRORED")
__eq__ = __ne__ = __lt__ = __gt__ = __ge__ = __le__ = raises_anything
arr = np.array([Raiser() for n in range(10)] + list(range(10)))
random.shuffle(arr)
arr
Out[6]:
array([<__main__.Raiser object at 0x0000000007F7BA20>,
<__main__.Raiser object at 0x0000000007F7B908>, 5, 8,
<__main__.Raiser object at 0x0000000007F7B940>, 9,
<__main__.Raiser object at 0x0000000007F7B978>,
<__main__.Raiser object at 0x0000000007F7B9E8>, 3,
<__main__.Raiser object at 0x0000000007F7BA58>, 2,
<__main__.Raiser object at 0x0000000007F7BA90>,
<__main__.Raiser object at 0x0000000007F7B9B0>, 1,
<__main__.Raiser object at 0x0000000007F7B898>, 6, 7, 4, 0,
<__main__.Raiser object at 0x0000000007F7BAC8>], dtype=object)
original = arr.copy()
arr.sort()
-c:1: RuntimeWarning: tp_compare didn't return -1 or -2 for exception
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-f2555d8c7d46> in <module>()
----> 1 arr.sort()
<ipython-input-1-1f1f20d5336e> in raises_anything(*args, **kwargs)
2 class Raiser(object):
3 def raises_anything(*args, **kwargs):
----> 4 raise TypeError("SOMETHING ERRORED")
5 __eq__ = __ne__ = __lt__ = __gt__ = __ge__ = __le__ = raises_anything
6 arr = np.array([Raiser() for n in range(10)] + list(range(10)))
TypeError: SOMETHING ERRORED
arr
Out[9]:
array([<__main__.Raiser object at 0x0000000007F7B908>, 5, 8,
<__main__.Raiser object at 0x0000000007F7B940>, 9,
<__main__.Raiser object at 0x0000000007F7B978>,
<__main__.Raiser object at 0x0000000007F7B9E8>,
<__main__.Raiser object at 0x0000000007F7BA20>, 3,
<__main__.Raiser object at 0x0000000007F7BA58>, 2,
<__main__.Raiser object at 0x0000000007F7BA90>,
<__main__.Raiser object at 0x0000000007F7B9B0>, 1,
<__main__.Raiser object at 0x0000000007F7B898>, 6, 7, 4, 0,
<__main__.Raiser object at 0x0000000007F7BAC8>], dtype=object)
original
Out[10]:
array([<__main__.Raiser object at 0x0000000007F7BA20>,
<__main__.Raiser object at 0x0000000007F7B908>, 5, 8,
<__main__.Raiser object at 0x0000000007F7B940>, 9,
<__main__.Raiser object at 0x0000000007F7B978>,
<__main__.Raiser object at 0x0000000007F7B9E8>, 3,
<__main__.Raiser object at 0x0000000007F7BA58>, 2,
<__main__.Raiser object at 0x0000000007F7BA90>,
<__main__.Raiser object at 0x0000000007F7B9B0>, 1,
<__main__.Raiser object at 0x0000000007F7B898>, 6, 7, 4, 0,
<__main__.Raiser object at 0x0000000007F7BAC8>], dtype=object) |
we can't as we are using C quicksort for object arrays which has no early bailout option. We could reimplement it of course. The only way to prevent objects moving is to do a copy before sorting, which is explicitly what one does not want to do with inplace sorting. If the array should be unchanged after a failure the user must use a out of place sort (np.sort) |
Okay, just wanted to check. Thanks for clarifying! |
@juliantaylor Is that the reason why |
Yeah, I think objects moving is a non-issue, this isn't an ACID database Re: lack of bailout: okay, but then we should still propagate the error On Mon, Oct 7, 2013 at 3:56 PM, Julian Taylor notifications@github.comwrote:
|
@cpclout yes it uses @njsmith the latter, after each comparison cpython goes into adjust_tp_compare(comparison_result) |
I think this is because |
We could reimplement it of course. I've been planning to do that for the sort functions for several years now ;) All as part of cleaning up the ugly calling code for those sorting functions that get passed a comparison function. |
we can't as we are using C quicksort for object arrays I do have a numpy version of quicksort that has been sitting in a branch for the last 18 mos that, IIRC, does fix that problem. |
We (@cpcloud and I) were investigating this strange problem with pandas where we were getting
RuntimeWarning: tp_compare didn't return -1 or -2 for exception
only on OSX. We narrowed down the issue all the way to this specific set of circumstances (it may occur other ways, but this at least triggers it). Given that it still fails with an Exception, not sure if it actually matters:datetime.datetime
or a Cythonized cdef'd class) or a pure Python classHere's an example:
generates an Exception and a warning about
tp_compare
:Same thing occurs if you create an array of datetimes + integers.
We're not sure what actually causes the warning, but we're thinking the reason length matters has to do with the choice of sort algorithm:
The text was updated successfully, but these errors were encountered: