def perform(self, cmd, msg='<STR_LIT>', extra_headers=None):
tries = <NUM_LIT:0><EOL>while <NUM_LIT:1>:<EOL><INDENT>conn = None<EOL>try:<EOL><INDENT>conn = self.get_connection()<EOL>if hasattr(msg, '<STR_LIT>') and hasattr(msg, '<STR_LIT>'):<EOL><INDENT>msg_length = str(os.fstat(msg.fileno()).st_size)<EOL><DEDENT>elif hasattr(msg, '<STR_LIT>'):<EOL><INDENT>msg.seek(<NUM_LIT:0>, <NUM_LIT:2>)<EOL>msg_length = str(msg.tell() + <NUM_LIT:2>)<EOL><DEDENT>else:<EOL><INDENT>if msg:<EOL><INDENT>try:<EOL><INDENT>msg_length = str(len(msg) + <NUM_LIT:2>)<EOL><DEDENT>except TypeError:<EOL><INDENT>conn.close()<EOL>raise ValueError(<EOL>'<STR_LIT>')<EOL><DEDENT><DEDENT>else:<EOL><INDENT>msg_length = '<STR_LIT:2>'<EOL><DEDENT><DEDENT>headers = self.get_headers(cmd, msg_length, extra_headers)<EOL>if isinstance(msg, types.StringTypes):<EOL><INDENT>if self.gzip and msg:<EOL><INDENT>msg = compress(msg + '<STR_LIT:\r\n>', self.compress_level)<EOL><DEDENT>else:<EOL><INDENT>msg = msg + '<STR_LIT:\r\n>'<EOL><DEDENT>conn.send(headers + msg)<EOL><DEDENT>else:<EOL><INDENT>conn.send(headers)<EOL>if hasattr(msg, '<STR_LIT>'):<EOL><INDENT>if hasattr(msg, '<STR_LIT>'):<EOL><INDENT>msg.seek(<NUM_LIT:0>)<EOL><DEDENT>conn.sendfile(msg, self.gzip, self.compress_level)<EOL><DEDENT><DEDENT>conn.send('<STR_LIT:\r\n>')<EOL>try:<EOL><INDENT>conn.socket().shutdown(socket.SHUT_WR)<EOL><DEDENT>except socket.error:<EOL><INDENT>pass<EOL><DEDENT>return get_response(cmd, conn)<EOL><DEDENT>except socket.gaierror as err:<EOL><INDENT>if conn is not None:<EOL><INDENT>conn.release()<EOL><DEDENT>raise SpamCError(str(err))<EOL><DEDENT>except socket.timeout as err:<EOL><INDENT>if conn is not None:<EOL><INDENT>conn.release()<EOL><DEDENT>raise SpamCTimeOutError(str(err))<EOL><DEDENT>except socket.error as err:<EOL><INDENT>if conn is not None:<EOL><INDENT>conn.close()<EOL><DEDENT>errors = (errno.EAGAIN, errno.EPIPE, errno.EBADF,<EOL>errno.ECONNRESET)<EOL>if err[<NUM_LIT:0>] not in errors or tries >= self.max_tries:<EOL><INDENT>raise SpamCError("<STR_LIT>" % str(err))<EOL><DEDENT><DEDENT>except BaseException:<EOL><INDENT>if conn is not None:<EOL><INDENT>conn.release()<EOL><DEDENT>raise<EOL><DEDENT>tries += <NUM_LIT:1><EOL>self.backend_mod.sleep(self.wait_tries)<EOL><DEDENT>
Perform the call