Skip to content

Empty tables are equal to None but are not None??? #8640

Closed

Description

@mcara

Let the code speak for itself:

>>> from astropy.table import Table
>>> Table() is None
False
>>> Table() == None                                                                                                        
True

Why? For me this is unexpected. Is this documented anywhere? Is this a bug?

Activity

  1. pllim commented on Apr 25, 2019

    @pllim
    Member

    Firstly, is None or == None is not the right thing to do when you want to check if table is empty or not. The proper way is:

    >>> t = Table()
    >>> len(t) == 0
    True

    Secondly, this behavior is because Table.__eq__ is not the same as is. You can check out the __eq__ implementation in table.py yourself.

    >>> t
    <Table length=0>
    <No columns>
    

    An empty table, as shown above, is clearly not returning None. That is why is None is False. On the other hand, == invokes self.as_array() == other and in your case, t.as_array() is None. Hence, the behavior you are seeing.

  2. added
    Close?Tell stale bot that this issue/PR is stale
    on Apr 25, 2019
  3. mcara commented on Apr 25, 2019

    @mcara
    ContributorAuthor

    The explanation for the cause is great but is this what is supposed to be? Is this documented? Is this obvious and should not be documented?

    From http://docs.astropy.org/en/stable/api/astropy.table.Table.html#astropy.table.Table.as_array:

    as_array(keep_byteorder=False)
    Return a new copy of the table in the form of a structured np.ndarray or np.ma.MaskedArray object (as appropriate).
    table_array: np.ndarray (unmasked) or np.ma.MaskedArray (masked)
    Copy of table as a numpy structured array

    Documentation for as_array() does not mention that it can return None and under what circumstances it might do so. A regular user does not know that __eq__() is overwritten and calls as_array(). My guess is that this is a bug.

  4. pllim commented on Apr 25, 2019

    @pllim
    Member

    Pretty sure returning None is intentional, but good point on clarifying the doc.

    if len(self.columns) == 0:
    return None

  5. removed
    Close?Tell stale bot that this issue/PR is stale
    on Apr 25, 2019
  6. mcara commented on Apr 26, 2019

    @mcara
    ContributorAuthor

    Pretty sure returning None is intentional...

    It may have been intentional but I am not sure it is necessarily the right thing to do. I am intuitively expecting as_array() to actually return an array but returning None would be OK if it is impossible to return an empty array for consistency purpose. However, since empty tables are allowed, why would empty arrays not allowed/returned? I am not saying one approach is better than the other but something needs to be done here (docs or code).

    Removing if len(self.columns) == 0: return None from as_array() makes as_array() return empty array of raw type. (why not float64 since this is the default type for tables with columns but not data?)

    Also the fact that Table() == None is true is just weird. What does it mean?

  7. pllim commented on Apr 26, 2019

    @pllim
    Member

    @taldcroft , any input?

  8. disha012 commented on Apr 28, 2019

    @disha012
    Contributor

    So, what is finally to be done in order to solve this issue?
    If, in case, there is a change to be made to the docs or the code, I would like to work on it.

  9. geekypathak21 commented on Apr 28, 2019

    @geekypathak21
    Contributor

    @disha012 We have to Wait for @taldcroft to suggest what we have to do either changes in docs or code. He is on a vacation so we have to wait for some time.

  10. mhvk commented on Apr 29, 2019

    @mhvk
    Contributor

    Hmm, let me pipe in as table co-maintainer: I consider it a bug that Table() == None evaluates to True.

    Looking at the cause, I agree with @mcara that it doesn't make much sense to return None in as_array for an empty Table - if the user asked for an array, they should get one! So I think returning an empty array is fine, and I like the suggestion to just remove the if clause altogether, as things will work out that way. (Also a nice example of "Special cases aren't special enough to break the rules", though we should see whether the next one, "Although practicality beats purity", holds...)

    @mcara - did you already make the change and want to turn it in a PR? If not, @disha012, if you want to try that, that would be great!

    Note that it may be that some Table tests will fail - we will then have to look if it is reasonable to change those, or whether that would cause more trouble than it is worth.

  11. added and removed on Apr 29, 2019
  12. mcara commented on Apr 29, 2019

    @mcara
    ContributorAuthor

    I can make a PR but I was waiting for a decision on whether this is a bug or a documentation issue. Thanks for feedback

  13. pllim commented on Apr 29, 2019

    @pllim
    Member

    For completeness, those LOCs in questions were originally added in #2790

  14. mhvk commented on Apr 29, 2019

    @mhvk
    Contributor

    @pllim - thanks for looking that up. That PR was a pretty major overhaul, so not so surprising that something might have slipped through review.

    @mcara - curious to see whether there are any test failures with your suggested change!

  15. mcara commented on Apr 29, 2019

    @mcara
    ContributorAuthor

    @mhvk There were 9 total failures in 3 tests due to assert self.t.as_array() is None tests. PR #8647 modified tests accordingly.

  16. mhvk commented on Apr 29, 2019

    @mhvk
    Contributor

    OK, those tests explicitly were for the code not behaving as documented, so I think it is fine to change them - anyway, just left my very brief review; let's move further discussion about the changes there.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions