python / python/cpython

Convert static initializers of `PyTypeObject`s to use C99 Designated (named) initializers

Aperta
#127,679 13 commenti 8 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

extension-modules interpreter-core type-feature
Lingua principale
Python
Stelle
77.2k
Fork
35.9k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

Named initializer are both easier to read and less error prone. There is AFAICT no downside to using them.

However, we have been historically reluctant to change code for purely maintenance. Personally, I think this leads to poorer code quality, but others value cleaner code history more.

In this case I think the readability and correctness advantages are such that we should make this change and accept the inconvenience in version control history.

As a motivating example, take the bool type, PyBool_Type:

PyTypeObject PyBool_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "bool",
    offsetof(struct _longobject, long_value.ob_digit),  /* tp_basicsize */
    sizeof(digit),                              /* tp_itemsize */
    bool_dealloc,                               /* tp_dealloc */
    0,                                          /* tp_vectorcall_offset */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_as_async */
    bool_repr,                                  /* tp_repr */
    &bool_as_number,                            /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
    bool_doc,                                   /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    0,                                          /* tp_methods */
    0,                                          /* tp_members */
    0,                                          /* tp_getset */
    &PyLong_Type,                               /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    bool_new,                                   /* tp_new */
    .tp_vectorcall = bool_vectorcall,
};

There are a lot of zeros, and a lot of comments to make sure we have the right number of zeros. If one is missing, things go wrong.
Contrast that with the C99 version:

PyTypeObject PyBool_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    .tp_name = "bool",
    .tp_basicsize = offsetof(struct _longobject, long_value.ob_digit),
    .tp_itemsize = sizeof(digit),
    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_as_number  = &bool_as_number, 
    .tp_base = &PyLong_Type, 
    .tp_dealloc  = bool_dealloc,  
    .tp_doc = bool_doc,
    .tp_new = bool_new,
    .tp_repr = bool_repr,
    .tp_vectorcall = bool_vectorcall,
};

The code is self describing (no need for comments naming the fields) and is much less error prone. The fields can listed in any order, in this case with the core field first, then the optional fields alphabetically.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia individuando PyBool_Type e gli altri inizializzatori statici di PyTypeObject nel codice sorgente di CPython, quindi confronta l’ordine dei loro campi con la definizione di PyTypeObject. Converti gli inizializzatori in campi designati C99 preservandone i valori; il lavoro è completato quando il codice interessato viene compilato correttamente con la nuova sintassi di inizializzazione.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
c
Ambito
backend
Tipo di issue
Refactoring
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.