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

bpo-33738: Fix macros which contradict PEP 384 #7477

Merged
merged 2 commits into from
Jun 9, 2018
Merged

bpo-33738: Fix macros which contradict PEP 384 #7477

merged 2 commits into from
Jun 9, 2018

Conversation

ctismer
Copy link
Contributor

@ctismer ctismer commented Jun 7, 2018

During development of the limited API support for PySide,
we saw an error in a macro that accessed a type field.

This patch fixes the 7 errors in the Python headers.
Macros which were not written as capitals were implemented
as function.

To do the necessary analysis again, a script was included that
parses all headers and looks for "->tp_" in sections which can
be reached with active limited API.

It is easily possible to call this script as a test.

Error listing:

../../Include/objimpl.h:243
#define PyObject_IS_GC(o) (PyType_IS_GC(Py_TYPE(o)) &&
(Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))
Action: commented only

../../Include/objimpl.h:362
#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0)
Action: commented only

../../Include/objimpl.h:364
#define PyObject_GET_WEAKREFS_LISTPTR(o)
((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset))
Action: commented only

../../Include/pyerrors.h:143
#define PyExceptionClass_Name(x)
((char )(((PyTypeObject)(x))->tp_name))
Action: implemented function

../../Include/abstract.h:593
#define PyIter_Check(obj)
((obj)->ob_type->tp_iternext != NULL &&
(obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented)
Action: implemented function

../../Include/abstract.h:713
#define PyIndex_Check(obj)
((obj)->ob_type->tp_as_number != NULL &&
(obj)->ob_type->tp_as_number->nb_index != NULL)
Action: implemented function

../../Include/abstract.h:924
#define PySequence_ITEM(o, i)
( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) )
Action: commented only

https://bugs.python.org/issue33738

During development of the limited API support for PySide,
we saw an error in a macro that accessed a type field.

This patch fixes the 7 errors in the Python headers.
Macros which were not written as capitals were implemented
as function.

To do the necessary analysis again, a script was included that
parses all headers and looks for "->tp_" in serctions which can
be reached with active limited API.

It is easily possible to call this script as a test.

Error listing:

../../Include/objimpl.h:243
#define PyObject_IS_GC(o) (PyType_IS_GC(Py_TYPE(o)) && \
    (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))
Action: commented only

../../Include/objimpl.h:362
#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0)
Action: commented only

../../Include/objimpl.h:364
#define PyObject_GET_WEAKREFS_LISTPTR(o) \
    ((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset))
Action: commented only

../../Include/pyerrors.h:143
#define PyExceptionClass_Name(x) \
     ((char *)(((PyTypeObject*)(x))->tp_name))
Action: implemented function

../../Include/abstract.h:593
#define PyIter_Check(obj) \
    ((obj)->ob_type->tp_iternext != NULL && \
     (obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented)
Action: implemented function

../../Include/abstract.h:713
#define PyIndex_Check(obj)                              \
    ((obj)->ob_type->tp_as_number != NULL &&            \
     (obj)->ob_type->tp_as_number->nb_index != NULL)
Action: implemented function

../../Include/abstract.h:924
#define PySequence_ITEM(o, i)\
    ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) )
Action: commented only
During development of the limited API support for PySide,
we saw an error in a macro that accessed a type field.

This patch fixes the 7 errors in the Python headers.
Macros which were not written as capitals were implemented
as function.

To do the necessary analysis again, a script was included that
parses all headers and looks for "->tp_" in sections which can
be reached with active limited API.

It is easily possible to call this script as a test.

Error listing:

../../Include/objimpl.h:243
    (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))
Action: commented only

../../Include/objimpl.h:362
Action: commented only

../../Include/objimpl.h:364
    ((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset))
Action: commented only

../../Include/pyerrors.h:143
     ((char *)(((PyTypeObject*)(x))->tp_name))
Action: implemented function

../../Include/abstract.h:593
    ((obj)->ob_type->tp_iternext != NULL && \
     (obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented)
Action: implemented function

../../Include/abstract.h:713
    ((obj)->ob_type->tp_as_number != NULL &&            \
     (obj)->ob_type->tp_as_number->nb_index != NULL)
Action: implemented function

../../Include/abstract.h:924
    ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) )
Action: commented only
@ctismer ctismer requested a review from a team as a code owner June 7, 2018 17:17
@ctismer
Copy link
Contributor Author

ctismer commented Jun 7, 2018

Can I squash these commits, or do I need to re-send the whole thing? (Or leave it in pieces)

@zware
Copy link
Member

zware commented Jun 7, 2018

They'll be squashed at merge time, don't worry about it until then :)

@ned-deily
Copy link
Member

LGTM, although this is not an area of my expertise. Since we are getting very close to 3.7.0rc1 and it would be good to have this resolved, I'm going to merge this to master now so it gets some buildbot exposure. If anyone has any review comments, get them in real soon! Otherwise, I will backport and merge to 3.7 within the next 24 hours.

@ned-deily ned-deily merged commit ea62ce7 into python:master Jun 9, 2018
@ned-deily
Copy link
Member

Looks like the change introduces a compile warning. Should that be addressed?:

..\Objects\exceptions.c(349): warning C4090: 'return': different 'const' qualifiers [D:\buildarea\3.x.ware-win81-release\build\PCbuild\pythoncore.vcxproj]

http://buildbot.python.org/all/#/builders/12/builds/960

@ctismer
Copy link
Contributor Author

ctismer commented Jun 9, 2018

Yes it should be fixed. I was not aware that Python has const-ness, already.
I have amended my patch with "const char *". But since it is merged, I don't see the change.

@ned-deily
Copy link
Member

@ctismer Thanks. The best thing would be to open a new PR but, if you can paste the diff here, I'll take care of it.

#define PyIter_Check(obj) \
((obj)->ob_type->tp_iternext != NULL && \
(obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented)
#else
PyAPI_FUNC(int) PyIter_Check(PyObject*);
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: it would look better if add a space between PyObject and *.

#define PyExceptionClass_Name(x) \
((char *)(((PyTypeObject*)(x))->tp_name))
#else
PyAPI_FUNC(char *) PyExceptionClass_Name(PyObject*);
Copy link
Member

Choose a reason for hiding this comment

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

Should return const char *. And please add a space between PyObject and *.

Copy link
Contributor Author

@ctismer ctismer Jun 10, 2018

Choose a reason for hiding this comment

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

Will do.
My style is a bit spoiled by Qt's C++ style. They write "func(PyObject *self)"
but "func(PyObject*)".
I am preparing a diff as Ned said, but I can also repeat the PR.

@@ -140,8 +140,12 @@ PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *);
#define PyExceptionInstance_Check(x) \
PyType_FastSubclass((x)->ob_type, Py_TPFLAGS_BASE_EXC_SUBCLASS)

#ifndef Py_LIMITED_API
#define PyExceptionClass_Name(x) \
((char *)(((PyTypeObject*)(x))->tp_name))
Copy link
Member

Choose a reason for hiding this comment

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

Actually (char *) is not needed. But it should be documented in What's New that PyExceptionClass_Name() now returns const char * instead of char * (there were similar breaking changes in 3.7).

@@ -342,6 +342,12 @@ PyException_SetContext(PyObject *self, PyObject *context)
Py_XSETREF(((PyBaseExceptionObject *)self)->context, context);
}

#undef PyExceptionClass_Name
char *
Copy link
Member

Choose a reason for hiding this comment

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

Return const char *.

@@ -2535,6 +2543,13 @@ PyObject_GetIter(PyObject *o)
}
}

#undef PyIter_Check
int PyIter_Check(PyObject *obj)
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: Break a line between int and PyIter_Check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, will do. Although all other #undef's are without newline.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Eeek, misunderstood!
Sure, you wanted a line after int!
I must have been very tired...

@serhiy-storchaka
Copy link
Member

Seems I forgot to press the "Submit review" button after adding comments.

@ctismer
Copy link
Contributor Author

ctismer commented Jun 10, 2018

Ok, I hope I got all changes right. Doing a new PR.

@serhiy-storchaka
Copy link
Member

Since this PR has been merged, my comments except the one about the result of PyExceptionClass_Name are outdated. They where just style nitpicks. And I have opened a separate issue for the latter.

@tekknolagi
Copy link
Contributor

Was this ever backported to Python 3.7?

@ned-deily
Copy link
Member

@tekknolagi No, I don't think they were ever backported to 3.7. See the discussion on the still open bug issue (https://bugs.python.org/issue33738) which is also the place for comments. In any case, with the upcoming release of 3.7.8, 3.7 has moved to security-fix mode, precluding changes like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants