Is it possible to use Python C-API to get the current size of value stack?

I’m playing with Python’s C-API. Specifically, I want to see if I can inspect how many elements the value stack currently has. Here’s my code:

#include <Python.h>
#include <frameobject.h>

int test() {
    PyFrameObject* f = PyEval_GetFrame();
    return (int)(f->f_stacktop - f->f_valuestack);

I’m not sure whether this can work, but this line exists in Python’s source code, so I gave it a try.

This usually give me a negative number, something like -547715639.

So clearly I’m doing it wrong, probably because what’e described in the documentation: “Frame evaluation usually NULLs it (f_stacktop)”. What’s the right way to do it, or is it even possible?

I found your question/response on Stack Overflow.

Here’s a link for future wanderers:

Yeah, I answered my own question. In short, it’s impossible, though I really hope Python could expose this information, which can unblock a lot of things.

I would recommend creating a new thread in to further discuss this. I don’t have a specific answer for you, but I suspect that you’d be able to find an answer there. Be sure to search through the archives to see if it was previously addressed.

Also, if you do manage to find a more detailed answer, I’m sure that others who encounter this topic would greatly appreciate if it were posted here (and perhaps in the stack overflow question).

Thanks Kyle. I can send an email to discuss if making changes to expose this information makes sense. As for the current codebase, I’m pretty sure it’s impossible, as explained in this answer:

I don’t think it makes much sense to expose details like this. It would mean we couldn’t do things like switch to a register-based VM instead of a stack-based one.

Why do you want this information? What’s the actual problem you’re trying to solve?

Make sense. I’m making a debugging tool and is exploring ideas. If this won’t work I’ll just go another route.

Even if it was non-public API (which debuggers could use), keeping the info in a more accessible place than a local variable would probably slow things down. Keeping another place updated (like we do with yield, but continuously) sounds even slower.

If you can instrument your CPython, you could:

If (and it’s a big if) you can find a way to get this information out without sacrificing performance, and the patch is not too unmaintainable, perhaps we can add it in.

1 Like

I’ve posted a response to your S.O. question with my techniques,