<div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">@Matthias:</p>
<blockquote style="margin:1.2em 0px;border-left:4px solid rgb(221,221,221);padding:0px 1em;color:rgb(119,119,119);quotes:none">
<p style="margin:0px 0px 1.2em!important">Most of the time I would not assign to arr.shape, but in some rare occasions I find it very useful.</p>
<p style="margin:0px 0px 1.2em!important">And one of those rare occasions is when you want guaranteed no-copy behavior.</p>
</blockquote>
<p style="margin:0px 0px 1.2em!important">Can you come up with any other example?<br>The only real argument you seem to have here is “my code uses <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">arr.shape = ...</code>“ and I don’t want it to break. That’s a fair argument, but all it really means is we should start emitting <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">DeprecationWarning("Use arr = arr.reshape(..., copy=np.never_copy) instead of arr.shape = ...")</code>, and consider having a long deprecation.<br>If necessary we could compromise on just putting a warning in the docs, and not notifying the user at all.</p>
<p style="margin:0px 0px 1.2em!important">@Ralf</p>
<blockquote style="margin:1.2em 0px;border-left:4px solid rgb(221,221,221);padding:0px 1em;color:rgb(119,119,119);quotes:none">
<p style="margin:0px 0px 1.2em!important">np.newaxis is not relevant here - it’s a simple alias for None, is just there for code readability, and is much more widely applicable than np.never_copy would be.</p>
</blockquote>
<p style="margin:0px 0px 1.2em!important">Is there any particular reason we chose to use <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">None</code>? If I were designing it again, I’d consider a singleton object with a better <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">__repr__</code></p>
<p style="margin:0px 0px 1.2em!important">@Nathaniel</p>
<blockquote style="margin:1.2em 0px;border-left:4px solid rgb(221,221,221);padding:0px 1em;color:rgb(119,119,119);quotes:none">
<p style="margin:0px 0px 1.2em!important">I guess another possibility to throw out there would be a second kwarg, require_view=False/True.</p>
</blockquote>
<p style="margin:0px 0px 1.2em!important">The downside of this approach is that array-likes will definitely need updating to support this new behavior, whereas many may work out of the box if we extend the <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">copy</code> argument (like, say, maskedarray). This also ties into the <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">__bool__</code> override - that will ensure that subclasses which don’t have a trivial reshape crash.</p>
<p style="margin:0px 0px 1.2em!important">@Sebastian:</p>
<blockquote style="margin:1.2em 0px;border-left:4px solid rgb(221,221,221);padding:0px 1em;color:rgb(119,119,119);quotes:none">
<p style="margin:0px 0px 1.2em!important">Unless we replace the string when dispatching, which seems strange on first sight.</p>
</blockquote>
<p style="margin:0px 0px 1.2em!important">I’m envisaging cases where we don’t have a dispatcher at all:</p>
<ul style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">Duck arrays implementing methods matching ndarray</li>
<li style="margin:0.5em 0px">Something like <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">my_custom_function(arr, copy=...)</code> that forwards its copy argument to <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">reshape</code></li>
</ul>
<p style="margin:0px 0px 1.2em!important">Eric</p>
<div title="MDH:PGRpdj5ATWF0dGhpYXM6PC9kaXY+PGRpdj48YnI+PC9kaXY+Jmd0O8KgPHNwYW4gc3R5bGU9ImNv
bG9yOiByZ2IoMzMsIDMzLCAzMyk7Ij5Nb3N0IG9mIHRoZSB0aW1lIEkgd291bGQgbm90IGFzc2ln
biB0byBhcnIuc2hhcGUsIGJ1dCBpbiBzb21lIHJhcmUmbmJzcDs8L3NwYW4+PHNwYW4gc3R5bGU9
ImNvbG9yOiByZ2IoMzMsIDMzLCAzMyk7Ij5vY2Nhc2lvbnMgSSBmaW5kIGl0IHZlcnkgdXNlZnVs
Ljwvc3Bhbj48YnIgc3R5bGU9ImNvbG9yOiByZ2IoMzMsIDMzLCAzMyk7Ij4mZ3Q7wqA8YnIgc3R5
bGU9ImNvbG9yOiByZ2IoMzMsIDMzLCAzMyk7Ij48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigzMywg
MzMsIDMzKTsiPiZndDsgQW5kIG9uZSBvZiB0aG9zZSByYXJlIG9jY2FzaW9ucyBpcyB3aGVuIHlv
dSB3YW50IGd1YXJhbnRlZWQgbm8tY29weSBiZWhhdmlvci48YnI+PGJyPkNhbiB5b3UgY29tZSB1
cCB3aXRoIGFueSBvdGhlciBleGFtcGxlPzwvc3Bhbj48ZGl2PjxzcGFuIHN0eWxlPSJjb2xvcjog
cmdiKDMzLCAzMywgMzMpOyI+VGhlIG9ubHkgcmVhbCBhcmd1bWVudCB5b3Ugc2VlbSB0byBoYXZl
IGhlcmUgaXMgIm15IGNvZGUgdXNlcyBgYXJyLnNoYXBlID0gLi4uYCIgYW5kIEkgZG9uJ3Qgd2Fu
dCBpdCB0byBicmVhay4gVGhhdCdzIGEgZmFpciBhcmd1bWVudCwgYnV0IGFsbCBpdCByZWFsbHkg
bWVhbnMgaXMgd2Ugc2hvdWxkIHN0YXJ0IGVtaXR0aW5nIGBEZXByZWNhdGlvbldhcm5pbmcoIlVz
ZSBhcnIgPSBhcnIucmVzaGFwZSguLi4sIGNvcHk9bnAubmV2ZXJfY29weSkgaW5zdGVhZCBvZiBh
cnIuc2hhcGUgPSAuLi4iKWAsIGFuZCBjb25zaWRlciBoYXZpbmcgYSBsb25nIGRlcHJlY2F0aW9u
Ljwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDMzLCAzMywgMzMpOyI+
SWYgbmVjZXNzYXJ5IHdlIGNvdWxkIGNvbXByb21pc2Ugb24ganVzdCBwdXR0aW5nIGEgd2Fybmlu
ZyBpbiB0aGUgZG9jcywgYW5kIG5vdCBub3RpZnlpbmcgdGhlIHVzZXIgYXQgYWxsLjwvc3Bhbj48
L2Rpdj48ZGl2PjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDMzLCAzMywgMzMpOyI+PGJyPjwvc3Bh
bj48L2Rpdj48ZGl2PjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDMzLCAzMywgMzMpOyI+QFJhbGY8
L3NwYW4+PC9kaXY+PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigzMywgMzMsIDMzKTsiPjxi
cj48L3NwYW4+PC9kaXY+PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigzMywgMzMsIDMzKTsi
PiZndDsmbmJzcDs8L3NwYW4+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMzMsIDMzLCAzMyk7Ij5u
cC5uZXdheGlzIGlzIG5vdCByZWxldmFudCBoZXJlIC0gaXQncyBhIHNpbXBsZSBhbGlhcyBmb3Ig
Tm9uZSwgaXMganVzdCB0aGVyZSBmb3IgY29kZSByZWFkYWJpbGl0eSwgYW5kIGlzIG11Y2ggbW9y
ZSB3aWRlbHkgYXBwbGljYWJsZSB0aGFuIG5wLm5ldmVyX2NvcHkgd291bGQgYmUuPC9zcGFuPjwv
ZGl2PjxkaXY+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMzMsIDMzLCAzMyk7Ij48YnI+PC9zcGFu
PjwvZGl2PjxkaXY+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMzMsIDMzLCAzMyk7Ij5JcyB0aGVy
ZSBhbnkgcGFydGljdWxhciByZWFzb24gd2UgY2hvc2UgdG8gdXNlIGBOb25lYD8gSWYgSSB3ZXJl
IGRlc2lnbmluZyBpdCBhZ2FpbiwgSSdkIGNvbnNpZGVyIGEgc2luZ2xldG9uIG9iamVjdCB3aXRo
IGEgYmV0dGVyIGBfX3JlcHJfX2A8L3NwYW4+PC9kaXY+PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6
IHJnYigzMywgMzMsIDMzKTsiPjxicj48L3NwYW4+PC9kaXY+PGRpdj48c3BhbiBzdHlsZT0iY29s
b3I6IHJnYigzMywgMzMsIDMzKTsiPkBOYXRoYW5pZWw8YnI+PGJyPiZndDsmbmJzcDs8L3NwYW4+
PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMzMsIDMzLCAzMyk7Ij5JIGd1ZXNzIGFub3RoZXIgcG9z
c2liaWxpdHkgdG8gdGhyb3cgb3V0IHRoZXJlIHdvdWxkIGJlIGEgc2Vjb25kJm5ic3A7PC9zcGFu
PjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDMzLCAzMywgMzMpOyI+a3dhcmcsIHJlcXVpcmVfdmll
dz1GYWxzZS9UcnVlLjwvc3Bhbj48L2Rpdj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigzMywgMzMs
IDMzKTsiPjxicj48L3NwYW4+PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigzMywgMzMsIDMz
KTsiPlRoZSBkb3duc2lkZSBvZiB0aGlzIGFwcHJvYWNoIGlzIHRoYXQgYXJyYXktbGlrZXMgd2ls
bCBkZWZpbml0ZWx5IG5lZWQgdXBkYXRpbmcgdG8gc3VwcG9ydCB0aGlzIG5ldyBiZWhhdmlvciwg
d2hlcmVhcyBtYW55IG1heSB3b3JrIG91dCBvZiB0aGUgYm94IGlmIHdlIGV4dGVuZCB0aGUgYGNv
cHlgIGFyZ3VtZW50IChsaWtlLCBzYXksIG1hc2tlZGFycmF5KS4gVGhpcyBhbHNvIHRpZXMgaW50
byB0aGUgYF9fYm9vbF9fYCBvdmVycmlkZSAtIHRoYXQgd2lsbCBlbnN1cmUgdGhhdCBzdWJjbGFz
c2VzIHdoaWNoIGRvbid0IGhhdmUgYSB0cml2aWFsIHJlc2hhcGUgY3Jhc2guPC9zcGFuPjwvZGl2
PjxkaXY+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMzMsIDMzLCAzMyk7Ij48YnI+PC9zcGFuPjwv
ZGl2PjxkaXY+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMzMsIDMzLCAzMyk7Ij5AU2ViYXN0aWFu
Ojxicj48YnI+Jmd0OyZuYnNwOzwvc3Bhbj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigzMywgMzMs
IDMzKTsiPlVubGVzcyB3ZSByZXBsYWNlIHRoZSBzdHJpbmcgd2hlbiBkaXNwYXRjaGluZywgd2hp
Y2ggc2VlbXMgc3RyYW5nZSBvbiZuYnNwOzwvc3Bhbj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigz
MywgMzMsIDMzKTsiPmZpcnN0IHNpZ2h0Ljwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuIHN0eWxlPSJj
b2xvcjogcmdiKDMzLCAzMywgMzMpOyI+PGJyPjwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuIHN0eWxl
PSJjb2xvcjogcmdiKDMzLCAzMywgMzMpOyI+SSdtIGVudmlzYWdpbmcgY2FzZXMgd2hlcmUgd2Ug
ZG9uJ3QgaGF2ZSBhIGRpc3BhdGNoZXIgYXQgYWxsOjxicj4qIER1Y2sgYXJyYXlzIGltcGxlbWVu
dGluZyBtZXRob2RzIG1hdGNoaW5nIG5kYXJyYXk8YnI+KiBTb21ldGhpbmcgbGlrZSBgbXlfY3Vz
dG9tX2Z1bmN0aW9uKGFyciwgY29weT0uLi4pYCB0aGF0IGZvcndhcmRzIGl0cyBjb3B5IGFyZ3Vt
ZW50IHRvIGByZXNoYXBlYDwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuIHN0eWxlPSJjb2xvcjogcmdi
KDMzLCAzMywgMzMpOyI+PGJyPjwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuIHN0eWxlPSJjb2xvcjog
cmdiKDMzLCAzMywgMzMpOyI+RXJpYzwvc3Bhbj48L2Rpdj4=" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0">​</div></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, 7 Jan 2019 at 11:05 Matthias Geier <<a href="mailto:matthias.geier@gmail.com">matthias.geier@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, Jan 2, 2019 at 2:24 PM Sebastian Berg wrote:<br>
><br>
> On Wed, 2019-01-02 at 11:27 +0100, Matthias Geier wrote:<br>
> > Hi Sebastian.<br>
> ><br>
> > Thanks for the clarification.<br>
> ><br>
> <snip><br>
> > > print(arr.shape)  # also (5, 2)<br>
> > ><br>
> > > so the arr container (shape, dtype) is changed/muted. I think we<br>
> > > expect<br>
> > > that for content here, but not for the shape.<br>
> ><br>
> > Thanks for the clarification, I think I now understand your example.<br>
> ><br>
> > However, the behavior you are describing is just like the normal<br>
> > reference semantics of Python itself.<br>
> ><br>
> > If you have multiple identifiers bound to the same (mutable) object,<br>
> > you'll always have this "problem".<br>
> ><br>
> > I think every Python user should be aware of this behavior, but I<br>
> > don't think it is reason to discourage assigning to arr.shape.<br>
><br>
> Well, I doubt I will convince you.<br>
<br>
I think we actually have quite little disagreement.<br>
<br>
I agree with you on what should be done *most of the time*, but I<br>
wouldn't totally discourage mutating NumPy array shapes, because I<br>
think in the right circumstances it can be very useful.<br>
<br>
> But want to point out that a numpy<br>
> array is:<br>
><br>
>   * underlying data<br>
>   * shape/strides (pointing to the exact data)<br>
>   * data type (interpret the data)<br>
><br>
> Arrays are mutable, but this is only half true from my perspective.<br>
> Everyone using numpy should be aware of "views", i.e. that the content<br>
> of the underlying data can change.<br>
<br>
I agree, everyone should be aware of that.<br>
<br>
> However, if I have a read-only array, and pass it around, I would not<br>
> expect it to change. That is because while the underlying data is<br>
> muted, how this data is accessed and interpreted is not.<br>
><br>
> In other words, I see array objects as having two sides to them [0]:<br>
><br>
>   * Underlying data   -> normally mutable and often muted<br>
>   * container:        -> not muted by almost all code<br>
>       * shape/strides<br>
>       * data type<br>
<br>
Exactly: "almost all code".<br>
<br>
Most of the time I would not assign to arr.shape, but in some rare<br>
occasions I find it very useful.<br>
<br>
And one of those rare occasions is when you want guaranteed no-copy behavior.<br>
<br>
There are also some (most likely significantly rarer) cases where I<br>
would modify arr.strides.<br>
<br>
> I realize that in some cases muting the container metadata happens. But<br>
> I do believe it should be as minimal as possible. And frankly, probably<br>
> one could do away with it completely.<br>
<br>
I guess that's the only point where we disagree.<br>
<br>
I wouldn't completely discourage it and I would definitely not remove<br>
the functionality.<br>
<br>
> Another example for where it is bad would be a threaded environment. If<br>
> a python function temporarily changes the shape of an array to read<br>
> from it without creating a view first, this will break multi-threaded<br>
> access to that array.<br>
<br>
Sure, let's not use it while multi-threading then.<br>
<br>
I still think that's not at all a reason to remove the feature.<br>
<br>
There are some things that are problematic when multi-threading, but<br>
that's typically not reason enough to completely disallow them.<br>
<br>
cheers,<br>
Matthias<br>
<br>
><br>
> - Sebastian<br>
><br>
><br>
> [0] I tried to find other examples for such a split. Maybe a<br>
> categorical/state object which is allowed change value/state. But the<br>
> list of possible states cannot change.<br>
><br>
><br>
> > Coming back to the original suggestion of this thread:<br>
> > Since assigning to arr.shape makes sure no copy of the array data is<br>
> > made, I don't think it's necessary to add a new no-copy argument to<br>
> > reshape().<br>
> ><br>
> > But the bug you mentioned ("on error the `arr.shape = ...` code<br>
> > currently creates the copy temporarily") should probably be fixed at<br>
> > some point ...<br>
> ><br>
> > cheers,<br>
> > Matthias<br>
> ><br>
> > > - Sebastian<br>
> > ><br>
> > ><br>
> > > > > There may be some corner cases, but a lot of the<br>
> > > > > "than why is it allowed" questions are answered with: for<br>
> > > > > history<br>
> > > > > reasons.<br>
> > > ><br>
> > > > OK, that's a good point.<br>
> > > ><br>
> > > > > By the way, on error the `arr.shape = ...` code currently<br>
> > > > > creates<br>
> > > > > the<br>
> > > > > copy temporarily.<br>
> > > ><br>
> > > > That's interesting and it should probably be fixed.<br>
> > > ><br>
> > > > But it is not reason enough for me not to use it.<br>
> > > > I find it important that is doesn't make a copy in the success<br>
> > > > case,<br>
> > > > I<br>
> > > > don't care very much for the error case.<br>
> > > ><br>
> > > > Would you mind elaborating on the real reasons why I shouldn't<br>
> > > > use<br>
> > > > it?<br>
> > > ><br>
> > > > cheers,<br>
> > > > Matthias<br>
> > > ><br>
> > > > > - Sebastian<br>
> > > > ><br>
> > > > ><br>
> > > > > > cheers,<br>
> > > > > > Matthias<br>
_______________________________________________<br>
NumPy-Discussion mailing list<br>
<a href="mailto:NumPy-Discussion@python.org" target="_blank">NumPy-Discussion@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/numpy-discussion" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/numpy-discussion</a><br>
</blockquote></div>