def _override_channel_close(ch: Channel): ch.channel_file = None ch.close_pending = False def do_close(): if ch.channel_file is not None and not ch.channel_file.closed: ch.close_pending = True return else: try: return Channel.close(ch) except EOFError as e: # Some problems while closing yield an EOFError, which is not # descriptive raise ConnectionError('Closing channel') from e ch.close = do_close
def _override_makefile(ch: Channel): # makefile for channels should work the same way as for sockets, but that's # not the case. In particular, if you close the channel the file remains # unusable, which is bad. # When doing makefile on a channel, we store a pointer to the file, so that # when trying to close the channel we can check if the file is still open # and leave the closure pending. We override the close method in the file # as to execute the pending closure if needed. ch.channel_file = None def do_makefile(*args): if ch.channel_file is None: ch.channel_file = Channel.makefile(ch, *args) _override_file_close(ch.channel_file) return ch.channel_file else: raise FileExistsError('We allow only one file per channel') ch.makefile = do_makefile