I feel like I should clarify - not everyone who posted got it wrong, and I understand there's a side discussion among those who are also interested/participants in https://discuss.python.org/t/demoting-the-is-operator-to-avoid-an-identity-crisis/86/ - but there was no of acknowledgement of Eryk Sun's correct and useful answer which I find very disappointing and a great way to discourage contributions.
We can, and should, do better, at least by thanking the person for their response before running down a barely related side track. On 17Jan.2019 2209, Steve Dower wrote: > For everyone who managed to reply *hours* after Eryk Sun posted the > correct answer and still get it wrong, here it is again in full. > > As a bonus, here's a link to the place where this answer appears in the > documentation: > https://docs.python.org/3/library/ctypes.html#ctypes.py_object > > Cheers, > Steve > > On 17Jan.2019 0550, eryk sun wrote: >> On 1/17/19, Steven D'Aprano <st...@pearwood.info> wrote: >>> >>> I understand that the only way to pass the address of an object to >>> ctypes is to use that id. Is that intentional? >> >> It's kind of dangerous to pass an object to C without an increment of >> its reference count. The proper way is to use a simple pointer of type >> "O" (object), which is already created for you as the "py_object" >> type. >> >> >>> ctypes.py_object._type_ >> 'O' >> >>> ctypes.py_object.__bases__ >> (<class '_ctypes._SimpleCData'>,) >> >> It keeps a reference in the readonly _objects attribute. For example: >> >> >>> b = bytearray(b'spam') >> >>> sys.getrefcount(b) >> 2 >> >>> cb = ctypes.py_object(b) >> >>> sys.getrefcount(b) >> 3 >> >>> cb._objects >> bytearray(b'spam') >> >>> del cb >> >>> sys.getrefcount(b) >> 2 >> >> If you need the address without relying on id(), cast to a void pointer: >> >> >>> ctypes.POINTER(ctypes.c_void_p)(cb)[0] == id(b) >> True >> >> Or instantiate a c_void_p from the py_object as a buffer: >> >> >>> ctypes.c_void_p.from_buffer(cb).value == id(b) >> True >> >> Note that ctypes.cast() doesn't work in this case. It's implemented as >> an FFI function that takes the object address as a void pointer. The >> from_param method of c_void_p doesn't support py_object: >> >> >>> ctypes.c_void_p.from_param(cb) >> Traceback (most recent call last): >> File "<stdin>", line 1, in <module> >> TypeError: wrong type _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com