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

DOC: emphasize the need to always call PySequence_Fast #11140

Merged
merged 5 commits into from
Sep 12, 2019

Conversation

mattip
Copy link
Contributor

@mattip mattip commented Dec 13, 2018

PySequence_Fast() should always be used (and the result checked) before any of the other PySequence_Fast* family of functions. As an implementation detail, CPython can circumvent this if PyTuple_CheckExact() passes, but that does not work on PyPy.

xref numpy/numpy#12524

@serhiy-storchaka
Copy link
Member

Is not this a PyPy issue that PySequence_Fast* functions do not work with lists and tuples?

@mattip
Copy link
Contributor Author

mattip commented Dec 13, 2018

The functions work for ret after calling PyObject* ret = PySequence_Fast(o), on both PyPy and CPython, but the documentation was not clear that this is always necessary. Hopefully now it is clearer.

@eric-wieser
Copy link
Contributor

@serhiy-storchaka: I think the point is that requiring those functions to work on lists and tuples puts nasty lifetime constraints on pypy, which could be lifted simply by relaxing the documentation to saying "PySequence_Fast_ITEMS is only defined on the result of PySequence_Fast".

@serhiy-storchaka
Copy link
Member

I think this change needs more wide discussion. Please open an issue on the bug tracker and ask the question on the Python-Dev mailing list.

@JulienPalard
Copy link
Member

@mattip Hi, have you been able to open an issue on bugs.python.org about it as requested by Serhiy?

@mattip
Copy link
Contributor Author

mattip commented Sep 11, 2019

@serhiy-storchaka what do you see as controversial? Perhaps you could suggest a phrasing that would not require such an extensive discussion for a documentation clarification?



.. c:function:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i)

Return the *i*\ th element of *o*, assuming that *o* was returned by
:c:func:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds.
Equivalent to :c:func:`PySequence_GetItem` but faster.
Copy link
Contributor

Choose a reason for hiding this comment

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

Not exactly. At the very least, it has a difference analogous to the one between PySequence_GetItem and PySequence_GetItem, where the "fast" form doesn't handle negative indexes.

:c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list
or tuple.
:c:func:`PySequence_Fast` and that *o* is not *NULL*. Equivalent to
:c:func:`PySequence_Size` but faster.
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 like to say these are equivalent, since PySequence_Fast_GET_SIZE has the assumption that PySequence_Fast has been called. The old sentence was clearer.

``PySequence_Fast*`` family of functions. On CPython, if *o* is already a
sequence or list, it will be returned, but this is an implementation detail.
Returns *NULL* on failure. If the object is not a sequence or iterable,
raises :exc:`TypeError` with *m* as the message text.
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest only describing the abstract semantics (the first and last sentences) of this function in the first paragraph and moving the implementation details below (the middle sentence).

Copy link
Contributor

Choose a reason for hiding this comment

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

This partially duplicates the first paragraph now.

Returns *NULL* on failure. If the object is not a sequence or iterable,
raises :exc:`TypeError` with *m* as the message text.

This family of functions is labelled *Fast* since it can assume *o* is a
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be clearer to say "The PySequence_Fast_* functions are thus named because they assume...".

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@mattip
Copy link
Contributor Author

mattip commented Sep 12, 2019

I have made the requested changes; please review again.

@bedevere-bot
Copy link

Thanks for making the requested changes!

@benjaminp: please review the changes made to this pull request.

iterable, raises :exc:`TypeError` with *m* as the message text.

The ``PySequence_Fast*`` functions are thus named because they can assume
*o* is a :c:type:`PyTupleObject` or a :c:type:`PyListObject`, and accesses
Copy link
Contributor

Choose a reason for hiding this comment

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

s/accesses/access/

``PySequence_Fast*`` family of functions. If the object is not a sequence or
iterable, raises :exc:`TypeError` with *m* as the message text.

The ``PySequence_Fast*`` functions are thus named because they can assume
Copy link
Contributor

Choose a reason for hiding this comment

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

remove can


The ``PySequence_Fast*`` functions are thus named because they can assume
*o* is a :c:type:`PyTupleObject` or a :c:type:`PyListObject`, and accesses
the type's data fields directly.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/type's/*o*'s/

``PySequence_Fast*`` family of functions. On CPython, if *o* is already a
sequence or list, it will be returned, but this is an implementation detail.
Returns *NULL* on failure. If the object is not a sequence or iterable,
raises :exc:`TypeError` with *m* as the message text.
Copy link
Contributor

Choose a reason for hiding this comment

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

This partially duplicates the first paragraph now.

@mattip
Copy link
Contributor Author

mattip commented Sep 12, 2019

I have made the requested changes; please review again

@bedevere-bot
Copy link

Thanks for making the requested changes!

@benjaminp: please review the changes made to this pull request.

@miss-islington
Copy link
Contributor

Thanks @mattip for the PR, and @benjaminp for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.7, 3.8.
🐍🍒⛏🤖

@bedevere-bot
Copy link

GH-16068 is a backport of this pull request to the 3.8 branch.

@bedevere-bot
Copy link

GH-16069 is a backport of this pull request to the 3.7 branch.

@miss-islington
Copy link
Contributor

Sorry, @mattip and @benjaminp, I could not cleanly backport this to 2.7 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 57b7dbc46e71269d855e644d30826d33eedee2a1 2.7

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Sep 12, 2019
(cherry picked from commit 57b7dbc)

Co-authored-by: Matti Picus <matti.picus@gmail.com>
miss-islington added a commit that referenced this pull request Sep 12, 2019
(cherry picked from commit 57b7dbc)

Co-authored-by: Matti Picus <matti.picus@gmail.com>
miss-islington added a commit that referenced this pull request Sep 12, 2019
(cherry picked from commit 57b7dbc)

Co-authored-by: Matti Picus <matti.picus@gmail.com>
gpshead added a commit to gpshead/cpython that referenced this pull request Feb 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir skip issue skip news
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants