// SPDX-License-Identifier: LGPL-2.1-or-later /**************************************************************************** * * * Copyright (c) 2023 The FreeCAD Project Association * * * * This file is part of FreeCAD. * * * * FreeCAD is free software: you can redistribute it and/or modify it * * under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 2.1 of the * * License, or (at your option) any later version. * * * * FreeCAD is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with FreeCAD. If not, see * * . * * * ***************************************************************************/ #ifndef FREECAD_PYWRAPPARSETUPLEANDKEYWORDS_H #define FREECAD_PYWRAPPARSETUPLEANDKEYWORDS_H #include #include namespace Base { /// A thin C++ wrapper around PyArg_ParseTupleAndKeywords providing const-correctness for the /// keywords argument \arg args The Python args object \arg kw The Python kw object \arg format The /// format string describing the expected arguments \arg keywords A std::array of keywords, /// terminated by a nullptr (required by CPython) \arg (variadic) Pointers to the storage locations /// for the parameters \returns boolean true on success, or false on failure template bool Wrapped_ParseTupleAndKeywords(PyObject* args, PyObject* kw, const char* format, const std::array keywords, ...) { static_assert(arraySize > 0, "keywords array must have at least a single nullptr in it"); if (keywords.back()) { PyErr_SetString(PyExc_ValueError, "Last element of keywords array is not null"); return false; } // NOTE: This code is from getargs.c in the Python source code (modified to use the public // interface at PyArg_VaParseTupleAndKeywords and to return a bool). if ((args == nullptr || !PyTuple_Check(args)) || (kw != nullptr && !PyDict_Check(kw)) || format == nullptr) { PyErr_BadInternalCall(); return false; } va_list va; // NOLINT va_start(va, keywords); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) int retval = PyArg_VaParseTupleAndKeywords(args, kw, format, const_cast(keywords.data()), va); va_end(va); return retval != 0; // Convert to a true C++ boolean } } // namespace Base #endif // FREECAD_PYWRAPPARSETUPLEANDKEYWORDS_H