Skip to content

Commit 442ce14

Browse files
committed
Adds simplifying macros for default arguments.
1 parent c50b989 commit 442ce14

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

doc/sphinx/source/parsing_arguments.rst

+52
Original file line numberDiff line numberDiff line change
@@ -437,3 +437,55 @@ Here is the complete C code:
437437
Py_XDECREF(pyObjArg_1);
438438
return ret;
439439
}
440+
441+
^^^^^^^^^^^^^^^^^^^^^^^^
442+
Simplifying Macros
443+
^^^^^^^^^^^^^^^^^^^^^^^^
444+
445+
For simple default values some macros may help. The first one declares and initialises the default value. It takes three arguments:
446+
447+
* The name of the argument variable, a static ``PyObject`` named ``default_<name>`` will also be created.
448+
* The default value which should return a new reference.
449+
* The value to return on failure to create a default value, usually -1 or ``NULL``.
450+
451+
.. code-block:: c
452+
453+
#define PY_DEFAULT_ARGUMENT_INIT(name, value, ret) \
454+
PyObject *name = NULL; \
455+
static PyObject *default_##name = NULL; \
456+
if (! default_##name) { \
457+
default_##name = value; \
458+
if (! default_##name) { \
459+
PyErr_SetString(PyExc_RuntimeError, "Can not create default value for " #name); \
460+
return ret; \
461+
} \
462+
}
463+
464+
The second one assigns the argument to the default if it is not initialised. It just takes the name of the argument:
465+
466+
.. code-block:: c
467+
468+
#define PY_DEFAULT_ARGUMENT_SET(name) if (! name) name = default_##name
469+
470+
And they can be used thus:
471+
472+
.. code-block:: c
473+
474+
static int
475+
something_init(something *self, PyObject *args, PyObject *kwds) {
476+
/* Initialise default arguments */
477+
PY_DEFAULT_ARGUMENT_INIT(encoding, PyUnicode_FromString("utf-8"), -1);
478+
PY_DEFAULT_ARGUMENT_INIT(the_id, PyLong_FromLong(0L), -1);
479+
PY_DEFAULT_ARGUMENT_INIT(must_log, PyBool_FromLong(1L), -1);
480+
481+
static const char *kwlist[] = { "encoding", "the_id", "must_log", NULL };
482+
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|Oip",
483+
const_cast<char**>(kwlist),
484+
&encoding, &the_id, &must_log)) {
485+
return -1;
486+
}
487+
/* Assign absent arguments to defaults. */
488+
PY_DEFAULT_ARGUMENT_SET(encoding);
489+
PY_DEFAULT_ARGUMENT_SET(the_id);
490+
PY_DEFAULT_ARGUMENT_SET(must_log);
491+
/* Use encoding, the_id, must_log from here on... */

0 commit comments

Comments
 (0)