homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ctypes.cast() creates circular reference in original object
Type: resource usage Stage: needs patch
Components: ctypes Versions: Python 3.10, Python 3.9, Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: bgilbert, mark.dickinson, terry.reedy, theller, vinay.sajip
Priority: normal Keywords:

Created on 2011年08月24日 21:53 by bgilbert, last changed 2022年04月11日 14:57 by admin.

Messages (5)
msg142933 - (view) Author: Benjamin Gilbert (bgilbert) Date: 2011年08月24日 21:53
Section 15.17.1.15 of the ctypes documentation illustrates the use of cast() thusly:
>>> a = (c_byte * 4)()
>>> cast(a, POINTER(c_int))
<ctypes.LP_c_long object at ...>
>>>
Executing the cast() causes a._objects to gain a reference back to a:
>>> a = (c_byte * 4)()
>>> a._objects
>>> cast(a, POINTER(c_int))
<__main__.LP_c_int object at 0x7fb879065b90>
>>> a._objects
{140430281170384: <__main__.c_byte_Array_4 object at 0x7fb879065dd0>}
>>> a
<__main__.c_byte_Array_4 object at 0x7fb879065dd0>
>>> 
If large temporary arrays are allocated, cast, used, and discarded in a tight inner loop, a lot of memory can thus be consumed by self-referencing objects before the garbage collector has a chance to run. Even if this behavior is correct from the perspective of ctypes, it is surprising.
msg143117 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2011年08月28日 18:39
What action are you suggesting? Change ctypes code or its doc or something else. If the doc, please suggest a specific change.
Can you test on 3.x?
msg143155 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2011年08月29日 16:15
I can confirm that the same behaviour occur in Python 3.3, and this appears to be by design. There's a specific line in the cast() function in in Modules/_ctypes.c:
rc = PyDict_SetItem(result->b_objects, index, src);
This adds the source object to the _objects of the cast object being returned. However, earlier in the function, the code
CDataObject *obj = (CDataObject *)src;
...
result->b_objects = obj->b_objects;
ensures that result and src are using a single dictionary. Possibly, the result's b_objects needs to be a copy of the src's b_objects; but I don't know enough about ctypes internals to say whether the present code is intentional, or whether an attempt to minimise resource usage (by not copying the dictionary) has led to unwanted consequences.
msg205955 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2013年12月12日 14:26
> Possibly, the result's b_objects needs to be a copy of the src's b_objects
That sounds right to me. I can't really believe that the current behaviour is intentional.
msg205961 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2013年12月12日 16:47
Adding Thomas Heller to nosy to see if he can shed any light on this.
History
Date User Action Args
2022年04月11日 14:57:21adminsetgithub: 57045
2020年09月30日 03:51:20eryksunsetstage: needs patch
versions: + Python 3.8, Python 3.9, Python 3.10, - Python 2.7, Python 3.3
2013年12月12日 16:47:59vinay.sajipsetnosy: + theller
messages: + msg205961
2013年12月12日 14:26:39mark.dickinsonsetnosy: + mark.dickinson
messages: + msg205955
2011年08月29日 16:15:10vinay.sajipsetnosy: + vinay.sajip

messages: + msg143155
versions: + Python 3.3
2011年08月28日 18:39:15terry.reedysetnosy: + terry.reedy

messages: + msg143117
title: cast() creates circular reference in original object -> ctypes.cast() creates circular reference in original object
2011年08月24日 21:53:54bgilbertcreate

AltStyle によって変換されたページ (->オリジナル) /