classification
Title: [C API] PyType_GetSlot cannot get tp_name
Type: enhancement Stage: patch review
Components: C API Versions:
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: corona10, fancitron, petr.viktorin, shihai1991, vstinner
Priority: normal Keywords: patch

Created on 2020-10-14 13:52 by fancitron, last changed 2021-02-01 16:06 by shihai1991.

Pull Requests
URL Status Linked Edit
PR 23903 open shihai1991, 2020-12-23 05:03
Messages (12)
msg378616 - (view) Author: (fancitron) Date: 2020-10-14 13:52
In the Limited API (where PyTypeObject is opaque), there is no way to retrieve the tp_name of a type object.  The PyType_GetSlot() function doesn’t define a slot ID Py_tp_name.  This makes it inconvenient to port existing code to the Limited API.  Is this intentional?  How to work around this?
msg379102 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2020-10-20 08:20
The slots are originally intended for defining types (PyType_FromSpec); PyType_GetSlot is not as useful as it could be.
tp_name can be exposed, but it needs to also be handled properly PyType_FromSpec -- e.g. raise an error.
msg379109 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2020-10-20 09:10
Ah, scratch that: PyType_GetSlot returns a function pointer.
To be correct, we should to expose a new function like PyType_GetName.

It's true that CPython currently doesn't always honor the distinction between data and function pointers, but the C standard says they're distinct, so it might bite us in the future.
msg379291 - (view) Author: (fancitron) Date: 2020-10-22 13:22
True enough.  Btw, PyType_FromSpec accepts Py_tp_doc (char *), Py_tp_base (PyTypeObject *), etc ... so to be strictly standard compliant, a union would be necessary.

PyType_GetName() sounds great.

One "proper" workaround at the moment is PyObject_GetAttrString(Py_TYPE(x), "__name__") and then process the result.  This is somewhat "heavy" and strips the module name.  "Py_tp_name" provides a convenient, exception safe, and backward compatible way to access tp_name.

What I actually do right now is to access the (opaque) PyTypeObject::tp_name by pointer offset.  This certain defies the purpose of stable ABI!
msg379416 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2020-10-23 08:54
Yes, for some cases the ship has sailed. I don't think we can add unions now -- the stable ABI needs to be stable.
msg383070 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2020-12-15 15:40
I'll be happy to review adding a PyType_GetName function.
msg385274 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2021-01-19 16:43
Now that I see the implementation (and now that I'm spending a lot of time trying to formalize what is good stable API), I see a problem with PyType_GetName: it effectively returns a borrowed reference.
The proposed docs say:

   Callers can hold [the retuned] pointer until the type has been deallocated.

This is not friendly to alternate Python implementations. For example, if tp_name is stored as UTF-32, it would need to generate the char* data -- and then retain it until the class is deallocated.
I guess the "correct" way would be to return a Py_buffer, which would (in CPython) reference the class.

Victor, what do you think?
msg385281 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2021-01-19 17:34
New C API functions must not return borrowed references, but strong references.
msg385282 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2021-01-19 17:36
A type has different names:

* short name: "name"
* qualified name: "module.name"

Which one should be returned by PyType_GetName()? Is there a warranty that it's always short or always qualified?
msg385390 - (view) Author: hai shi (shihai1991) * (Python triager) Date: 2021-01-21 05:02
> New C API functions must not return borrowed references, but strong references.

Thanks petr, victor for your suggestion. It's more friendly to users.

> Which one should be returned by PyType_GetName()? Is there a warranty that it's always short or always qualified?

Returning short or qualified name depends on how to define the tp_name in PyType_Spec or type object. IMHO, PyType_GetName() return the original defined type name is fine to users.
msg385433 - (view) Author: hai shi (shihai1991) * (Python triager) Date: 2021-01-21 16:22
Wait. petr mentioned `_PyType_Name` in PR 23903 which use the short name. So I am not sure which way is better. Lol~
msg386080 - (view) Author: hai shi (shihai1991) * (Python triager) Date: 2021-02-01 16:06
I found `type.__name__` has the implementation details in https://github.com/python/cpython/blob/master/Objects/typeobject.c#L486. 
IMHO, keep the consistency in `PyType_GetName()` is OK.

Victor, Petr. Do you think it make senses?
History
Date User Action Args
2021-02-01 16:06:13shihai1991setmessages: + msg386080
2021-01-21 16:22:44shihai1991setmessages: + msg385433
2021-01-21 05:02:39shihai1991setmessages: + msg385390
2021-01-19 17:36:42vstinnersetmessages: + msg385282
2021-01-19 17:34:28vstinnersetmessages: + msg385281
2021-01-19 16:43:23petr.viktorinsetmessages: + msg385274
2021-01-07 08:54:20vstinnersetnosy: + vstinner
2020-12-23 05:03:52shihai1991setkeywords: + patch
stage: patch review
pull_requests: + pull_request22757
2020-12-15 15:40:49petr.viktorinsetmessages: + msg383070
2020-11-03 14:24:54shihai1991setnosy: + shihai1991
2020-10-23 08:54:41petr.viktorinsetmessages: + msg379416
2020-10-22 13:22:12fancitronsetmessages: + msg379291
2020-10-20 09:10:50petr.viktorinsetmessages: + msg379109
2020-10-20 08:20:20petr.viktorinsetmessages: + msg379102
2020-10-14 13:55:04vstinnersetnosy: + petr.viktorin, corona10

title: PyType_GetSlot cannot get tp_name -> [C API] PyType_GetSlot cannot get tp_name
2020-10-14 13:52:05fancitroncreate