Skip to content

ENH: call np.positive in ndarray.__pos__, and issue a deprecation warning when it falls #9081

Closed

Description

@shoyer

As I wrote in #8967 (comment):

Probably, the desired behavior is something like:

def __pos__(self):
    try:
        return np.positive(self)
    except TypeError:
        issue deprecation warning
        return self.copy()

(This may be a little tricky, though, because it will need to be done in C.)

This will be useful for ndarray subclasses that override __array_ufunc__.

Activity

  1. eric-wieser commented on May 10, 2017

    @eric-wieser
    Member

    I think you also want if self.__array_ufunc__ != ndarray.__array_ufunc__ in there, so that if __array_ufunc__ raises an unrelated TypeError, it's not just swallowed

  2. njsmith commented on May 10, 2017

    @njsmith
    Member

    In fact, that could potentially replace the TypeError catch altogether?

    if self.__array_ufunc__ is not ndarray.__array_ufunc__:
        return np.positive(self)
    else:
        return self.copy()

    I don't think we'd even need to deprecate anything if we did it this way.

  3. eric-wieser commented on May 10, 2017

    @eric-wieser
    Member

    Difference would be that __array_wrap__ would never see np.positive, but I don't think we care. So that does sound like a good solution

  4. njsmith commented on May 10, 2017

    @njsmith
    Member

    Or more precisely, __array_wrap__ would see explicit calls to np.positive, but wouldn't see calls to __pos__ (just like today). And that's actually probably what we want, since we don't want to risk breaking existing __array_wrap__ users.

  5. shoyer commented on May 10, 2017

    @shoyer
    MemberAuthor

    I don't think we'd even need to deprecate anything if we did it this way.

    I also wanted to deprecate calls like +np.array(['foo']), which currently works but should really raise an error.

    But we could switch to only catching TypeError if __array_ufunc__ is not set. Something like:

    def __pos__(self):
        if self.__array_ufunc__ is not ndarray.__array_ufunc__:
            return np.positive(self)
        else:
            try:
                return np.positive(self)
            except TypeError:
                issue deprecation warning
                return self.copy()

    This would give us a path to eventually replacing the implementation with:

    def __pos__(self):
        return np.positive(self)
  6. ngoldbaum commented on May 23, 2017

    @ngoldbaum
    Member

    I'll just say that it would be really nice if np.positive were invoked by operator.pos. With __array_ufunc__ I've been able to remove all of the magic method overrides on my ndarray subclass except for the override for __pos__ due to this issue.

  7. eric-wieser commented on May 23, 2017

    @eric-wieser
    Member

    @ngoldbaum: Although it's also really not hard for you to use def __pos__(self): return np.positive(self) until this is fixed :)

  8. ngoldbaum commented on May 23, 2017

    @ngoldbaum
    Member

    I realize, it's just yet another corner case that an implementer of an ndarray subclass needs to deal with.

  9. shoyer commented on May 23, 2017

    @shoyer
    MemberAuthor

    @ngoldbaum this logic is all pretty self-contained (I would start here), so implementing something like @njsmith's suggestion both would be straightforward. Contributions would certainly be welcome!

    It would indeed be nice to get this into 1.13 before the final release.

  10. mhvk commented on Jun 29, 2018

    @mhvk
    Contributor

    See #11450 for a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions