[Python-Dev] When does `PyType_Type.tp_alloc get assigned to PyType_GenericAlloc ?

2016-02-07 Thread Randy Eels
Hi everyone,

I've a question about the implementation of the `type` builtin (in Python
3.5).

In Objects/typeobject.c, the `tp_alloc` slot of PyType_Type gets set to 0.
However, I can see (using gdb) that it later gets assigned to
`&PyType_GenericAlloc`. I'd argue that this makes sense because, in
`type_new`, there is a line where that member function gets called without
previously checking whether that member points to something:

```
/* Allocate the type object */
type = (PyTypeObject *)metatype->tp_alloc(metatype, nslots);
```

Yet, I can't seem to understand where and when does the `tp_alloc` slot of
PyType_Type get re-assigned to PyType_GenericAlloc. Does that even happen?
Or am I missing something bigger?

And, just out of further curiosity, why doesn't the aforementioned slot get
initialised to `PyType_GenericAlloc` in the first place?

Thanks a lot.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] When does `PyType_Type.tp_alloc get assigned to PyType_GenericAlloc ?

2016-02-17 Thread Randy Eels
On Sun, Feb 7, 2016 at 8:45 PM, Guido van Rossum  wrote:

> I think it's probably line 2649 in typeobject.c, in type_new():
>
> type->tp_alloc = PyType_GenericAlloc;


I pondered it but it doesn't seem to be that. Isn't `type_new` called
*after* PyType_Type.tp_alloc has been called? I thought that line was only
being executed for user-defined types, and maybe some built-in types, but
certainly not PyType_Type.

On Sun, Feb 7, 2016 at 9:27 PM, eryk sun  wrote:

> On Sun, Feb 7, 2016 at 7:58 AM, Randy Eels  wrote:
> >
> > Yet, I can't seem to understand where and when does the `tp_alloc` slot
> of
> > PyType_Type get re-assigned to PyType_GenericAlloc. Does that even
> happen?
> > Or am I missing something bigger?
>
> _Py_InitializeEx_Private in Python/pylifecycle.c calls _Py_ReadyTypes
> in Objects/object.c. This calls PyType_Ready(&PyType_Type) in
> Objects/typeobject.c, which assigns type->tp_base = &PyBaseObject_Type
> and then calls inherit_slots. This executes COPYSLOT(tp_alloc), which
> assigns PyType_Type.tp_alloc = PyBaseObject_Type.tp_alloc, which is
> statically assigned as PyType_GenericAlloc.
>
> Debug trace on Windows:
>
> 0:000> bp python35!PyType_Ready
> 0:000> g
> Breakpoint 0 hit
> python35!PyType_Ready:
> `6502d160 4053pushrbx
> 0:000> ?? ((PyTypeObject *)@rcx)->tp_name
> char * 0x`650e4044
>  "object"
> 0:000> g
> Breakpoint 0 hit
> python35!PyType_Ready:
> `6502d160 4053pushrbx
> 0:000> ?? ((PyTypeObject *)@rcx)->tp_name
> char * 0x`651d8e5c
>  "type"
> 0:000> bp python35!inherit_slots
> 0:000> g
> Breakpoint 1 hit
> python35!inherit_slots:
> `6502c440 48895c2408  mov qword ptr [rsp+8],rbx
> ss:`0028f960={
> python35!PyType_Type
> (`6527cba0)}
>
> At entry to inherit_slots, PyType_Type.tp_alloc is NULL:
>
> 0:000> ?? python35!PyType_Type.tp_alloc
>  * 0x`
> 0:000> pt
> python35!inherit_slots+0xd17:
> `6502d157 c3  ret
>
> At exit it's set to PyType_GenericAlloc:
>
> 0:000> ?? python35!PyType_Type.tp_alloc
>  * 0x`65025580
> 0:000> ln 65025580
> (`65025580)   python35!PyType_GenericAlloc   |
> (`650256a0)   python35!PyType_GenericNew
> Exact matches:
> python35!PyType_GenericAlloc (void)
>

This makes quite a bit of sense. I completely overlooked the interpreter
init routines.

Thank you both Guido and eryk!
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com