Skip to content

gh-86542: New C-APIs to simplify module attribute declaration #23286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
Prev Previous commit
Next Next commit
Remove PyModuleDef.m_constants again
  • Loading branch information
tiran committed Apr 17, 2021
commit 366e810efce0a95c40bf089d2068ee64ebc8feeb
137 changes: 137 additions & 0 deletions Doc/c-api/module.rst
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,143 @@ state:

.. versionadded:: 3.9

.. c:function:: PyTypeeObject * PyModule_AddNewTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *base)

Initialize a new type and add it to *module*.
The function is equivalent to :c:func:`PyType_FromModuleAndSpec` followed
by :c:func:`PyModule_AddType`. *base* must be either ``NULL``, a single
type object, or a tuple of types.
Return ``NULL`` on error; otherwise a borrowed reference to a
``PyTypeObject *``, which can be assigned to a module state object.

.. versionadded:: 3.10

.. c:function:: PyObject * PyModule_AddNewException(PyObject *module, const char *name, const char *doc, PyObject *base, PyObject *dict)

Create a new exception and add it to *module*.
The function is equivalent to :c:func:`PyErr_NewExceptionWithDoc` followed
by :c:func:`PyModule_AddObjectRef`. The name of the exception object is
taken from the last component of *name* after dot.
Return ``NULL`` on error; otherwise a borrowed reference to a
``PyObject *``, which can be assigned to a module state object.

.. versionadded:: 3.10

.. c:function:: int PyModule_AddConstants(PyObject *module, PyModuleConst_Def *def)

Initialize module constants from a PyModuleConst_Def array. The function
provides a convenient way to declare module-level constants.
Return ``-1`` on error, ``0`` on success.

Example::

static PyObject*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: static PyObject * in here.

example_call(void *)
{
return PyBytes_FromString("23");
}

#define EXAMPLE_INT 23
#define EXAMPLE_STRING "world"

static PyModuleConst_Def example_constants[] = {
PyModuleConst_None("none_value"),
PyModuleConst_Long("integer", 42),
PyModuleConst_Bool("false_value", 0),
PyModuleConst_Bool("true_value", 1),
#ifdef Py_MATH_PI
PyModuleConst_Double("pi", Py_MATH_PI),
#endif
PyModuleConst_String("somestring", "Hello"),
PyModuleConst_Call("call", example_call),
PyModuleConst_LongMacro(EXAMPLE_INT),
PyModuleConst_StringMacro(EXAMPLE_STRING),
{NULL},
}

static int
example_init_constants(PyObject *module)
{
return PyModule_AddConstants(module, posix_constants);
}

static PyModuleDef_Slot example_slots[] = {
{Py_mod_exec, example_init_constants},
{0, NULL}
};


.. c:type:: PyModuleConst_Def

The values for *type* and the definition of the *value* union are
internal implementation details. Use any of the ``PyModuleConst_`` macros
to define entries. The array must be terminated by an entry with name
set to ``NULL``.

.. c:member:: const char *name

Attribute name.

.. c:member:: int type

Attribute type.

.. c:member:: union value

Value of the module constant definition, whose meaning depends on
*type*.

.. versionadded:: 3.10

.. c:macro:: PyModuleConst_None(name)

Add an entry for None.

.. versionadded:: 3.10

.. c:macro:: PyModuleConst_Long(name, value)

Add an entry for an int constant.

.. versionadded:: 3.10

.. c:macro:: PyModuleConst_Bool(name, value)

Add an entry for a bool constant.

.. versionadded:: 3.10

.. c:macro:: PyModuleConst_Double(name, value)

Add an entry for a float constant.

.. versionadded:: 3.10

.. c:macro:: PyModuleConst_String(name, value)

Add an entry for a string constant.

.. versionadded:: 3.10

.. c:macro:: PyModuleConst_Call(name, c_function)

Add an entry for a constant as returned by *c_function*.

.. versionadded:: 3.10

.. c:macro:: PyModuleConst_LongMacro(macro)

Add an entry for an int constant. The name and the value are taken from
*macro*.

.. versionadded:: 3.10

.. c:macro:: PyModuleConst_StringMacro(macro)

Add an entry for a string constant. The name and the value are taken from
*macro*.

.. versionadded:: 3.10

Module lookup
^^^^^^^^^^^^^
Expand Down
1 change: 0 additions & 1 deletion Include/moduleobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ typedef struct PyModuleDef{
traverseproc m_traverse;
inquiry m_clear;
freefunc m_free;
struct PyModuleConst_Def* m_constants;
} PyModuleDef;


Expand Down
13 changes: 12 additions & 1 deletion Modules/mathmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3595,6 +3595,17 @@ static PyModuleConst_Def math_constants[] = {
{NULL, 0},
};

static int
math_init_constants(PyObject *module)
{
return PyModule_AddConstants(module, math_constants);
}

static PyModuleDef_Slot math_slots[] = {
{Py_mod_exec, math_init_constants},
{0, NULL}
};

PyDoc_STRVAR(module_doc,
"This module provides access to the mathematical functions\n"
"defined by the C standard.");
Expand All @@ -3605,7 +3616,7 @@ static struct PyModuleDef mathmodule = {
.m_doc = module_doc,
.m_size = 0,
.m_methods = math_methods,
.m_constants = math_constants,
.m_slots = math_slots,
};

PyMODINIT_FUNC
Expand Down
10 changes: 8 additions & 2 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -15687,7 +15687,7 @@ posixmodule_exec(PyObject *m)
return 0;
}

static PyModuleConst_Def _posix_constants[] = {
static PyModuleConst_Def posix_constants[] = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about using another sepeareted PR to do this converation operation?

#ifdef F_OK
PyModuleConst_LongMacro(F_OK),
#endif
Expand Down Expand Up @@ -15769,9 +15769,16 @@ static PyModuleConst_Def _posix_constants[] = {
{NULL, 0},
};

static int
posixmodule_init_constants(PyObject *module)
{
return PyModule_AddConstants(module, posix_constants);
}


static PyModuleDef_Slot posixmodile_slots[] = {
{Py_mod_exec, posixmodule_exec},
{Py_mod_exec, posixmodule_init_constants},
{0, NULL}
};

Expand All @@ -15785,7 +15792,6 @@ static struct PyModuleDef posixmodule = {
.m_traverse = _posix_traverse,
.m_clear = _posix_clear,
.m_free = _posix_free,
.m_constants = _posix_constants,
};

PyMODINIT_FUNC
Expand Down
13 changes: 0 additions & 13 deletions Objects/moduleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,12 +299,6 @@ _PyModule_CreateInitialized(struct PyModuleDef* module, int module_api_version)
return NULL;
}
}
if (module->m_constants != NULL) {
if (PyModule_AddConstants((PyObject *) m, module->m_constants) != 0) {
Py_DECREF(m);
return NULL;
}
}
m->md_def = module;
return (PyObject*)m;
}
Expand Down Expand Up @@ -424,13 +418,6 @@ PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api
}
}

if (def->m_constants != NULL) {
if (PyModule_AddConstants(m, def->m_constants) != 0) {
Py_DECREF(m);
return NULL;
}
}

Py_DECREF(nameobj);
return m;

Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy