Skip to content

Manual/deterministic releasing of interface pointers #871

@gexgd0419

Description

@gexgd0419

I wonder, is it possible to release a COM interface pointer manually by calling Release(), instead of waiting for its __del__ to be called?

The problem of this method is that Release() is still called when __del__ is called.

def __del__(self, _debug=logger.debug) -> None:
"Release the COM refcount we own."
if self:
# comtypes calls CoUninitialize() when the atexit handlers
# runs. CoUninitialize() cleans up the COM objects that
# are still alive. Python COM pointers may still be
# present but we can no longer call Release() on them -
# this may give a protection fault. So we need the
# _com_shutting_down flag.
#
if not type(self)._com_shutting_down:
_debug("Release %s", self)
self.Release() # type: ignore

__del__() in Python cannot be used to achieve deterministic destruction, like destructors in C++ do. In the docs:

del() can be invoked when arbitrary code is being executed, including from any arbitrary thread.

This would cause some problems if I want a certain COM object to be released at or before a certain time.

Although CPython uses reference counting, so usually the object will be released when the last reference is removed, it isn't necessarily the case in other Python implementations.

A common solution is to use the context manager. Implement __enter__ and __exit__, so that it can be used in a with block, and be automatically released when leaving the with block. Many resource objects, such as files, already support the context manager protocol.

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions