def close(self):
        if self.closed:
            return

        # Delegate close to self._fp -- it'll try to do it during its
        # destructor which is why delegation is used rather than
        # manipulation of the fd directly.
        self._fp.close()
        try:
            del self._fp
        except AttributeError:
            pass

        try:
            del self._bd
        except __HOLE__:
            pass

        # Invalidate state and flag total completion of the close
        # operation.
        self._fd = -1
dataset/ETHPy150Open wal-e/wal-e/wal_e/pipebuf.py/NonBlockBufferedReader.close