This function is called from only one place. Maybe there are special conditions that the one call site already ensures?

I tried to see if there are situations where obj==NULL arises, and there are. I'm a little unclear on where -- I've narrowed down one case to any class inheriting from Protocol, so that makes me wonder if `__init_subclass__` is involved.


On Fri, Aug 14, 2020 at 9:52 AM Skip Montanaro <skip.montanaro@gmail.com> wrote:
(I'm far from certain this is the correct place for this message. Maybe I should have opened a case on bpo instead?)

I got far behind on my register instruction set stuff and in the interim the ground shifted underneath me. I'm still working to try and get the test suite to pass (modulo test_ssl, which I expect to fail on Ubuntu 20.04 for the time being).

In trying to track down where my code differs from the main/3.10 branch, I was looking at the super_init_without_args() function in typeobject.c. I'm puzzled by this chunk of code near the top:

    PyObject *obj = f->f_localsplus[0];
    Py_ssize_t i, n;
    if (obj == NULL && co->co_cell2arg) {
        /* The first argument might be a cell. */
        n = PyTuple_GET_SIZE(co->co_cellvars);
        for (i = 0; i < n; i++) {
            if (co->co_cell2arg[i] == 0) {
                PyObject *cell = f->f_localsplus[co->co_nlocals + i];
                assert(PyCell_Check(cell));
                obj = PyCell_GET(cell);
                break;
            }
        }
    }


More specifically, the test for f->f_localsplus[0] being NULL seems odd. I can understand that there might not be any local variables, but there is no test for co->co_nlocals == 0. Since we don't know how many locals there might be, if there were none, wouldn't a reference to a cell variable or free variable occupy the first slot (assuming there are any)? I guess I'm confused about what the obj == NULL term in the if statement's expression is doing for us.

On a (maybe not) related note, there is a comment further down in super_init():

        /* Call super(), without args -- fill in from __class__
           and first local variable on the stack. */


I'm not seeing where the first local variable on the stack is used to fill anything in, certainly not within the block guarded by the type == NULL expression.

Skip
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/FOCMYF53HVGTCE4GA3BFVA6ASZEQ2THF/
Code of Conduct: http://python.org/psf/codeofconduct/


--
--Guido van Rossum (python.org/~guido)
Pronouns: he/him (why is my pronoun here?)