Title: C API: Consider adding a public PyList_Extend() function · Issue #111138 · python/cpython · GitHub
Open Graph Title: C API: Consider adding a public PyList_Extend() function · Issue #111138 · python/cpython
X Title: C API: Consider adding a public PyList_Extend() function · Issue #111138 · python/cpython
Description: Feature or enhancement The private _PyList_Extend() function has been removed in Python 3.13: see PR #108451. @scoder asked what is the replacement for this removed function. The obvious replacement is PyObject_CallMethod(list, "extend",...
Open Graph Description: Feature or enhancement The private _PyList_Extend() function has been removed in Python 3.13: see PR #108451. @scoder asked what is the replacement for this removed function. The obvious replacemen...
X Description: Feature or enhancement The private _PyList_Extend() function has been removed in Python 3.13: see PR #108451. @scoder asked what is the replacement for this removed function. The obvious replacemen...
Opengraph URL: https://github.com/python/cpython/issues/111138
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"C API: Consider adding a public PyList_Extend() function","articleBody":"# Feature or enhancement\n\nThe private `_PyList_Extend()` function has been removed in Python 3.13: see PR #108451.\n\n@scoder [asked](https://github.com/python/cpython/pull/108451#issuecomment-1772792843) what is the replacement for this removed function.\n\nThe obvious replacement is ``PyObject_CallMethod(list, \"extend\", \"O\", arg)``: call the `list.extend()` method. But it's slower, `PyObject_CallMethod()` has to get the method and decode the \"O\" format string.\n\nAnother replacement is ``PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, arg)`` which is less straightforward, but it's efficient.\n\nI propose adding a public PyList_Extend() function. The list type is commonly used in C extensions, it's a convenient API to create a collection when the length is not known is advance.\n\nI don't think that performance is really the problem here since ``PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, arg)`` is available. The problem is more to more the function easier to discover and make the API easier to use. Also, it should help people to migrate away from the removed function.\n\nThere is already a public **PyDict_Update()** API for the dict type, it is part of the limited C API.\n\nIf we add a function for the list type, should we also add **PySet_Update()** \"for completeness\"? The private `_PySet_Update()` was removed in Python 3.13.\n\ncc @serhiy-storchaka @encukou \n\n---\n\nA code search on ``_PyList_Extend`` in PyPI top 5,000 projects (2023-07-04) found 4 projects using this function:\n\n* Cython (0.29.36)\n* catboost (1.2)\n* mypy (1.4.1)\n* pyrsistent (0.19.3)\n\nLogs:\n\n\u003cdetails\u003e\n\n```\nPYPI-2023-07-04/catboost-1.2.tar.gz: catboost-1.2/catboost_all_src/contrib/tools/cython/Cython/Compiler/Builtin.py: BuiltinMethod(\"extend\", \"TO\", \"r\", \"__Pyx_PyList_Extend\",\nPYPI-2023-07-04/catboost-1.2.tar.gz: catboost-1.2/catboost_all_src/contrib/tools/cython/Cython/Compiler/ExprNodes.py: extend_func = \"__Pyx_PyList_Extend\"\nPYPI-2023-07-04/catboost-1.2.tar.gz: catboost-1.2/catboost_all_src/contrib/tools/cython/Cython/Utility/Optimize.c: static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {\nPYPI-2023-07-04/catboost-1.2.tar.gz: catboost-1.2/catboost_all_src/contrib/tools/cython/Cython/Utility/Optimize.c: PyObject* none = _PyList_Extend((PyListObject*)L, v);\n\nPYPI-2023-07-04/Cython-0.29.36.tar.gz: Cython-0.29.36/Cython/Compiler/Builtin.py: BuiltinMethod(\"extend\", \"TO\", \"r\", \"__Pyx_PyList_Extend\",\nPYPI-2023-07-04/Cython-0.29.36.tar.gz: Cython-0.29.36/Cython/Compiler/ExprNodes.py: extend_func = \"__Pyx_PyList_Extend\"\nPYPI-2023-07-04/Cython-0.29.36.tar.gz: Cython-0.29.36/Cython/Utility/Optimize.c: static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {\nPYPI-2023-07-04/Cython-0.29.36.tar.gz: Cython-0.29.36/Cython/Utility/Optimize.c: PyObject* none = _PyList_Extend((PyListObject*)L, v);\n\nPYPI-2023-07-04/mypy-1.4.1.tar.gz: mypy-1.4.1/mypyc/lib-rt/dict_ops.c: PyObject *res = _PyList_Extend((PyListObject *)list, view);\nPYPI-2023-07-04/mypy-1.4.1.tar.gz: mypy-1.4.1/mypyc/lib-rt/dict_ops.c: PyObject *res = _PyList_Extend((PyListObject *)list, view);\nPYPI-2023-07-04/mypy-1.4.1.tar.gz: mypy-1.4.1/mypyc/lib-rt/dict_ops.c: PyObject *res = _PyList_Extend((PyListObject *)list, view);\nPYPI-2023-07-04/mypy-1.4.1.tar.gz: mypy-1.4.1/mypyc/lib-rt/list_ops.c: return _PyList_Extend((PyListObject *)o1, o2);\n\nPYPI-2023-07-04/pyrsistent-0.19.3.tar.gz: pyrsistent-0.19.3/pvectorcmodule.c: PyObject *retVal = _PyList_Extend((PyListObject *)self-\u003eappendList, args);\n```\n\n\u003c/details\u003e\n\nCython uses the function to implement its own __Pyx_PyList_Extend() API:\n\n```c\nstatic CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {\n#if CYTHON_COMPILING_IN_CPYTHON\n PyObject* none = _PyList_Extend((PyListObject*)L, v);\n if (unlikely(!none))\n return -1;\n Py_DECREF(none);\n return 0;\n#else\n return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);\n#endif\n}\n```\n\n\u003c!-- gh-linked-prs --\u003e\n### Linked PRs\n* gh-111582\n* gh-111862\n\u003c!-- /gh-linked-prs --\u003e\n","author":{"url":"https://github.com/vstinner","@type":"Person","name":"vstinner"},"datePublished":"2023-10-20T21:13:41.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":8},"url":"https://github.com/111138/cpython/issues/111138"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:4b1968d2-e7c2-f664-0cda-d90354eda311 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 86DE:8619D:172F9EB:1EF9009:6969BE7D |
| html-safe-nonce | 6b70de314f83199278839ac3364b815b55101d736dac76f02740513bbe37b08e |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4NkRFOjg2MTlEOjE3MkY5RUI6MUVGOTAwOTo2OTY5QkU3RCIsInZpc2l0b3JfaWQiOiI1NzgwODk0MzA3MDc3MTc2OTU3IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 0f91e3c5e9608db4eb62950f1a941028cab026da040aca5699ce0d369d50c0ca |
| hovercard-subject-tag | issue:1955019781 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python/cpython/111138/issue_layout |
| twitter:image | https://opengraph.githubassets.com/abb0c6b1cb577c9c2fe9d2b0e24737b94ddcb67046df275d5529d33c4f90907c/python/cpython/issues/111138 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/abb0c6b1cb577c9c2fe9d2b0e24737b94ddcb67046df275d5529d33c4f90907c/python/cpython/issues/111138 |
| og:image:alt | Feature or enhancement The private _PyList_Extend() function has been removed in Python 3.13: see PR #108451. @scoder asked what is the replacement for this removed function. The obvious replacemen... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | vstinner |
| hostname | github.com |
| expected-hostname | github.com |
| None | acedec8b5f975d9e3d494ddd8f949b0b8a0de59d393901e26f73df9dcba80056 |
| turbo-cache-control | no-preview |
| go-import | github.com/python/cpython git https://github.com/python/cpython.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 81598961 |
| octolytics-dimension-repository_nwo | python/cpython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81598961 |
| octolytics-dimension-repository_network_root_nwo | python/cpython |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 83c08c21cdda978090dc44364b71aa5bc6dcea79 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width