cmdutil: return a dummy, closable file object if it cannot be duped
If the ui I/O descriptors aren't real descriptors, they cannot be duped.
Instead, we return a wrapper object that behaves the same, and
can be closed (by overriding close and doing nothing).
--- a/mercurial/cmdutil.py Wed Jun 08 14:54:52 2011 +0300
+++ b/mercurial/cmdutil.py Wed Jun 15 23:50:33 2011 +0300
@@ -161,7 +161,22 @@
if not pat or pat == '-':
fp = writable and repo.ui.fout or repo.ui.fin
- return os.fdopen(os.dup(fp.fileno()), mode)
+ if hasattr(fp, 'fileno'):
+ return os.fdopen(os.dup(fp.fileno()), mode)
+ else:
+ # if this fp can't be duped properly, return
+ # a dummy object that can be closed
+ class wrappedfileobj(object):
+ noop = lambda x: None
+ def __init__(self, f):
+ self.f = f
+ def __getattr__(self, attr):
+ if attr == 'close':
+ return self.noop
+ else:
+ return getattr(self.f, attr)
+
+ return wrappedfileobj(fp)
if hasattr(pat, 'write') and writable:
return pat
if hasattr(pat, 'read') and 'r' in mode: