[Numpy-discussion] copy="never" discussion and no deprecation cycle?

Stefan van der Walt stefanv at berkeley.edu
Wed Jun 23 14:09:14 EDT 2021


Perhaps it is also worth going back to explore our original motivation for making this change.

One reason was that Sebastian didn't like people doing `x.shape = ...`.  Users do that, presumably, to trigger an error if a copy needs to be made.  However, we can catch that already:

x = np.reshape(y, ...)
if np.may_share_memory(x, y):
    ...

We can fix Sebastian's issue by introducing a `copy` keyword to `reshape`, which currently has none:

x = np.reshape(y, copy='never')

For consistency, it would be nice to have `np.array` support copy=never, but if there is no urgency we can take the long route towards an API that uses strings (consistent with the rest of NumPy).

The arguments against string names *right now* is that, if users write code with `copy='if-needed'` it will not work correctly with old NumPy code, since old versions will evaluate `if-needed` to True.  The assessment was that this happens frequently, but we should consider how frequently, and how big of an issue it is.

So, I guess ultimately I am wondering if the change to `np.array` is needed right now, or whether we can get away without it for a while.

Stéfan

On Tue, Jun 22, 2021, at 15:21, bas van beek wrote:
> > Stefan, that sketch is more complicated than it needs to be - `np.copy` is a python function, so you can just attach the attributes directly! (although maybe there are implications for static typing)
> 
> For the type annotations we can simply use something akin to Stéfans proposed `NpCopy` class; 
> probably in combination with `Protocol`.
> It's a bit more work compared to annotating a normal python function, but it's quite easy nevertheless.
> 
> Regards, Bas
> 
> 
> *From:* NumPy-Discussion <numpy-discussion-bounces+bas.vanbeek=hotmail.com at python.org> on behalf of Eric Wieser <wieser.eric+numpy at gmail.com>
> *Sent:* 21 June 2021 18:56
> *To:* Discussion of Numerical Python <numpy-discussion at python.org>
> *Subject:* Re: [Numpy-discussion] copy="never" discussion and no deprecation cycle? 
>  
> 
> Stefan, that sketch is more complicated than it needs to be - `np.copy` is a python function, so you can just attach the attributes directly! (although maybe there are implications for static typing)
> ```
> class CopyFlag(enum.Enum):
>     IF_NEEDED = 0
>     ALWAYS = 1
>     NEVER = 2
> 
> np.copy.IF_NEEDED = CopyFlag.IF_NEEDED
> np.copy.ALWAYS = CopyFlag.ALWAYS
> np.copy.NEVER = CopyFlag.NEVER
> ```
> It would also work nicely for the `True/False/other` version that was proposed in the much older PR as `np.never_copy`:
> ```
> class _CopyNever:
>     def __bool__(self): raise ValueError
> 
> np.copy.NEVER = _CopyNever()
> ```
> 
> All of these versions (and using the enum directly) seem fine to me.
> If we go down the enum route route, we probably want to add "new-style" versions of `np.CLIP` and friends that are true enums / live within a more obvious namespace.
> 
> Eric 
> 
> On Mon, 21 Jun 2021 at 17:24, Stefan van der Walt <stefanv at berkeley.edu> wrote:
>> On Sun, Jun 20, 2021, at 20:46, Gagandeep Singh wrote:
>> > I have recently joined the mailing list and have gone through the previous discussions on this thread. I would like to share my analysis (advantages and disadvantages) of three possible alternatives (Enum, String, boolean) to support the proposed feature.
>> 
>> Thanks for this thorough analysis, Gagandeep!
>> 
>> I'll throw one more heretical idea out there:
>> 
>> `np.copy.IF_NEEDED`, `np.copy.ALWAYS`, `np.copy.NEVER`.
>> 
>> This has the advantages of the enum, doesn't pollute the global namespace, and has an intuitive name.
>> 
>> `np.array(x, copy=np.copy.ALWAYS)`
>> 
>> It would be slightly more awkward to type, but is doable.  A rough Python version sketch would be:
>> 
>> class CopyFlag(enum.Enum):
>>     IF_NEEDED = 0
>>     ALWAYS = 1
>>     NEVER = 2
>> 
>> class NpCopy:
>>     IF_NEEDED : CopyFlag = CopyFlag.IF_NEEDED
>>     ALWAYS : CopyFlag = CopyFlag.ALWAYS
>>     NEVER : CopyFlag = CopyFlag.NEVER
>> 
>>     def __call__(self, x):
>>         return ...whatever copy returns...
>> 
>> np.copy = NpCopy()
>> 
>> 
>> Stéfan
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion at python.org
>> https://mail.python.org/mailman/listinfo/numpy-discussion
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at python.org
> https://mail.python.org/mailman/listinfo/numpy-discussion
> 


More information about the NumPy-Discussion mailing list