GeezerVison is showing github.com — IDisposable should implement the context manager protocol · Issue #79 · pythonnet/pythonnet
IDisposable should implement the context manager protocol #79DescriptionPretty self-explanatory :)
Since it's currently not possible to monkey-patch interfaces, this can't be implemented in pure Python. Reacted by NValerij, Daria Maximova, Alex Kulikov, Curtis den Otter, Andrey Andrianov, Sergey Gorbunov, Michael and sean-anderson-seco Activitytonyroberts commented on Jun 26, 2015 Sounds like a good idea, and should be pretty easy to implement.
I think it would just be a case of checking if a type implements IDisposable in ClassManager.GetClassInfo (classmanager.cs) and adding the enter and exit methods. Might need a new subclass of MethodInfo too, since exit and Dispose have different signatures. Reacted by NValerij and Alex Kulikov filmor commented on Jun 26, 2015 Oh, nice hint, I'll have a look. filmor commented on Jun 26, 2015 Doesn't it make more sense to implement this like IEnumerable is implemented, in classbase.cs? tonyroberts commented on Jun 27, 2015 Iterators have a tp_iter pointer in the PyTypeObject struct, which is what is implemented in ClassBase for IEnumerable. There's no equivalent for context managers (unless I've missed something), so I think the enter and exit methods have to be in the class' or object's dict. That's why I was thinking constructing these methods in GetClassInfo would make sense. den-run-ai commented on Jan 30, 2016 filmor commented on Feb 22, 2016 It is, yes. I currently use a simple wrapper function for this:
"""Wrapper function to help dealing with IDisposable classes."""
from inspect import isclass, isfunction
from contextlib import contextmanager
__all__ = ['disposable']
@contextmanager
def disposable(obj_or_class, *args, **kwargs):
"""Contextmanager wrapper around IDisposables."""
if isclass(obj_or_class) or isfunction(obj_or_class):
obj = obj_or_class(*args, **kwargs)
else:
obj = obj_or_class
if hasattr(obj, '__enter__') and hasattr(obj, '__exit__'):
# Already a contextmanager, skip
return obj
if not hasattr(obj, 'Dispose') or not callable(obj.Dispose):
# Likely not IDisposable, currently isinstance doesn't work for
# interfaces so we have to check that in this explicit way
return obj
try:
yield obj
finally:
obj.Dispose()
This allows me to use something like
with disposable(dbConnection):
bla
Since IDisposable is so tied into .NET itself by the using keyword it makes sense to forward this functionality directly. Reacted by Curtis den Otter, NValerij and Michael den-run-ai commented on Feb 23, 2016 filmor commented on Feb 24, 2016 @tonyroberts How exactly would I add a method from C#? Hooking into the attribute resolution feels wrong ... tonyroberts commented on Feb 24, 2016 You could add it to the class dict. That's probably the best way, and I
that's how the normal methods are added I seem to remember.
On Wed, Feb 24, 2016 at 10:29 AM Benedikt Reinartz [email protected]
wrote:
@tonyroberts https://github.com/tonyroberts How exactly would I add a
method from C#? Hooking into the attribute resolution feels wrong ...
—
Reply to this email directly or view it on GitHub
#79 (comment).
awa5114 commented on Mar 23, 2025 It's been about a decade. Has this been addressed yet? Reacted by Kevin Watkins Reacted by Michael den-run-ai commented on Mar 23, 2025 @awa5114 i took a stab at this with claude code, looks reasonable:
#2568
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|