From f1d4e83f6dcc26b5579f67ea3d90c0f780343b5d Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 12 Jun 2020 00:12:32 +0900 Subject: [PATCH 1/9] bpo-40950: Apply PEP 3121 to nis module --- .../2020-06-12-00-12-28.bpo-40950.tzMy7m.rst | 1 + Modules/nismodule.c | 69 ++++++++++++++----- 2 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst new file mode 100644 index 00000000000000..f39b6c3feab1b8 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst @@ -0,0 +1 @@ +Apply :pep:`3121` to :mod:`nis`. Patch by Dong-hee Na. diff --git a/Modules/nismodule.c b/Modules/nismodule.c index a24978e0686705..e81d9f7f4b2645 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -44,12 +44,48 @@ PyDoc_STRVAR(maps__doc__, Returns an array of all available NIS maps within a domain. If domain\n\ is not specified it defaults to the system default domain.\n"); -static PyObject *NisError; +typedef struct { + PyObject *NisError; +} nis_state; + +static inline nis_state* +get_nis_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (nis_state *)state; +} + +static int +nis_clear(PyObject *m) +{ + Py_CLEAR(get_nis_state(m)->NisError); + return 0; +} + +static int +nis_traverse(PyObject *m, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(m)); + Py_VISIT(get_nis_state(m)->NisError); + return 0; +} + +static void +nis_free(void *m) +{ + nis_clear((PyObject *) m); +} + +static struct PyModuleDef nismodule; + +#define nis_state_global \ +((nis_state *) PyModule_GetState(PyState_FindModule(&nismodule))) static PyObject * nis_error (int err) { - PyErr_SetString(NisError, yperr_string(err)); + PyErr_SetString(nis_state_global->NisError, yperr_string(err)); return NULL; } @@ -364,12 +400,12 @@ nis_maplist (char *dom) mapi++; } if (!server) { - PyErr_SetString(NisError, "No NIS master found for any map"); + PyErr_SetString(nis_state_global->NisError, "No NIS master found for any map"); return NULL; } cl = clnt_create(server, YPPROG, YPVERS, "tcp"); if (cl == NULL) { - PyErr_SetString(NisError, clnt_spcreateerror(server)); + PyErr_SetString(nis_state_global->NisError, clnt_spcreateerror(server)); goto finally; } list = nisproc_maplist_2 (&dom, cl); @@ -444,14 +480,13 @@ PyDoc_STRVAR(nis__doc__, static struct PyModuleDef nismodule = { PyModuleDef_HEAD_INIT, - "nis", - nis__doc__, - -1, - nis_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "nis", + .m_doc = nis__doc__, + .m_size = sizeof(nis_state), + .m_methods = nis_methods, + .m_traverse = nis_traverse, + .m_clear = nis_clear, + .m_free = nis_free, }; PyMODINIT_FUNC @@ -459,11 +494,13 @@ PyInit_nis(void) { PyObject *m, *d; m = PyModule_Create(&nismodule); - if (m == NULL) + if (m == NULL) { return NULL; + } d = PyModule_GetDict(m); - NisError = PyErr_NewException("nis.error", NULL, NULL); - if (NisError != NULL) - PyDict_SetItemString(d, "error", NisError); + get_nis_state(m)->NisError = PyErr_NewException("nis.error", NULL, NULL); + if (get_nis_state(m)->NisError != NULL) { + PyDict_SetItemString(d, "error", get_nis_state(m)->NisError ); + } return m; } From b67167ca0d3548a389fea94e2aecad8e8caa1f0e Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 12 Jun 2020 01:08:25 +0900 Subject: [PATCH 2/9] Update Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst Co-authored-by: Victor Stinner --- .../Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst index f39b6c3feab1b8..05c0a81e9d4812 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst @@ -1 +1 @@ -Apply :pep:`3121` to :mod:`nis`. Patch by Dong-hee Na. +Add a state to the :mod:`nis` module (:pep:`3121`). Patch by Dong-hee Na. From f3b5f82bd246b8c9a4d704669cac39b19885d81e Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 12 Jun 2020 01:13:24 +0900 Subject: [PATCH 3/9] bpo-40950: Apply Victor's review --- Modules/nismodule.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Modules/nismodule.c b/Modules/nismodule.c index e81d9f7f4b2645..51f94b927008dc 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -45,7 +45,7 @@ Returns an array of all available NIS maps within a domain. If domain\n\ is not specified it defaults to the system default domain.\n"); typedef struct { - PyObject *NisError; + PyObject *nis_error; } nis_state; static inline nis_state* @@ -59,15 +59,14 @@ get_nis_state(PyObject *module) static int nis_clear(PyObject *m) { - Py_CLEAR(get_nis_state(m)->NisError); + Py_CLEAR(get_nis_state(m)->nis_error); return 0; } static int nis_traverse(PyObject *m, visitproc visit, void *arg) { - Py_VISIT(Py_TYPE(m)); - Py_VISIT(get_nis_state(m)->NisError); + Py_VISIT(get_nis_state(m)->nis_error); return 0; } @@ -85,7 +84,7 @@ static struct PyModuleDef nismodule; static PyObject * nis_error (int err) { - PyErr_SetString(nis_state_global->NisError, yperr_string(err)); + PyErr_SetString(nis_state_global->nis_error, yperr_string(err)); return NULL; } @@ -400,12 +399,12 @@ nis_maplist (char *dom) mapi++; } if (!server) { - PyErr_SetString(nis_state_global->NisError, "No NIS master found for any map"); + PyErr_SetString(nis_state_global->nis_error, "No NIS master found for any map"); return NULL; } cl = clnt_create(server, YPPROG, YPVERS, "tcp"); if (cl == NULL) { - PyErr_SetString(nis_state_global->NisError, clnt_spcreateerror(server)); + PyErr_SetString(nis_state_global->nis_error, clnt_spcreateerror(server)); goto finally; } list = nisproc_maplist_2 (&dom, cl); @@ -498,9 +497,10 @@ PyInit_nis(void) return NULL; } d = PyModule_GetDict(m); - get_nis_state(m)->NisError = PyErr_NewException("nis.error", NULL, NULL); - if (get_nis_state(m)->NisError != NULL) { - PyDict_SetItemString(d, "error", get_nis_state(m)->NisError ); + nis_state* state = get_nis_state(m); + state->nis_error = PyErr_NewException("nis.error", NULL, NULL); + if (state->nis_error != NULL) { + PyDict_SetItemString(d, "error", state->nis_error); } return m; } From 8e3fda222abd6e2515f5bd4b2b04253114ddc212 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 12 Jun 2020 02:13:45 +0900 Subject: [PATCH 4/9] bpo-40950: Apply Victor's review --- Modules/nismodule.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Modules/nismodule.c b/Modules/nismodule.c index 51f94b927008dc..9a3eec6b5659b8 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -491,16 +491,24 @@ static struct PyModuleDef nismodule = { PyMODINIT_FUNC PyInit_nis(void) { - PyObject *m, *d; - m = PyModule_Create(&nismodule); - if (m == NULL) { + PyObject *module; + module = PyModule_Create(&nismodule); + if (module == NULL) { return NULL; } - d = PyModule_GetDict(m); - nis_state* state = get_nis_state(m); + + nis_state* state = get_nis_state(module); state->nis_error = PyErr_NewException("nis.error", NULL, NULL); - if (state->nis_error != NULL) { - PyDict_SetItemString(d, "error", state->nis_error); + if (state->nis_error == NULL) { + Py_DECREF(module); + return NULL; + } + + Py_INCREF(state->nis_error); + if (PyModule_AddObject(module, "error", state->nis_error) < 0) { + Py_DECREF(module); + Py_DECREF(state->nis_error); + return NULL; } - return m; + return module; } From 4574e0db945ebc09817bd5361bc0bcad1286c40a Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 12 Jun 2020 02:15:33 +0900 Subject: [PATCH 5/9] bpo-40950: fix --- Modules/nismodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/nismodule.c b/Modules/nismodule.c index 9a3eec6b5659b8..668bf86a4a3f3e 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -505,7 +505,7 @@ PyInit_nis(void) } Py_INCREF(state->nis_error); - if (PyModule_AddObject(module, "error", state->nis_error) < 0) { + if (PyModule_AddObject(module, "error", state->nis_error) < 0) { Py_DECREF(module); Py_DECREF(state->nis_error); return NULL; From 9e58180cfbca8ca1ef56c33f6e60e483e0bb41c8 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 12 Jun 2020 02:38:27 +0900 Subject: [PATCH 6/9] bpo-40950: Apply code review --- Modules/nismodule.c | 69 +++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/Modules/nismodule.c b/Modules/nismodule.c index 668bf86a4a3f3e..3b91b559608d58 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -76,15 +76,10 @@ nis_free(void *m) nis_clear((PyObject *) m); } -static struct PyModuleDef nismodule; - -#define nis_state_global \ -((nis_state *) PyModule_GetState(PyState_FindModule(&nismodule))) - static PyObject * -nis_error (int err) +nis_error(nis_state *state, int err) { - PyErr_SetString(nis_state_global->nis_error, yperr_string(err)); + PyErr_SetString(state->nis_error, yperr_string(err)); return NULL; } @@ -172,21 +167,22 @@ nis_foreach (int instatus, char *inkey, int inkeylen, char *inval, } static PyObject * -nis_get_default_domain (PyObject *self, PyObject *Py_UNUSED(ignored)) +nis_get_default_domain(PyObject *module, PyObject *Py_UNUSED(ignored)) { char *domain; int err; PyObject *res; - - if ((err = yp_get_default_domain(&domain)) != 0) - return nis_error(err); + nis_state *state = get_nis_state(module); + if ((err = yp_get_default_domain(&domain)) != 0) { + return nis_error(state, err); + } res = PyUnicode_FromStringAndSize (domain, strlen(domain)); return res; } static PyObject * -nis_match (PyObject *self, PyObject *args, PyObject *kwdict) +nis_match (PyObject *module, PyObject *args, PyObject *kwdict) { char *match; char *domain = NULL; @@ -200,18 +196,22 @@ nis_match (PyObject *self, PyObject *args, PyObject *kwdict) if (!PyArg_ParseTupleAndKeywords(args, kwdict, "Us|s:match", kwlist, - &ukey, &map, &domain)) + &ukey, &map, &domain)) { return NULL; - if ((bkey = PyUnicode_EncodeFSDefault(ukey)) == NULL) + } + if ((bkey = PyUnicode_EncodeFSDefault(ukey)) == NULL) { return NULL; + } /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(bkey, &key, &keylen) == -1) { Py_DECREF(bkey); return NULL; } + + nis_state *state = get_nis_state(module); if (!domain && ((err = yp_get_default_domain(&domain)) != 0)) { Py_DECREF(bkey); - return nis_error(err); + return nis_error(state, err); } map = nis_mapname (map, &fix); if (fix) @@ -222,15 +222,16 @@ nis_match (PyObject *self, PyObject *args, PyObject *kwdict) Py_DECREF(bkey); if (fix) len--; - if (err != 0) - return nis_error(err); + if (err != 0) { + return nis_error(state, err); + } res = PyUnicode_DecodeFSDefaultAndSize(match, len); free (match); return res; } static PyObject * -nis_cat (PyObject *self, PyObject *args, PyObject *kwdict) +nis_cat (PyObject *module, PyObject *args, PyObject *kwdict) { char *domain = NULL; char *map; @@ -241,10 +242,13 @@ nis_cat (PyObject *self, PyObject *args, PyObject *kwdict) static char *kwlist[] = {"map", "domain", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s|s:cat", - kwlist, &map, &domain)) + kwlist, &map, &domain)) { return NULL; - if (!domain && ((err = yp_get_default_domain(&domain)) != 0)) - return nis_error(err); + } + nis_state *state = get_nis_state(module); + if (!domain && ((err = yp_get_default_domain(&domain)) != 0)) { + return nis_error(state, err); + } dict = PyDict_New (); if (dict == NULL) return NULL; @@ -257,7 +261,7 @@ nis_cat (PyObject *self, PyObject *args, PyObject *kwdict) PyEval_RestoreThread(data.state); if (err != 0) { Py_DECREF(dict); - return nis_error(err); + return nis_error(state, err); } return dict; } @@ -387,7 +391,7 @@ nisproc_maplist_2(domainname *argp, CLIENT *clnt) static nismaplist * -nis_maplist (char *dom) +nis_maplist(nis_state *state, char *dom) { nisresp_maplist *list; CLIENT *cl; @@ -399,12 +403,12 @@ nis_maplist (char *dom) mapi++; } if (!server) { - PyErr_SetString(nis_state_global->nis_error, "No NIS master found for any map"); + PyErr_SetString(state->nis_error, "No NIS master found for any map"); return NULL; } cl = clnt_create(server, YPPROG, YPVERS, "tcp"); if (cl == NULL) { - PyErr_SetString(nis_state_global->nis_error, clnt_spcreateerror(server)); + PyErr_SetString(state->nis_error, clnt_spcreateerror(server)); goto finally; } list = nisproc_maplist_2 (&dom, cl); @@ -423,7 +427,7 @@ nis_maplist (char *dom) } static PyObject * -nis_maps (PyObject *self, PyObject *args, PyObject *kwdict) +nis_maps (PyObject *module, PyObject *args, PyObject *kwdict) { char *domain = NULL; nismaplist *maps; @@ -432,17 +436,22 @@ nis_maps (PyObject *self, PyObject *args, PyObject *kwdict) static char *kwlist[] = {"domain", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwdict, - "|s:maps", kwlist, &domain)) + "|s:maps", kwlist, &domain)) { return NULL; + } + + nis_state *state = get_nis_state(module); if (!domain && ((err = yp_get_default_domain (&domain)) != 0)) { - nis_error(err); + nis_error(state, err); return NULL; } - if ((maps = nis_maplist (domain)) == NULL) + if ((maps = nis_maplist(state, domain)) == NULL) { return NULL; - if ((list = PyList_New(0)) == NULL) + } + if ((list = PyList_New(0)) == NULL) { return NULL; + } for (; maps; maps = maps->next) { PyObject *str = PyUnicode_FromString(maps->map); if (!str || PyList_Append(list, str) < 0) From c1fd880bce159fd99cd9c89daf3a3b592ab4c49e Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 12 Jun 2020 02:40:02 +0900 Subject: [PATCH 7/9] bpo-40950: nit --- Modules/nismodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/nismodule.c b/Modules/nismodule.c index 3b91b559608d58..70c385102492a4 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -100,7 +100,7 @@ static struct nis_map { }; static char * -nis_mapname (char *map, int *pfix) +nis_mapname(char *map, int *pfix) { int i; @@ -128,7 +128,7 @@ struct ypcallback_data { }; static int -nis_foreach (int instatus, char *inkey, int inkeylen, char *inval, +nis_foreach(int instatus, char *inkey, int inkeylen, char *inval, int invallen, struct ypcallback_data *indata) { if (instatus == YP_TRUE) { @@ -182,7 +182,7 @@ nis_get_default_domain(PyObject *module, PyObject *Py_UNUSED(ignored)) } static PyObject * -nis_match (PyObject *module, PyObject *args, PyObject *kwdict) +nis_match(PyObject *module, PyObject *args, PyObject *kwdict) { char *match; char *domain = NULL; @@ -231,7 +231,7 @@ nis_match (PyObject *module, PyObject *args, PyObject *kwdict) } static PyObject * -nis_cat (PyObject *module, PyObject *args, PyObject *kwdict) +nis_cat(PyObject *module, PyObject *args, PyObject *kwdict) { char *domain = NULL; char *map; From 23bd00dae443e33dc13890f3b5b3f769920eee35 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 12 Jun 2020 02:51:23 +0900 Subject: [PATCH 8/9] bpo-409501: Port nis module to multiphase initialization --- Modules/nismodule.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/Modules/nismodule.c b/Modules/nismodule.c index 70c385102492a4..6655451ebd2fbf 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -483,6 +483,28 @@ static PyMethodDef nis_methods[] = { {NULL, NULL} /* Sentinel */ }; +static int +nis_exec(PyObject *module) +{ + nis_state* state = get_nis_state(module); + state->nis_error = PyErr_NewException("nis.error", NULL, NULL); + if (state->nis_error == NULL) { + return -1; + } + + Py_INCREF(state->nis_error); + if (PyModule_AddObject(module, "error", state->nis_error) < 0) { + Py_DECREF(state->nis_error); + return -1; + } + return 0; +} + +static PyModuleDef_Slot nis_slots[] = { + {Py_mod_exec, nis_exec}, + {0, NULL} +}; + PyDoc_STRVAR(nis__doc__, "This module contains functions for accessing NIS maps.\n"); @@ -495,29 +517,11 @@ static struct PyModuleDef nismodule = { .m_traverse = nis_traverse, .m_clear = nis_clear, .m_free = nis_free, + .m_slots = nis_slots, }; PyMODINIT_FUNC PyInit_nis(void) { - PyObject *module; - module = PyModule_Create(&nismodule); - if (module == NULL) { - return NULL; - } - - nis_state* state = get_nis_state(module); - state->nis_error = PyErr_NewException("nis.error", NULL, NULL); - if (state->nis_error == NULL) { - Py_DECREF(module); - return NULL; - } - - Py_INCREF(state->nis_error); - if (PyModule_AddObject(module, "error", state->nis_error) < 0) { - Py_DECREF(module); - Py_DECREF(state->nis_error); - return NULL; - } - return module; + return PyModuleDef_Init(&nismodule); } From 0e6d3eaee2142b8b42f8025aeeaff0810e9b3a68 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 12 Jun 2020 11:01:00 +0900 Subject: [PATCH 9/9] bpo-40950: Update NEWS.d --- .../Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst index 05c0a81e9d4812..925b5790f73f3d 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-12-00-12-28.bpo-40950.tzMy7m.rst @@ -1 +1,2 @@ -Add a state to the :mod:`nis` module (:pep:`3121`). Patch by Dong-hee Na. +Add a state to the :mod:`nis` module (:pep:`3121`) and apply +the multiphase initialization. Patch by Dong-hee Na.