8000 bpo-44800: unobtrusively rename _PyInterpreterFrame to _Py_frame by ncoghlan · Pull Request #32024 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-44800: unobtrusively rename _PyInterpreterFrame to _Py_frame #32024

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

Closed

Conversation

ncoghlan
Copy link
Contributor
@ncoghlan ncoghlan commented Mar 21, 2022
  • rename _PyInterpreterFrame to _Py_frame to help indicate that _Py_frame
    is an implementation optimisation for frame objects rather than a distinct concept
  • add a block comment to pycore_frame.h covering future naming conventions,
    as well as deviations from those conventions for historical reasons
  • convert a potentially confusing use of cframe as a variable name to just frame

https://bugs.python.org/issue44800

@@ -0,0 +1,5 @@
Renamed ``_PyInterpreterFrame`` as ``_Py_frame`` to emphasise its close
association with ``PyFrameObject`` (they're conceptually the same thing, but
Copy link
Member

Choose a reason for hiding this comment

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

What does "conceptually the same thing" mean?
They aren't the same thing. What is the concept that makes them the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The same thing that makes it OK to pass both PyFrameObject and _PyInterpreterFrame structs to functions that have names starting with _PyFrame: they're Python code evaluation frames either way, but you may be working with the underlying data storage directly, or you may be working with the full refcounted Python object.

The difference between the two is mechanical (how their memory allocation is managed) rather than conceptual.

Copy link
Member

Choose a reason for hiding this comment

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

Your concepts are just that, your concepts. They are highly subjective.

PyFrameObjects and _PyInterpreterFrame are different things. One is a reference counted heap object, the other a stack frame. They have to managed quite differently, to me that means they are "conceptually distinct".

@markshannon
Copy link
Member

I really don't see why you think _Py_frame is a better name than _PyInterpreterFrame
Removing an adjective only makes a noun phrase clearer if that adjective is misleading.
Do you find Interpreter misleading?

Also, could you explain why the change to the name of the struct, and changes to the names of its fields must be in the same PR? They seem like independent changes to me.

@ncoghlan
Copy link
Contributor Author
ncoghlan commented Mar 21, 2022

Yes, I find "Interpreter" misleading, and as I said on the Discourse thread, it was your own comment on the first bpo-44800 PR that made me understand why it was confusing me: “From the point of view of Python code, the frame object is the frame, not just a view of it.”

When the names are _PyInterpreterFrame and PyFrameObject, that reads to me like they're two conceptually distinct things, whereas _Py_frame and PyFrameObject reads like the latter is just a Python API wrapper around the former, which is their actual relationship.

I think the last part of your comment may have been aimed at the previous PR, as there aren't any struct field name changes in this one.

@markshannon
Copy link
Member

If Interpreter is misleading, what would be a better adjective?

whereas _Py_frame and PyFrameObject reads like the latter is just a Python API wrapper around the former

To you. Not to me. _Py_frame tells me nothing. Is it a Python stack frame, a C stack frame, a video frame, an audio frame, a compression frame, ... ?

@ncoghlan
Copy link
Contributor Author
ncoghlan commented Mar 22, 2022

The ship sailed on PyFrame years ago when PyFrameObject was first named, along with all the associated PyFrame and _PyFrame APIs.

The problem Python 3.11 has created is that suddenly a lot of those _PyFrame APIs don't take a PyFrameObject pointer anymore, they take a _PyInterpreterFrame pointer. This makes them look like they're now accepting a different Python type from the one you'd expect based on their prefix, when what has really happened is that the essential PyFrameObject data storage has been pulled out to a separate C struct as a performance optimisation. Even the GDB bindings in the repo are confused, referring to the inner struct as a PyFramePtr, while the full Python object is PyFrameObjectPtr.

However, the only differences between PyFrameObject and _PyInterpreterFrame are mechanical (i.e. how you work with them in code), rather than conceptual (i.e. what they represent: a frame of execution for Python code).

When the two C types are instead PyFrameObject and _Py_frame those inconsistencies disappear:

  • a C data struct with a Python object API wrapper around it is a thoroughly normal thing to do in hybrid Python/C programming
  • _PyFrame APIs accept either PyFrameObject or _Py_frame, depending on which level they work at
  • PyFramePtr in the GDB bindings points to a _Py_frame struct
  • _Py_frame * doesn't look like a Python object pointer (it's intentionally similar to PEP 3118's Py_buffer in that respect - oddly, PEP 7 doesn't provide any guidance on naming regular C structs vs Python types in the C API)

The only thing getting in the way of that conventional coding style is the redundant "interpreter" adjective in the name of the underlying C struct. (As far as preferred adjectives go, my preferred one is "execution frame", hence the use of that in the first bpo-44800 PR that prompted your observation about there being no conceptual distinction between the two frame structs: "From the point of view of Python code, the frame object is the frame, not just a view of it". That's the observation that persuaded me that the best adjective to use here is no adjective at all, since PyFrameObject doesn't use one)

@ncoghlan
Copy link
Contributor Author

@markshannon I'm willing to close this and make a replacement PR that just documents the status quo in pycore_frame.h, but I'd like a definitive rejection from you first, rather than getting the silent treatment again.

Specifically, I'm looking for confirmation that you don't believe that it is in any way confusing to have the "interpreter" adjective solely in the struct name, when it's absent from the names of all the functions that manipulate the struct, from the name of the Python object that wraps the struct, and from most of the variables and struct fields that reference the struct.

@markshannon
Copy link
Member

I've said I don't like this change. I'm not sure what the "silent treatment" is, apart from not repeating myself.

You point out that some of the functions that take _PyInterpreterFrame have a PyFrame prefix, not a _PyInterpreterFrame.
I don't see how that is justification for this PR.
Renaming the internal functions that take a _PyInterpreterFrame would be a sensible change.
Want to do that? The functions in Include/internal/pycore_frame.h are mostly fair game.

Renaming _PyInterpreterFrame to something better is not unreasonable, although you haven't come up with a better name yet, IMO. FTR the name I initially proposed was "activation record", but it was decided that keeping "frame" in the name was less confusing.
Any name change is likely to break something, so the name would have to be much better to justify the change.

@ncoghlan
Copy link
Contributor Author

Renaming the private APIs is something I tried in a previous iteration of the proposal - it gets even messier than renaming the types and fields did.

I'll switch to adding internal code level documentation of the status quo (including the requirement to be super careful with not keeping hold of pointers to interpreter frames beyond their known validity)

@ncoghlan ncoghlan closed this Mar 26, 2022
@ncoghlan
Copy link
Contributor Author
ncoghlan commented Apr 3, 2022

Replacement PR that just documents the status quo: #32281

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.

4 participants
0