Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solving issue with wcs.wcs.cunit equality #8480

Merged
merged 3 commits into from Apr 19, 2019

Conversation

geekypathak21
Copy link
Contributor

@geekypathak21 geekypathak21 commented Mar 6, 2019

EDIT: Fix #8415

Please Help me out in this after a lot reading from here and there I was able to apply this because Embedded c with python is a new topic for me. So, please forgive any mistakes done by me .
__eq__ function was not working so I used richcompare function

@codecov
Copy link

codecov bot commented Mar 6, 2019

Codecov Report

Merging #8480 into master will decrease coverage by 0.02%.
The diff coverage is 0%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #8480      +/-   ##
==========================================
- Coverage   86.79%   86.76%   -0.03%     
==========================================
  Files         386      386              
  Lines       58098    58117      +19     
  Branches     1060     1065       +5     
==========================================
  Hits        50427    50427              
- Misses       7056     7075      +19     
  Partials      615      615
Impacted Files Coverage Δ
astropy/wcs/src/unit_list_proxy.c 46.89% <0%> (-7.08%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 69e2fab...4e080b6. Read the comment docs.

@pllim pllim requested review from astrofrog and nden March 7, 2019 00:20
@astropy astropy deleted a comment from codecov bot Mar 7, 2019
@bsipocz
Copy link
Member

bsipocz commented Mar 7, 2019

This will need testing, as a minimal one e.g. the example from the issue would do.

@codecov
Copy link

codecov bot commented Mar 8, 2019

Codecov Report

Merging #8480 into master will decrease coverage by <.01%.
The diff coverage is 62.5%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #8480      +/-   ##
==========================================
- Coverage   86.82%   86.81%   -0.01%     
==========================================
  Files         386      386              
  Lines       58197    58213      +16     
  Branches     1060     1064       +4     
==========================================
+ Hits        50530    50540      +10     
- Misses       7052     7054       +2     
- Partials      615      619       +4
Impacted Files Coverage Δ
astropy/wcs/src/unit_list_proxy.c 54.92% <62.5%> (+0.96%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fda61c9...9a91f69. Read the comment docs.

@geekypathak21
Copy link
Contributor Author

I added test for wcs.cunit @bsipocz Thanks for helping

@geekypathak21
Copy link
Contributor Author

Another wcs is added in test_wcs.py thanks for suggestion @astrofrog

@MSeifert04
Copy link
Contributor

MSeifert04 commented Mar 9, 2019

Thanks for the contribution. I found it quite hard to read the code because it doesn't follow the coding conventions in the rest of the file (nor PEP 7). Could you please re-format the code (especially with regards to whitespaces, indentation, and blank lines) to follow the style of the rest of the file?

Py_RETURN_FALSE;
}
} else {
return NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning NULL without an exception will probably result in a SystemError - or is that handled differently for richcmp? Did you check this path?

By the way I would prefer it to immediately fail in case an exception should be raised. That way one could also remove the status variable completely.

if (self->size!=other->size||self->unit_class!=other->unit_class||self->array!=other->array)
{status = 0;
equal = 0;}
else if (self == 0x0 || other == 0x0){
Copy link
Contributor

@MSeifert04 MSeifert04 Mar 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0x0? Do you mean NULL?

PyObject_TypeCheck(other, &PyUnitListProxyType)) {


if (self->size!=other->size||self->unit_class!=other->unit_class||self->array!=other->array)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is correct to use pointer equality for unit_class or array. Are these singletons?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I felt so that they are singletons. I will check it again

@MSeifert04
Copy link
Contributor

MSeifert04 commented Mar 9, 2019

Thank you for the pull request. I have some questions about the changes but I'm not really familiar with the WCS C-internals so forgive me if these may sound stupid. 😄

Btw: a first-time contributor that dares to go into Python C Extensions - I'm genuinely impressed! 👍 Let me know if you need any help or my comments don't make sense to you.

@@ -4,6 +4,8 @@
*/

#define NO_IMPORT_ARRAY
#ifndef ASTROPY_WCS_API_H
#define ASTROPY_WCS_API_H
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is correct. As far as I see this constant should be defined only in astropy_wcs_api.h

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I am removing this. It is not correct

@MSeifert04
Copy link
Contributor

MSeifert04 commented Mar 9, 2019

The flake check did detect some problems in the Python file too:

 ------ file ----------------:line:col: problem
astropy/wcs/tests/test_wcs.py:1189:23: W291 trailing whitespace
astropy/wcs/tests/test_wcs.py:1192:1: W293 blank line contains whitespace
astropy/wcs/tests/test_wcs.py:1193:39: W291 trailing whitespace
astropy/wcs/tests/test_wcs.py:1200:1: W391 blank line at end of file
astropy/wcs/tests/test_wcs.py:1200:1: W293 blank line contains whitespace

Could you fix them so the CI can succeed?

@geekypathak21
Copy link
Contributor Author

@MSeifert04 I need help I can't able to find any method to convert PyObject to C type for comparison .
Will value_fixer() work for it or not

@MSeifert04
Copy link
Contributor

@himanshupathak21061998 I'm not sure what you mean with value_fixer. Could you provide more context where you want to convert PyObject to C?

@geekypathak21
Copy link
Contributor Author

@MSeifert04 Sorry for late reply but I was not able to find any good way to compare unit_class which is a pyobject. I used RichCompareBool function to compare it thanks for your help.

Copy link
Contributor

@MSeifert04 MSeifert04 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. This looks really good.

The indentation still seems to be a bit off though and I have some comments (again).

@@ -16,6 +16,7 @@

static PyTypeObject PyUnitListProxyType;


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the additional blank line is needed

@@ -186,6 +187,59 @@ PyUnitListProxy_getitem(
return result;
}

static PyObject *
PyUnitListProxy_richcmp(
PyUnitListProxy *a,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By assuming PyUnitListProxy here instead of PyObject (see richcmpfunc) we might get segfaults if you compare them to non PyUnitListProxy. (could you add a test case for a different class?)

astropy/wcs/src/unit_list_proxy.c Outdated Show resolved Hide resolved
astropy/wcs/src/unit_list_proxy.c Outdated Show resolved Hide resolved
astropy/wcs/src/unit_list_proxy.c Outdated Show resolved Hide resolved
astropy/wcs/src/unit_list_proxy.c Outdated Show resolved Hide resolved
astropy/wcs/src/unit_list_proxy.c Outdated Show resolved Hide resolved
astropy/wcs/tests/test_wcs.py Outdated Show resolved Hide resolved
astropy/wcs/tests/test_wcs.py Outdated Show resolved Hide resolved
astropy/wcs/src/unit_list_proxy.c Outdated Show resolved Hide resolved
@MSeifert04
Copy link
Contributor

@himanshupathak21061998 Thanks for the update, this looks really good 👍

I was not able to find any good way to compare unit_class which is a pyobject. I used RichCompareBool function to compare it thanks for your help.

If unit_class implements rich-compare then this should be fine. I suspected that you meant this, but wasn't sure.

Sorry for late reply

No problem. By the way: I'm away the next few days and probably cannot reply until next Tuesday. 😅

@MSeifert04
Copy link
Contributor

MSeifert04 commented Mar 13, 2019

@pllim Sorry for pinging you - but are the test failures expected? They seem unrelated but I haven't been really active in the past so I don't know 😓

@pllim
Copy link
Member

pllim commented Mar 14, 2019

@MSeifert04 , I just saw these errors on another PR and also on cron (https://travis-ci.org/astropy/astropy/jobs/506241000). Will have to investigate but I don't think they are related to this PR.

UPDATE: Failures are unrelated and caused by #8498

@MSeifert04
Copy link
Contributor

@pllim Thank you for the investigation. 👍

I was on the mobile and did not want to look at the travis logs (because they tend to load for a while) and forgot when I came home. 😅

@geekypathak21
Copy link
Contributor Author

Not sure for the cause of error https://ci.appveyor.com/project/Astropy/astropy/builds/23131678

@MSeifert04
Copy link
Contributor

@himanshupathak21061998 Do you let me know when the comments are addressed so I can do a final review (although @nden probably needs to do the final review/approval).

@geekypathak21
Copy link
Contributor Author

geekypathak21 commented Mar 19, 2019

@MSeifert04 I am struggling with this

By assuming PyUnitListProxy here instead of PyObject (see richcmpfunc) we might get segfaults if you compare them to non PyUnitListProxy. (could you add a test case for a different class?)

Because when I accept Pyobject and compare Objects inside PyUnitListProxy struct. It always returning true can you please suggest a way to tackle this

@MSeifert04
Copy link
Contributor

MSeifert04 commented Mar 19, 2019

The richcmpfunc expects (PyObject *a, PyObject *b, int op) so the function arguments should be equal to these:

static PyObject *
PyUnitListProxy_richcmp(
    PyObject *a,
    PyObject *b,
    int op) {

Because we don't want to compare them to anything else except other PyUnitListProxy you immediately check if they are:

PyUnitListProxy *lhs, *rhs;
/* Normally these shouldn't be NULL, ever */
assert(a != NULL && b != NULL);

/* At the moment we only support comparisons of PyUnitListProxy with other instances of the same class */
if (!PyObject_TypeCheck(a, &PyUnitListProxyType) 
        || !PyObject_TypeCheck(b, &PyUnitListProxyType) {
    Py_RETURN_NOTIMPLEMENTED;
}
/* Only equality and non-equality are supported */
if (op != Py_EQ && op != Py_NE)) {
    Py_RETURN_NOTIMPLEMENTED;
}
lhs = (PyUnitListProxy *)a;
rhs = (PyUnitListProxy *)b;

Then continue with lhs and rhs.

For example I would then immediately check if PyObject_RichCompareBool works:

int equal = PyObject_RichCompareBool(lhs->unit_class, rhs->unit_class, Py_EQ);
if (equal == -1) {
    return NULL;  // Exception will be set because the rich-compare failed
}

and so on.

I tend to prefer failing immediately because it avoids deep (and complex) nestings later.

@geekypathak21
Copy link
Contributor Author

@MSeifert04 thanks for helping I added all things as suggested by you. Sorry for late updates

@geekypathak21
Copy link
Contributor Author

@MSeifert04 Now should I squash commits. If everything is done

@MSeifert04
Copy link
Contributor

@himanshupathak21061998 I'll do another review later today. Thanks for the update

@geekypathak21
Copy link
Contributor Author

geekypathak21 commented Mar 28, 2019

@MSeifert04 Please review changes

@bsipocz
Copy link
Member

bsipocz commented Mar 29, 2019

@himanshupathak2106199 - please be patient, all core maintainers have different day jobs than maintaining astropy, so having to wait a couple of days (or weeks in cases) for a review is part of the game.

CHANGES.rst Outdated Show resolved Hide resolved
@MSeifert04
Copy link
Contributor

Sorry for the long delay, I've been a bit busy. This looks good to me (from a technical viewpoint), the changelog could be clarified a bit though.

@astrofrog or @nden what do you think?

@geekypathak21
Copy link
Contributor Author

@MSeifert04 Thanks for reviewing and helping me I have changed the Changelog.rst

@nden
Copy link
Contributor

nden commented Apr 17, 2019

@himanshupathak21061998 This looks good! Thanks for the contribution and sorry for the late review.
@MSeifert04 Thanks for the reviews.

I am not sure what the codecov report means. It looks like it points to files in samp not in wcs but I may be misreading it. So I think this is ready to merge.

@himanshupathak21061998 can you squash the commits?

@geekypathak21
Copy link
Contributor Author

geekypathak21 commented Apr 17, 2019

@nden Thanks for reviewing I have done with squashing the commits as suggested

@geekypathak21
Copy link
Contributor Author

Again Codecov failure😁

@nden
Copy link
Contributor

nden commented Apr 17, 2019

@himanshupathak21061998 Could you add tests for

  • an error is raised by w1.wcs.cunit == [1, 2, 3]
  • an error is raised by w1.wcs.cunit == w2.wcs.cunit

I hope this will solve the coverage issue.

# Inequality checking of cunit with a list of literals
assert not w1.wcs.cunit == [1, 2, 3]
# Inequality checking with some characters
assert w1.wcs.cunit != ['a', 'b', 'c']
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this test because of !=

lhs = (PyUnitListProxy *)a;
rhs = (PyUnitListProxy *)b;
int equal = PyObject_RichCompareBool(lhs->unit_class, rhs->unit_class, Py_EQ);
if (equal == -1) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage report failure is because of this case as PyObject_RichCompareBool is not returning -1 in any of the case present in the test. For this I think, it needs direct testing of PyUnitListProxy which will be more cumbersome. So right now we can merge it

@geekypathak21
Copy link
Contributor Author

@nden Can you please review it again Thanks for helping

Copy link
Contributor

@nden nden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @himanshupathak21061998 ! I am going to merge this as it is.

@nden nden merged commit d1f2fd5 into astropy:master Apr 19, 2019
@geekypathak21
Copy link
Contributor Author

Thanks for merging

@geekypathak21 geekypathak21 deleted the WCSequality branch July 31, 2019 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Issue with WCS.wcs.cunit equality
6 participants