bool TuplesDefaultImpl::m_parse(va_list ap) { bool ret_val = false; TupleInDefaultImpl *ptupleIn = m_current_tuple_in(); if (!m_tuple) { /* NOTE в режиме execute не исключено значение m_tuple = NULL; это означает, что: -- для функции PyNoArgsFunction (флаг METH_NOARGS) вызывается проверка аргументов -- метод создан только для получения данных (TupleFillState::modGetter) в обоих случаях исключение сработает раньше -- в TupleState::parse */ throw ArgsException(); } try { char * const * keywords = ptupleIn->keywords(); if ( ptupleIn->args().empty() && !PyObject_Length(m_tuple) && (!m_kw || !PyObject_Length(m_kw)) || m_kw && PyArg_VaParseTupleAndKeywords(m_tuple, m_kw, ptupleIn->format().c_str(), const_cast<char **>(keywords), ap) || !m_kw && PyArg_VaParse(m_tuple, ptupleIn->format().c_str(), ap) ) { ret_val = true; } } catch (const TupleBase::FormatException &ex) { /*TODO Возможно правильнее было бы перехватить здесь исключение Вопрос особенно актуален, когда сигнатур несколько и большая часть из них правильные см также function_dublicate в pytest_pyhrol_keywords.cpp -- этот эффект будет ликвидирован, а многие тесты будут провалены ptupleIn->parseError = ex.what(); */ throw; } if (!ret_val && PyErr_Occurred()) { PyObject *ptype, *pvalue, *ptraceback; PyErr_Fetch(&ptype, &pvalue, &ptraceback); const char *pStrErrorMessage = PyString_AsString(pvalue); if (pStrErrorMessage) { ptupleIn->parseError = pStrErrorMessage; } Py_DecRef(ptype); Py_DecRef(pvalue); Py_DecRef(ptraceback); PyErr_Clear(); } return ret_val; }
/* * We're using "const char **" for keywords, * PyArg_ParseTupleAndKeywords expects a "char **". Confine the * inevitable warnings to just one place. */ static int ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, const char **keywords, ...) { va_list a; int ret; va_start(a, keywords); ret = PyArg_VaParseTupleAndKeywords(args, kw, format, (char **)keywords, a); va_end(a); return ret; }
/* * We're using "const char * const *" for keywords, * PyArg_ParseTupleAndKeywords expects a "char **". Confine the * inevitable warnings to just one place. */ static int ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, const char * const *keywords, ...) { char **_keywords = discard_const_p(char *, keywords); va_list a; int ret; va_start(a, keywords); ret = PyArg_VaParseTupleAndKeywords(args, kw, format, _keywords, a); va_end(a); return ret; }