Python C API:Pylist_append在错误上做什么?

发布于 2025-01-21 22:48:26 字数 400 浏览 4 评论 0原文

文档中没有记录这一点。它只是说它“返回0以取得成功,而-1返回错误”。这是什么意思?

如果我们要迭代一些数据结构(例如链接列表/数组),并且在迭代时添加元素,然后突然Pylist_append返回-1 - ? < / strong>的元素是否被添加,参考计数减少了,或者Python只是死了,而退出 /减少参考计数是我最少的担心吗?

如果迄今为止添加的元素 的参考计数减少了,那么我知道没有任何事情必须完成,如在这种情况下,我的下属分配函数处理了其他参考计数的减少(如果元素的参考计数达到0) - 但是,如果Python只是扔了双手,说“您是您自己的” - 我必须确保我在错误时管理参考计数,请立即(或遭受参考泄露)。

那是哪个呢?

This is not documented in the docs. It just says it "returns 0 for success and -1 for error". What does this mean?

If we're iterating over some data structure (say a linked list/array) and we're adding elements as we iterate, and suddenly PyList_Append returns -1 - what happens? Does the elements that did get added, have their reference count decremented or does Python just die and de-allocating / decrementing reference counts is the least of my worries?

If the elements that thus far was added have their reference count decremented then I understand nothing has to be done, as in this case, my de-allocation function handles decrementing of other reference counts where it needs to (if the element's reference count reaches 0) - but if Python just throws it's hands up and say "you're on your own" - I would have to make sure I manage the reference counting at time of error, immediately (or suffer a reference leak).

So which is it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

年华零落成诗 2025-01-28 22:48:26

我相信Pylist_appendmemoryError可能会发生两个错误

  • (如果必须放大列表的分配内存,并且无法分配足够的时间)。
  • Systemerror如果将其传递给不是列表的东西。您应该能够通过适当的类型检查避免这种情况,因此,如果正确编写代码,则永远不会发生。

在这两种情况下:

  • 列表的现有内容仍然是列表中的一部分(其参考计数不会更改)。这些都是列表所有的,当列表被销毁时,它们的参考数将减少1,因此您不需要对它们做任何特别的事情,
  • 您要添加的元素也不会添加,并且其参考数量仍然存在不变。您是呼叫者自己的1参考(在成功和失败情况下),您可能想要DECREF

实际上,很难从内存 - 错误从中恢复 - 大多数操作系统都会分配内存,因此,当您实际上看到一段时间以前用完的内存错误时。


示例(未经测试)代码大致显示您要做什么:

PyObject *make_list(int n) {
    PyObject* list = PyList_New(0);
    for (int i=0; i<n; ++i) {
        PyObject *toAdd = PyLong_FromLong(i);
        if (!toAdd) goto bad;
        int appendRes = PyList_Append(list, toAdd);
        Py_DECREF(toAdd);  // decref this whatever the result of append
        if (appendRes < 0) goto bad;
    }
    if (0) {
        bad:
        Py_CLEAR(list);  // decref and set list to NULL - this will clean up any of list contents that were already
    }
    return list;
}

I believe there are two errors that can occur with PyList_Append:

  • MemoryError (if it had to enlarge the allocated memory for the list, and was unable to allocate enough).
  • SystemError if you pass it something that isn't a list. You should be able to avoid this through appropriate type-checks so if your code is written correctly it should never happen.

In both cases:

  • The existing contents of the list are still part of the list (and their reference count doesn't change). These are owned by the list and their reference count will be reduced by 1 when the list is destroyed, therefore you don't need to do anything special with them,
  • The element you were trying to add is not added, and its reference count remains unchanged. You as the caller own 1 reference to it (in both the success and failure cases) that you probably want to DECREF.

Practically memory-errors are hard to recover from - most operating systems over-allocate memory so by the time you actually see a memory error you've usually run out a while ago.


Example (untested) code showing roughly what you'd do:

PyObject *make_list(int n) {
    PyObject* list = PyList_New(0);
    for (int i=0; i<n; ++i) {
        PyObject *toAdd = PyLong_FromLong(i);
        if (!toAdd) goto bad;
        int appendRes = PyList_Append(list, toAdd);
        Py_DECREF(toAdd);  // decref this whatever the result of append
        if (appendRes < 0) goto bad;
    }
    if (0) {
        bad:
        Py_CLEAR(list);  // decref and set list to NULL - this will clean up any of list contents that were already
    }
    return list;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文