Repository navigation
ENH/API: Change flexible types to indicate resizability with elsize == -1 - #8970
eric-wieser wants to merge 5 commits into
Conversation
|
I think this all makes sense to me. I never paid as close attention to the cases of using |
977268a to
0d96866
Compare
There was a problem hiding this comment.
this should be just Py_BuildValue('(Oi)', type, 1)
There was a problem hiding this comment.
Yeah, I did it this way for speed - perhaps premature optimization
There was a problem hiding this comment.
type needs casting to PyObject then.
The error checking above, while it won#t happen in practice may throw errors with static reference checker
There was a problem hiding this comment.
also for speed PyTuple_Pack is usually good
There was a problem hiding this comment.
Good catch. Think I might go for Py_BuildValue anyway here, since creating zeros of string type doesn't sound like something that should be a bottleneck
There was a problem hiding this comment.
I'd be surprised if what I have here is slower than PyTuple_Pack, since that at best does a loop with these lines in
There was a problem hiding this comment.
PyTuple_Pack is (marginally) slower than directly setting a few entries but faster than Py_BuildValue if you already have objects.
Here it would be useful to save some lines of code, this doesn't seem to be a performance relevant path to me.
There was a problem hiding this comment.
Alright, changed to use Py_BuildValue("Ni", (PyObject*)type, 1)
There was a problem hiding this comment.
adding and example and dtypes is better, e.g. unsized dtypes (``S``) from sized-to-zero dtypes (``S0``)
it should also mention that the python-side returns None for unsized dtypes.
There was a problem hiding this comment.
Is this too breaking a change? Any C code that constructs flexible dtypes manually is in for a bad time - but hopefully nothing ever should, since PyArray_DescrFromTypeObject(Py_String) etc already do the right things
There was a problem hiding this comment.
yes it previously returned a number now it doesn't. Likely not a big deal in practice but it should be mentioned.
There was a problem hiding this comment.
Sorry, I mean from the C api perspective. But yes, I agree it at the very least needs to be in the release notes
There was a problem hiding this comment.
Yes it has the potential to break others code that assumes itemsize is always positive.
But at least it should be an easy to detect error as it will probably crash by trying to allocate 2GiB of memory.
There was a problem hiding this comment.
I was thinking code that assumed setting elsize to 0 would allow it to resize would be surprised when it no longer does
There was a problem hiding this comment.
does this work with overlapping input and output?
There was a problem hiding this comment.
These don't overlap - tuple contains a copy of the value in type, not a pointer to the variable &type
There was a problem hiding this comment.
really? I though setitem will just increase the reference count of type by 1 not actually make a copy of it.
There was a problem hiding this comment.
SET_ITEM actually doesn't touch the reference count at all - it steals the reference.
But SetItem copies type but increases the reference count of *type. We would be free to set type = NULL after adding it to the tuple, and the tuple would still contain the right thing
There was a problem hiding this comment.
yes but PyArray_DescrConverter would still be working inplace, its output type is the same object as its input type. It probably works fine but that should be checked.
There was a problem hiding this comment.
No it isn't, because PyArray_DescrConverter does essentially *(&type) = CreateNewDescr. It never touches the original object - because normally that original object is NULL
There was a problem hiding this comment.
if it does this it doesn't work because creating a new type into type overwrites the input before it is read.
There was a problem hiding this comment.
oh it does work as its &type not type never mind then
There was a problem hiding this comment.
No it doesn't, because the input is no longer the type variable - it's the copy of the pointer the type variable held, which is stored inside tuple. So for example
type = (PyObject *) 0x00001230
Tuple_SETITEM(tuple, 0, type);
Tuple_GETITEM(tuple, 0); // returns (PyObject *) 0x00001230
type = NULL
Tuple_GETITEM(tuple, 0); // still returns (PyObject *) 0x00001230 - we didn't store a pointer to type
juliantaylor
left a comment
There was a problem hiding this comment.
looks good with some minor comments
|
Any suggestions for what to call |
|
hm it seems to crash astropys testsuite which would make it a too invasive change for now. |
|
Which part causes the crash? It might be that we can just warn and keep the old behaviour in those places |
|
no clue, astropys test system is not exactly easy to use |
|
Comments addressed, hopefully. @mhvk: Mind taking a look at the astropy failure, and seeing whether it can be worked around here? |
|
seems to be division by 0 in |
|
Nice catch! There are more of those elsewhere too... |
If you feel it's too complicated please open an issue on the astropy tracker or on the astropy-dev mailing list. It would be definetly helpful to get this kind of feedback - at least I would like to know what makes it "not easy to use". :) Sorry for being off-topic here. |
|
@MSeifert04 |
|
@eric-wieser - I cannot seem to install this branch: |
|
@juliantaylor - astropy uses |
|
@mhvk: fixed. Note that this last commit is fixing bugs that were already present, just really hard to come across before this changeset |
There was a problem hiding this comment.
your mul_with_overflow are wrong, its *result, a, b
There was a problem hiding this comment.
Alarming that runtest.py -b on windows does not warn me about that
There was a problem hiding this comment.
our travis warning check catches it
There was a problem hiding this comment.
Indeed, but that's pretty late in the pipeline, and it runs a bunch of other tests first
14e5c4e to
9f746e6
Compare
|
(rebased on top of #8977) |
|
☔ The latest upstream changes (presumably #8971) made this pull request unmergeable. Please resolve the merge conflicts. |
This allows us to change how flexible types with no length are represented in future, to allow zero-size dtypes (numpy#8970).
|
(Rebased on top of #9953) |
|
additional rebase needed |
This allows empty strings to be unambigiously specified. Unsized strings continue to promote to single-character strings.
This argument is no longer used
d9b2d23 to
bc393a8
Compare
This means that zero-size strings/unicode/void are now properly supported - in that
S0,V0, andU0always mean zero-size, not resizable. Follows from #6430, cc @embraySome changes resulting from this:
np.dtype('S')andnp.dtype('S0')now mean different things - "resizable" and "empty"np.dtype(x).itemsizeisNonewhenxis:str,bytes,unicode,np.void,'S','U','V'Previously, it was
0np.dtype([('a', float), ('b', str)])is now aValueErrorPreviously, it implied
np.dtype([('a', float), ('b', str, 0)]), with the last field as size0, likely masking bugs. This explicit form works without errors- removed since this change gains nothingnp.empty(10, str)now has dtypeS0, notS1.We could be a little stricter here, and make it a
ValueErroras aboveFor the last two, we could take a more gradual deprecation path if necessary, keeping the existing behaviour but with a
FutureWarningIt's probably worth adding a#define PyDescr_Resizable -1somewhere, and using that everywhere - but I'm sure of the best name, nor the best file to put it in