Pretty self-explanatory :)
Since it's currently not possible to monkey-patch interfaces, this can't be implemented in pure Python.
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.
Oh, nice hint, I'll have a look.
Doesn't it make more sense to implement this like IEnumerable is implemented, in classbase.cs?
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.
@filmor @tonyroberts is this to support with statements like here?
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.
@filmor @tonyroberts this should definitely go into advanced examples!
@tonyroberts How exactly would I add a method from C#? Hooking into the attribute resolution feels wrong ...
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
https://github.com/pythonnet/pythonnet/issues/79#issuecomment-188182437.
Most helpful comment
It is, yes. I currently use a simple wrapper function for this:
This allows me to use something like
Since
IDisposableis so tied into .NET itself by theusingkeyword it makes sense to forward this functionality directly.