PyArg_ParseTupleAndKeywords需要一个指定对象的空参数?

时间:2013-07-26 09:36:20

标签: python python-c-api cpython

我在C Python扩展中对PyArg_ParseTupleAndKeywords进行了以下调用:

static char *kwlist [] = {
    "page_slug", "keys", "facets", "categories", "max_level",
    "current_level", "level", "parent_slug", "query",
    "include_category", "include_ancestor", NULL
};

int max_level, current_level, level = 0;
PyObject *page_slug, *keys, *facets, *categories,
         *parent_slug = PyString_FromString(""), *query = Py_None,
         *include_category = Py_True, *include_ancestor = Py_True;

if (!PyArg_ParseTupleAndKeywords(
        args, kwargs, "OO!O!O!ii|iOOO!O!", kwlist,
        &page_slug, &PyList_Type, &keys,
        &PyDict_Type, &facets, &PyDict_Type, &categories, 
        &max_level, &current_level, &level, &parent_slug,
        &PyBool_Type, &include_category, 
        &PyBool_Type, &include_ancestor)) {
    return NULL;
}

哪个应该会产生如下签名:

func(page_slug, keys, facets, categories, max_level,
     current_level, level=0, parent_slug="", query=None,
     include_category=True, include_ancestor=True)

但是,当从Python中调用方法时,会引发TypeError,如下所示:

TypeError: argument 10 must be (null), not bool

任何人都可以解释为什么在理论上它应该接受NULL时,为什么参数10应该是PyObject*?而且,如何纠正这个?

编辑:

从Python开始,函数被称为:

func(page_slug, keys, facets, categories, max_level,
     current_level, level=level + 1, parent_slug=slug,
     query=query, include_category=include_category,
     include_ancestor=include_ancestor)

page_slugparent_slugquery是unicode对象,keys是一个列表,max_levelcurrent_level和{{ 1}}是整数,levelfacets是双关语。

不包括布尔参数(categoriesinclude_ancestor)有效(或者更确切地说,对include_category的调用有效,有一个分段错误,目前在C函数中发生很久) ,但包括其中任何一个都会导致PyArg_ParseTupleAndKeywords被提升。

将对TypeError的通话更改为:

PyArg_ParseTupleAndKeyword

(即删除PyArg_ParseTupleAndKeywords( args, kwargs, "OO!O!O!ii|iOOOO", kwlist, &page_slug, &PyList_Type, &keys, &PyDict_Type, &facets, &PyDict_Type, &categories, &max_level, &current_level, &level, &parent_slug, &include_category, &include_ancestor) include_category的布尔要求)导致include_ancestor中的分段错误。

1 个答案:

答案 0 :(得分:2)

query

之后,你没有将PyArg_ParseTupleAndKeywords传递给&parent_slug,

请致电

if (!PyArg_ParseTupleAndKeywords(
        args, kwargs, "OO!O!O!ii|iOOO!O!", kwlist,
        &page_slug, &PyList_Type, &keys,
        &PyDict_Type, &facets, &PyDict_Type, &categories, 
        &max_level, &current_level, &level, &parent_slug,
        &query, &PyBool_Type, &include_category, 
        &PyBool_Type, &include_ancestor)) {
    return NULL;
}

您的原始通话会导致格式和对象列表不匹配,从而引发异常(我认为)。

分解格式和传递的内容

O   &page_slug
O!  &PyList_Type, &keys
O!  &PyDict_Type, &facets
O!  &PyDict_Type, &categories
i   &max_level
i|  &current_level
i   &level
O   &parent_slug
O   ---
O!  &PyBool_Type, &include_category
O!  &PyBool_Type, &include_ancestor