Convert static initializers of `PyTypeObject`s to use C99 Designated (named) initializers
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 36k
- Métriques de merge des PR
- Métriques de PR en attente
Description
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.
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par localiser PyBool_Type et les autres initialiseurs statiques de PyTypeObject dans le code source de CPython, puis comparez l’ordre de leurs champs avec la définition de PyTypeObject. Convertissez les initialiseurs en champs désignés C99 tout en préservant leurs valeurs ; le travail est considéré comme terminé lorsque le code concerné se construit correctement avec la nouvelle syntaxe d’initialisation.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- c
- Domaine
- backend
- Type d'issue
- Refactorisation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 35/100