def parse(self, ticket):
if len(ticket) < self._min_ticket_size():<EOL><INDENT>raise TicketParseError(ticket, '<STR_LIT>')<EOL><DEDENT>digest_len = self._hash.digest_size * <NUM_LIT:2><EOL>digest = ticket[:digest_len]<EOL>try:<EOL><INDENT>time_len = <NUM_LIT:8><EOL>time = int(ticket[digest_len:digest_len + time_len], <NUM_LIT:16>)<EOL><DEDENT>except:<EOL><INDENT>raise TicketParseError(ticket, '<STR_LIT>')<EOL><DEDENT>parts = ticket[digest_len + time_len:].split('<STR_LIT:!>')<EOL>if len(parts) != <NUM_LIT:3>:<EOL><INDENT>raise TicketParseError(ticket, '<STR_LIT>')<EOL><DEDENT>user_id = ulp.unquote(parts[<NUM_LIT:0>])<EOL>tokens = ()<EOL>if parts[<NUM_LIT:1>]:<EOL><INDENT>tokens = tuple((ulp.unquote(t) for t in parts[<NUM_LIT:1>].split('<STR_LIT:U+002C>')))<EOL><DEDENT>user_data = ulp.unquote(parts[<NUM_LIT:2>])<EOL>return TicketInfo(digest, user_id, tokens, user_data, time)<EOL>
Parses the passed ticket, returning a tuple containing the digest,
        user_id, valid_until, tokens, and user_data fields