def b32decode(s, casefold=False, map01=None):
    """Decode a Base32 encoded string.

    s is the string to decode.  Optional casefold is a flag specifying whether
    a lowercase alphabet is acceptable as input.  For security purposes, the
    default is False.

    RFC 3548 allows for optional mapping of the digit 0 (zero) to the letter O
    (oh), and for optional mapping of the digit 1 (one) to either the letter I
    (eye) or letter L (el).  The optional argument map01 when not None,
    specifies which letter the digit 1 should be mapped to (when map01 is not
    None, the digit 0 is always mapped to the letter O).  For security
    purposes the default is None, so that 0 and 1 are not allowed in the
    input.

    The decoded string is returned.  A TypeError is raised if s were
    incorrectly padded or if there are non-alphabet characters present in the
    string.
    """
    quanta, leftover = divmod(len(s), 8)
    if leftover:
        raise TypeError('Incorrect padding')
    # Handle section 2.4 zero and one mapping.  The flag map01 will be either
    # False, or the character to map the digit 1 (one) to.  It should be
    # either L (el) or I (eye).
    if map01:
        s = s.translate(string.maketrans(b'01', b'O' + map01))
    if casefold:
        s = s.upper()
    # Strip off pad characters from the right.  We need to count the pad
    # characters because this will tell us how many null bytes to remove from
    # the end of the decoded string.
    padchars = 0
    mo = re.search('(?P<pad>[=]*)$', s)
    if mo:
        padchars = len(mo.group('pad'))
        if padchars > 0:
            s = s[:-padchars]
    # Now decode the full quanta
    parts = []
    acc = 0
    shift = 35
    for c in s:
        val = _b32rev.get(c)
        if val is None:
            raise TypeError('Non-base32 digit found')
        acc += _b32rev[c] << shift
        shift -= 5
        if shift < 0:
            parts.append(binascii.unhexlify('%010x' % acc))
            acc = 0
            shift = 35
    # Process the last, partial quanta
    last = binascii.unhexlify('%010x' % acc)
    if padchars == 0:
        last = ''                       # No characters
    elif padchars == 1:
        last = last[:-1]
    elif padchars == 3:
        last = last[:-2]
    elif padchars == 4:
        last = last[:-3]
    elif padchars == 6:
        last = last[:-4]
    else:
        raise TypeError('Incorrect padding')
    parts.append(last)
    return EMPTYSTRING.join(parts)


def b16decode(s, casefold=False):
    """Decode a Base16 encoded string.

    s is the string to decode.  Optional casefold is a flag specifying whether
    a lowercase alphabet is acceptable as input.  For security purposes, the
    default is False.

    The decoded string is returned.  A TypeError is raised if s is
    incorrectly padded or if there are non-alphabet characters present in the
    string.
    """
    if casefold:
        s = s.upper()
    if re.search('[^0-9A-F]', s):
        raise TypeError('Non-base16 digit found')
    return binascii.unhexlify(s)

def
b16decode
(
s
,
casefold
=
False
)
:
if
casefold
:
s
=
s
.
upper
(
)
if
re
.
search
(
'[^0-9A-F]'
,
s
)
:
raise
TypeError
(
'Non-base16 digit found'
)
return
binascii
.
unhexlify
(
s
)


def encode(input, output):
    """Encode a file."""
    while True:
        s = input.read(MAXBINSIZE)
        if not s:
            break
        while len(s) < MAXBINSIZE:
            ns = input.read(MAXBINSIZE-len(s))
            if not ns:
                break
            s += ns
        line = binascii.b2a_base64(s)
        output.write(line)

def encode ( input , output ) : while True : s = input . read ( MAXBINSIZE ) if not s : break while len ( s ) < MAXBINSIZE : ns = input . read ( MAXBINSIZE - len ( s ) ) if not ns : break s += ns line = binascii . b2a_base64 ( s ) output . write ( line )


def decode(input, output):
    """Decode a file."""
    while True:
        line = input.readline()
        if not line:
            break
        s = binascii.a2b_base64(line)
        output.write(s)

def decode ( input , output ) : while True : line = input . readline ( ) if not line : break s = binascii . a2b_base64 ( line ) output . write ( s )


def encodestring(s):
    """Encode a string into multiple lines of base-64 data."""
    pieces = []
    for i in range(0, len(s), MAXBINSIZE):
        chunk = s[i : i + MAXBINSIZE]
        pieces.append(binascii.b2a_base64(chunk))
    return "".join(pieces)

def encodestring ( s ) : pieces = [ ] for i in range ( 0 , len ( s ) , MAXBINSIZE ) : chunk = s [ i : i + MAXBINSIZE ] pieces . append ( binascii . b2a_base64 ( chunk ) ) return "" . join ( pieces )

Encode a string into multiple lines of base - 64 data .


def chain(self, expanded_from):
        """
        Returns a range identical to this one, but indicating that
        it was expanded from the range `expanded_from`.
        """
        return Range(self.source_buffer, self.begin_pos, self.begin_pos,
                     expanded_from=expanded_from)

def chain ( self , expanded_from ) : return Range ( self . source_buffer , self . begin_pos , self . begin_pos , expanded_from = expanded_from )

Returns a range identical to this one but indicating that it was expanded from the range expanded_from .


def begin(self):
        """
        Returns a zero-length range located just before the beginning of this range.
        """
        return Range(self.source_buffer, self.begin_pos, self.begin_pos,
                     expanded_from=self.expanded_from)

def begin ( self ) : return Range ( self . source_buffer , self . begin_pos , self . begin_pos , expanded_from = self . expanded_from )

Returns a zero - length range located just before the beginning of this range .


def end(self):
        """
        Returns a zero-length range located just after the end of this range.
        """
        return Range(self.source_buffer, self.end_pos, self.end_pos,
                     expanded_from=self.expanded_from)

def end ( self ) : return Range ( self . source_buffer , self . end_pos , self . end_pos , expanded_from = self . expanded_from )

Returns a zero - length range located just after the end of this range .


def column(self):
        """
        Returns a zero-based column number of the beginning of this range.
        """
        line, column = self.source_buffer.decompose_position(self.begin_pos)
        return column

def column ( self ) : line , column = self . source_buffer . decompose_position ( self . begin_pos ) return column

Returns a zero - based column number of the beginning of this range .


def line(self):
        """
        Returns the line number of the beginning of this range.
        """
        line, column = self.source_buffer.decompose_position(self.begin_pos)
        return line

def line ( self ) : line , column = self . source_buffer . decompose_position ( self . begin_pos ) return line

Returns the line number of the beginning of this range .


def source_lines(self):
        """
        Returns the lines of source code containing the entirety of this range.
        """
        return [self.source_buffer.source_line(line)
                for line in range(self.line(), self.end().line() + 1)]

def source_lines ( self ) : return [ self . source_buffer . source_line ( line ) for line in range ( self . line ( ) , self . end ( ) . line ( ) + 1 ) ]

Returns the lines of source code containing the entirety of this range .


def compare(left, right, compare_locs=False):
    """
    An AST comparison function. Returns ``True`` if all fields in
    ``left`` are equal to fields in ``right``; if ``compare_locs`` is
    true, all locations should match as well.
    """
    if type(left) != type(right):
        return False

    if isinstance(left, ast.AST):
        for field in left._fields:
            if not compare(getattr(left, field), getattr(right, field)):
                return False

        if compare_locs:
            for loc in left._locs:
                if getattr(left, loc) != getattr(right, loc):
                    return False

        return True
    elif isinstance(left, list):
        if len(left) != len(right):
            return False

        for left_elt, right_elt in zip(left, right):
            if not compare(left_elt, right_elt):
                return False

        return True
    else:
        return left == right

def compare ( left , right , compare_locs = False ) : if type ( left ) != type ( right ) : return False if isinstance ( left , ast . AST ) : for field in left . _fields : if not compare ( getattr ( left , field ) , getattr ( right , field ) ) : return False if compare_locs : for loc in left . _locs : if getattr ( left , loc ) != getattr ( right , loc ) : return False return True elif isinstance ( left , list ) : if len ( left ) != len ( right ) : return False for left_elt , right_elt in zip ( left , right ) : if not compare ( left_elt , right_elt ) : return False return True else : return left == right

An AST comparison function . Returns True if all fields in left are equal to fields in right ; if compare_locs is true all locations should match as well .


def generic_visit(self, node):
        """Called if no explicit visitor function exists for a node."""
        for field_name in node._fields:
            setattr(node, field_name, self.visit(getattr(node, field_name)))
        return node

def generic_visit ( self , node ) : for field_name in node . _fields : setattr ( node , field_name , self . visit ( getattr ( node , field_name ) ) ) return node

Called if no explicit visitor function exists for a node .


def float_unpack(Q, size, le):
  """Convert a 32-bit or 64-bit integer created
  by float_pack into a Python float."""

  if size == 8:
    MIN_EXP = -1021  # = sys.float_info.min_exp
    MAX_EXP = 1024   # = sys.float_info.max_exp
    MANT_DIG = 53    # = sys.float_info.mant_dig
    BITS = 64
  elif size == 4:
    MIN_EXP = -125   # C's FLT_MIN_EXP
    MAX_EXP = 128    # FLT_MAX_EXP
    MANT_DIG = 24    # FLT_MANT_DIG
    BITS = 32
  else:
    raise ValueError("invalid size value")

  if Q >> BITS:
    raise ValueError("input out of range")

  # extract pieces
  sign = Q >> BITS - 1
  exp = (Q & ((1 << BITS - 1) - (1 << MANT_DIG - 1))) >> MANT_DIG - 1
  mant = Q & ((1 << MANT_DIG - 1) - 1)

  if exp == MAX_EXP - MIN_EXP + 2:
    # nan or infinity
    result = float('nan') if mant else float('inf')
  elif exp == 0:
    # subnormal or zero
    result = math.ldexp(float(mant), MIN_EXP - MANT_DIG)
  else:
    # normal
    mant += 1 << MANT_DIG - 1
    result = math.ldexp(float(mant), exp + MIN_EXP - MANT_DIG - 1)
  return -result if sign else result

def
float_unpack
(
Q
,
size
,
le
)
:
if
size
==
8
:
MIN_EXP
=
1021
# = sys.float_info.min_exp
MAX_EXP
=
1024
# = sys.float_info.max_exp
MANT_DIG
=
53
# = sys.float_info.mant_dig
BITS
=
64
elif
size
==
4
:
MIN_EXP
=
125
# C's FLT_MIN_EXP
MAX_EXP
=
128
# FLT_MAX_EXP
MANT_DIG
=
24
# FLT_MANT_DIG
BITS
=
32
else
:
raise
ValueError
(
"invalid size value"
)
if
Q
>>
BITS
:
raise
ValueError
(
"input out of range"
)
# extract pieces
sign
=
Q
>>
BITS
1
exp
=
(
Q
&
(
(
1
<<
BITS
1
)
(
1
<<
MANT_DIG
1
)
)
)
>>
MANT_DIG
1
mant
=
Q
&
(
(
1
<<
MANT_DIG
1
)
1
)
if
exp
==
MAX_EXP
MIN_EXP
+
2
:
# nan or infinity
result
=
float
(
'nan'
)
if
mant
else
float
(
'inf'
)
elif
exp
==
0
:
# subnormal or zero
result
=
math
.
ldexp
(
float
(
mant
)
,
MIN_EXP
MANT_DIG
)
else
:
# normal
mant
+=
1
<<
MANT_DIG
1
result
=
math
.
ldexp
(
float
(
mant
)
,
exp
+
MIN_EXP
MANT_DIG
1
)
return
result
if
sign
else
result

Convert a 32 - bit or 64 - bit integer created by float_pack into a Python float .


def float_pack(x, size):
  """Convert a Python float x into a 64-bit unsigned integer
  with the same byte representation."""

  if size == 8:
    MIN_EXP = -1021  # = sys.float_info.min_exp
    MAX_EXP = 1024   # = sys.float_info.max_exp
    MANT_DIG = 53    # = sys.float_info.mant_dig
    BITS = 64
  elif size == 4:
    MIN_EXP = -125   # C's FLT_MIN_EXP
    MAX_EXP = 128    # FLT_MAX_EXP
    MANT_DIG = 24    # FLT_MANT_DIG
    BITS = 32
  else:
    raise ValueError("invalid size value")

  sign = math.copysign(1.0, x) < 0.0
  if math.isinf(x):
    mant = 0
    exp = MAX_EXP - MIN_EXP + 2
  elif math.isnan(x):
    mant = 1 << (MANT_DIG - 2)  # other values possible
    exp = MAX_EXP - MIN_EXP + 2
  elif x == 0.0:
    mant = 0
    exp = 0
  else:
    m, e = math.frexp(abs(x))  # abs(x) == m * 2**e
    exp = e - (MIN_EXP - 1)
    if exp > 0:
      # Normal case.
      mant = round_to_nearest(m * (1 << MANT_DIG))
      mant -= 1 << MANT_DIG - 1
    else:
      # Subnormal case.
      if exp + MANT_DIG - 1 >= 0:
        mant = round_to_nearest(m * (1 << exp + MANT_DIG - 1))
      else:
        mant = 0
      exp = 0

    # Special case: rounding produced a MANT_DIG-bit mantissa.
    assert 0 <= mant <= 1 << MANT_DIG - 1
    if mant == 1 << MANT_DIG - 1:
      mant = 0
      exp += 1

    # Raise on overflow (in some circumstances, may want to return
    # infinity instead).
    if exp >= MAX_EXP - MIN_EXP + 2:
      raise OverflowError("float too large to pack in this format")

  # check constraints
  assert 0 <= mant < 1 << MANT_DIG - 1
  assert 0 <= exp <= MAX_EXP - MIN_EXP + 2
  assert 0 <= sign <= 1
  return ((sign << BITS - 1) | (exp << MANT_DIG - 1)) | mant

Convert a Python float x into a 64 - bit unsigned integer with the same byte representation .


def context(self, *notes):
        """
        A context manager that appends ``note`` to every diagnostic processed by
        this engine.
        """
        self._appended_notes += notes
        yield
        del self._appended_notes[-len(notes):]

def context ( self , * notes ) : self . _appended_notes += notes yield del self . _appended_notes [ - len ( notes ) : ]

A context manager that appends note to every diagnostic processed by this engine .


def format_list(extracted_list):
    """Format a list of traceback entry tuples for printing.

    Given a list of tuples as returned by extract_tb() or
    extract_stack(), return a list of strings ready for printing.
    Each string in the resulting list corresponds to the item with the
    same index in the argument list.  Each string ends in a newline;
    the strings may contain internal newlines as well, for those items
    whose source text line is not None.
    """
    list = []
    for filename, lineno, name, line in extracted_list:
        item = '  File "%s", line %d, in %s\n' % (filename,lineno,name)
        if line:
            item = item + '    %s\n' % line.strip()
        list.append(item)
    return list

def
format_list
(
extracted_list
)
:
list
=
[
]
for
filename
,
lineno
,
name
,
line
in
extracted_list
:
item
=
'  File "%s", line %d, in %s\n'
%
(
filename
,
lineno
,
name
)
if
line
:
item
=
item
+
'    %s\n'
%
line
.
strip
(
)
list
.
append
(
item
)
return
list

Format a list of traceback entry tuples for printing .


def print_tb(tb, limit=None, file=None):
    """Print up to 'limit' stack trace entries from the traceback 'tb'.

    If 'limit' is omitted or None, all entries are printed.  If 'file'
    is omitted or None, the output goes to sys.stderr; otherwise
    'file' should be an open file or file-like object with a write()
    method.
    """
    if file is None:
        file = sys.stderr
    if limit is None:
        if hasattr(sys, 'tracebacklimit'):
            limit = sys.tracebacklimit
    n = 0
    while tb is not None and (limit is None or n < limit):
        f = tb.tb_frame
        lineno = tb.tb_lineno
        co = f.f_code
        filename = co.co_filename
        name = co.co_name
        _print(file,
               '  File "%s", line %d, in %s' % (filename, lineno, name))
        linecache.checkcache(filename)
        line = linecache.getline(filename, lineno, f.f_globals)
        if line: _print(file, '    ' + line.strip())
        tb = tb.tb_next
        n = n+1

def
print_tb
(
tb
,
limit
=
,
file
=
)
:
if
file
is
:
file
=
sys
.
stderr
if
limit
is
:
if
hasattr
(
sys
,
'tracebacklimit'
)
:
limit
=
sys
.
tracebacklimit
n
=
0
while
tb
is
not
and
(
limit
is
or
n
<
limit
)
:
f
=
tb
.
tb_frame
lineno
=
tb
.
tb_lineno
co
=
f
.
f_code
filename
=
co
.
co_filename
name
=
co
.
co_name
_print
(
file
,
'  File "%s", line %d, in %s'
%
(
filename
,
lineno
,
name
)
)
linecache
.
checkcache
(
filename
)
line
=
linecache
.
getline
(
filename
,
lineno
,
f
.
f_globals
)
if
line
:
_print
(
file
,
'    '
+
line
.
strip
(
)
)
tb
=
tb
.
tb_next
n
=
n
+
1

Print up to limit stack trace entries from the traceback tb .


def print_exception(etype, value, tb, limit=None, file=None):
    """Print exception up to 'limit' stack trace entries from 'tb' to 'file'.

    This differs from print_tb() in the following ways: (1) if
    traceback is not None, it prints a header "Traceback (most recent
    call last):"; (2) it prints the exception type and value after the
    stack trace; (3) if type is SyntaxError and value has the
    appropriate format, it prints the line where the syntax error
    occurred with a caret on the next line indicating the approximate
    position of the error.
    """
    if file is None:
        # TODO: Use sys.stderr when that's implemented.
        file = open('/dev/stderr', 'w')
        #file = sys.stderr
    if tb:
        _print(file, 'Traceback (most recent call last):')
        print_tb(tb, limit, file)
    lines = format_exception_only(etype, value)
    for line in lines:
        _print(file, line, '')

Print exception up to limit stack trace entries from tb to file .


def format_exception(etype, value, tb, limit = None):
    """Format a stack trace and the exception information.

    The arguments have the same meaning as the corresponding arguments
    to print_exception().  The return value is a list of strings, each
    ending in a newline and some containing internal newlines.  When
    these lines are concatenated and printed, exactly the same text is
    printed as does print_exception().
    """
    if tb:
        list = ['Traceback (most recent call last):\n']
        list = list + format_tb(tb, limit)
    else:
        list = []
    list = list + format_exception_only(etype, value)
    return list

def
format_exception
(
etype
,
value
,
tb
,
limit
=
)
:
if
tb
:
list
=
[
'Traceback (most recent call last):\n'
]
list
=
list
+
format_tb
(
tb
,
limit
)
else
:
list
=
[
]
list
=
list
+
format_exception_only
(
etype
,
value
)
return
list

Format a stack trace and the exception information .


def format_exception_only(etype, value):
    """Format the exception part of a traceback.

    The arguments are the exception type and value such as given by
    sys.last_type and sys.last_value. The return value is a list of
    strings, each ending in a newline.

    Normally, the list contains a single string; however, for
    SyntaxError exceptions, it contains several lines that (when
    printed) display detailed information about where the syntax
    error occurred.

    The message indicating which exception occurred is always the last
    string in the list.

    """

    # An instance should not have a meaningful value parameter, but
    # sometimes does, particularly for string exceptions, such as
    # >>> raise string1, string2  # deprecated
    #
    # Clear these out first because issubtype(string1, SyntaxError)
    # would raise another exception and mask the original problem.
    if (isinstance(etype, BaseException) or
#        isinstance(etype, types.InstanceType) or
        etype is None or type(etype) is str):
        return [_format_final_exc_line(etype, value)]

    stype = etype.__name__

    if not issubclass(etype, SyntaxError):
        return [_format_final_exc_line(stype, value)]

    # It was a syntax error; show exactly where the problem was found.
    lines = []
    try:
        msg, (filename, lineno, offset, badline) = value.args
    except Exception:
        pass
    else:
        filename = filename or "<string>"
        lines.append('  File "%s", line %d\n' % (filename, lineno))
        if badline is not None:
            lines.append('    %s\n' % badline.strip())
            if offset is not None:
                caretspace = badline.rstrip('\n')
                offset = min(len(caretspace), offset) - 1
                caretspace = caretspace[:offset].lstrip()
                # non-space whitespace (likes tabs) must be kept for alignment
                caretspace = ((c.isspace() and c or ' ') for c in caretspace)
                lines.append('    %s^\n' % ''.join(caretspace))
        value = msg

    lines.append(_format_final_exc_line(stype, value))
    return lines

Format the exception part of a traceback .


def print_stack(f=None, limit=None, file=None):
    """Print a stack trace from its invocation point.

    The optional 'f' argument can be used to specify an alternate
    stack frame at which to start. The optional 'limit' and 'file'
    arguments have the same meaning as for print_exception().
    """
    if f is None:
        try:
            raise ZeroDivisionError
        except ZeroDivisionError:
            f = sys.exc_info()[2].tb_frame.f_back
    print_list(extract_stack(f, limit), file)

def print_stack ( f = None , limit = None , file = None ) : if f is None : try : raise ZeroDivisionError except ZeroDivisionError : f = sys . exc_info ( ) [ 2 ] . tb_frame . f_back print_list ( extract_stack ( f , limit ) , file )

Print a stack trace from its invocation point .


def extract_stack(f=None, limit = None):
    """Extract the raw traceback from the current stack frame.

    The return value has the same format as for extract_tb().  The
    optional 'f' and 'limit' arguments have the same meaning as for
    print_stack().  Each item in the list is a quadruple (filename,
    line number, function name, text), and the entries are in order
    from oldest to newest stack frame.
    """
    if f is None:
        try:
            raise ZeroDivisionError
        except ZeroDivisionError:
            f = sys.exc_info()[2].tb_frame.f_back
    if limit is None:
        if hasattr(sys, 'tracebacklimit'):
            limit = sys.tracebacklimit
    list = []
    n = 0
    while f is not None and (limit is None or n < limit):
        lineno = f.f_lineno
        co = f.f_code
        filename = co.co_filename
        name = co.co_name
        linecache.checkcache(filename)
        line = linecache.getline(filename, lineno, f.f_globals)
        if line: line = line.strip()
        else: line = None
        list.append((filename, lineno, name, line))
        f = f.f_back
        n = n+1
    list.reverse()
    return list

def extract_stack ( f = None , limit = None ) : if f is None : try : raise ZeroDivisionError except ZeroDivisionError : f = sys . exc_info ( ) [ 2 ] . tb_frame . f_back if limit is None : if hasattr ( sys , 'tracebacklimit' ) : limit = sys . tracebacklimit list = [ ] n = 0 while f is not None and ( limit is None or n < limit ) : lineno = f . f_lineno co = f . f_code filename = co . co_filename name = co . co_name linecache . checkcache ( filename ) line = linecache . getline ( filename , lineno , f . f_globals ) if line : line = line . strip ( ) else : line = None list . append ( ( filename , lineno , name , line ) ) f = f . f_back n = n + 1 list . reverse ( ) return list

Extract the raw traceback from the current stack frame .


def seed(self, a=None):
        """Initialize internal state of the random number generator.

        None or no argument seeds from current time or from an operating
        system specific randomness source if available.

        If a is not None or is an int or long, hash(a) is used instead.
        Hash values for some types are nondeterministic when the
        PYTHONHASHSEED environment variable is enabled.
        """

        super(Random, self).seed(a)
        self.gauss_next = None

def seed ( self , a = None ) : super ( Random , self ) . seed ( a ) self . gauss_next = None

Initialize internal state of the random number generator .


def shuffle(self, x, random=None):
        """x, random=random.random -> shuffle list x in place; return None.

        Optional arg random is a 0-argument function returning a random
        float in [0.0, 1.0); by default, the standard random.random.

        """

        if random is None:
            random = self.random
        _int = int
        for i in reversed(xrange(1, len(x))):
            # pick an element in x[:i+1] with which to exchange x[i]
            j = _int(random() * (i+1))
            x[i], x[j] = x[j], x[i]

x random = random . random - > shuffle list x in place ; return None .


def _slotnames(cls):
    """Return a list of slot names for a given class.

    This needs to find slots defined by the class and its bases, so we
    can't simply return the __slots__ attribute.  We must walk down
    the Method Resolution Order and concatenate the __slots__ of each
    class found there.  (This assumes classes don't modify their
    __slots__ attribute to misrepresent their slots after the class is
    defined.)
    """

    # Get the value from a cache in the class if possible
    names = cls.__dict__.get("__slotnames__")
    if names is not None:
        return names

    # Not cached -- calculate the value
    names = []
    if not hasattr(cls, "__slots__"):
        # This class has no slots
        pass
    else:
        # Slots found -- gather slot names from all base classes
        for c in cls.__mro__:
            if "__slots__" in c.__dict__:
                slots = c.__dict__['__slots__']
                # if class has a single slot, it can be given as a string
                if isinstance(slots, basestring):
                    slots = (slots,)
                for name in slots:
                    # special descriptors
                    if name in ("__dict__", "__weakref__"):
                        continue
                    # mangled names
                    elif name.startswith('__') and not name.endswith('__'):
                        names.append('_%s%s' % (c.__name__, name))
                    else:
                        names.append(name)

    # Cache the outcome in the class if at all possible
    try:
        cls.__slotnames__ = names
    except:
        pass # But don't die if we can't

    return names

Return a list of slot names for a given class .


def add_extension(module, name, code):
    """Register an extension code."""
    code = int(code)
    if not 1 <= code <= 0x7fffffff:
        raise ValueError, "code out of range"
    key = (module, name)
    if (_extension_registry.get(key) == code and
        _inverted_registry.get(code) == key):
        return # Redundant registrations are benign
    if key in _extension_registry:
        raise ValueError("key %s is already registered with code %s" %
                         (key, _extension_registry[key]))
    if code in _inverted_registry:
        raise ValueError("code %s is already in use for key %s" %
                         (code, _inverted_registry[code]))
    _extension_registry[key] = code
    _inverted_registry[code] = key


def remove_extension(module, name, code):
    """Unregister an extension code.  For testing only."""
    key = (module, name)
    if (_extension_registry.get(key) != code or
        _inverted_registry.get(code) != key):
        raise ValueError("key %s is not registered with code %s" %
                         (key, code))
    del _extension_registry[key]
    del _inverted_registry[code]
    if code in _extension_cache:
        del _extension_cache[code]

def
remove_extension
(
module
,
name
,
code
)
:
key
=
(
module
,
name
)
if
(
_extension_registry
.
get
(
key
)
!=
code
or
_inverted_registry
.
get
(
code
)
!=
key
)
:
raise
ValueError
(
"key %s is not registered with code %s"
%
(
key
,
code
)
)
del
_extension_registry
[
key
]
del
_inverted_registry
[
code
]
if
code
in
_extension_cache
:
del
_extension_cache
[
code
]

Unregister an extension code . For testing only .


def update_wrapper(wrapper,
                   wrapped,
                   assigned = WRAPPER_ASSIGNMENTS,
                   updated = WRAPPER_UPDATES):
    """Update a wrapper function to look like the wrapped function

       wrapper is the function to be updated
       wrapped is the original function
       assigned is a tuple naming the attributes assigned directly
       from the wrapped function to the wrapper function (defaults to
       functools.WRAPPER_ASSIGNMENTS)
       updated is a tuple naming the attributes of the wrapper that
       are updated with the corresponding attribute from the wrapped
       function (defaults to functools.WRAPPER_UPDATES)
    """
    for attr in assigned:
        setattr(wrapper, attr, getattr(wrapped, attr))
    for attr in updated:
        getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
    # Return the wrapper so this can be used as a decorator via partial()
    return wrapper


def cmp_to_key(mycmp):
    """Convert a cmp= function into a key= function"""
    class K(object):
        __slots__ = ['obj']
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
        def __hash__(self):
            raise TypeError('hash not implemented')
    return K

def
cmp_to_key
(
mycmp
)
:
class
K
(
object
)
:
__slots__
=
[
'obj'
]
def
__init__
(
self
,
obj
,
*
args
)
:
self
.
obj
=
obj
def
__lt__
(
self
,
other
)
:
return
mycmp
(
self
.
obj
,
other
.
obj
)
<
0
def
__gt__
(
self
,
other
)
:
return
mycmp
(
self
.
obj
,
other
.
obj
)
>
0
def
__eq__
(
self
,
other
)
:
return
mycmp
(
self
.
obj
,
other
.
obj
)
==
0
def
__le__
(
self
,
other
)
:
return
mycmp
(
self
.
obj
,
other
.
obj
)
<=
0
def
__ge__
(
self
,
other
)
:
return
mycmp
(
self
.
obj
,
other
.
obj
)
>=
0
def
__ne__
(
self
,
other
)
:
return
mycmp
(
self
.
obj
,
other
.
obj
)
!=
0
def
__hash__
(
self
)
:
raise
TypeError
(
'hash not implemented'
)
return
K

Convert a cmp = function into a key = function


def unquote(s):
    """Remove quotes from a string."""
    if len(s) > 1:
        if s.startswith('"') and s.endswith('"'):
            return s[1:-1].replace('\\\\', '\\').replace('\\"', '"')
        if s.startswith('<') and s.endswith('>'):
            return s[1:-1]
    return s

def unquote ( s ) : if len ( s ) > 1 : if s . startswith ( '"' ) and s . endswith ( '"' ) : return s [ 1 : - 1 ] . replace ( '\\\\' , '\\' ) . replace ( '\\"' , '"' ) if s . startswith ( '<' ) and s . endswith ( '>' ) : return s [ 1 : - 1 ] return s


def formatdate(timeval=None):
    """Returns time format preferred for Internet standards.

    Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123

    According to RFC 1123, day and month names must always be in
    English.  If not for that, this code could use strftime().  It
    can't because strftime() honors the locale and could generate
    non-English names.
    """
    if timeval is None:
        timeval = time.time()
    timeval = time.gmtime(timeval)
    return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (
            ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")[timeval[6]],
            timeval[2],
            ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")[timeval[1]-1],
                                timeval[0], timeval[3], timeval[4], timeval[5])

def
formatdate
(
timeval
=
)
:
if
timeval
is
:
timeval
=
time
.
time
(
)
timeval
=
time
.
gmtime
(
timeval
)
return
"%s, %02d %s %04d %02d:%02d:%02d GMT"
%
(
(
"Mon"
,
"Tue"
,
"Wed"
,
"Thu"
,
"Fri"
,
"Sat"
,
"Sun"
)
[
timeval
[
6
]
]
,
timeval
[
2
]
,
(
"Jan"
,
"Feb"
,
"Mar"
,
"Apr"
,
"May"
,
"Jun"
,
"Jul"
,
"Aug"
,
"Sep"
,
"Oct"
,
"Nov"
,
"Dec"
)
[
timeval
[
1
]
1
]
,
timeval
[
0
]
,
timeval
[
3
]
,
timeval
[
4
]
,
timeval
[
5
]
)

Returns time format preferred for Internet standards .


def readheaders(self):
        """Read header lines.

        Read header lines up to the entirely blank line that terminates them.
        The (normally blank) line that ends the headers is skipped, but not
        included in the returned list.  If a non-header line ends the headers,
        (which is an error), an attempt is made to backspace over it; it is
        never included in the returned list.

        The variable self.status is set to the empty string if all went well,
        otherwise it is an error message.  The variable self.headers is a
        completely uninterpreted list of lines contained in the header (so
        printing them will reproduce the header exactly as it appears in the
        file).
        """
        self.dict = {}
        self.unixfrom = ''
        self.headers = lst = []
        self.status = ''
        headerseen = ""
        firstline = 1
        startofline = unread = tell = None
        if hasattr(self.fp, 'unread'):
            unread = self.fp.unread
        elif self.seekable:
            tell = self.fp.tell
        while 1:
            if tell:
                try:
                    startofline = tell()
                except IOError:
                    startofline = tell = None
                    self.seekable = 0
            line = self.fp.readline()
            if not line:
                self.status = 'EOF in headers'
                break
            # Skip unix From name time lines
            if firstline and line.startswith('From '):
                self.unixfrom = self.unixfrom + line
                continue
            firstline = 0
            if headerseen and line[0] in ' \t':
                # It's a continuation line.
                lst.append(line)
                x = (self.dict[headerseen] + "\n " + line.strip())
                self.dict[headerseen] = x.strip()
                continue
            elif self.iscomment(line):
                # It's a comment.  Ignore it.
                continue
            elif self.islast(line):
                # Note! No pushback here!  The delimiter line gets eaten.
                break
            headerseen = self.isheader(line)
            if headerseen:
                # It's a legal header line, save it.
                lst.append(line)
                self.dict[headerseen] = line[len(headerseen)+1:].strip()
                continue
            elif headerseen is not None:
                # An empty header name. These aren't allowed in HTTP, but it's
                # probably a benign mistake. Don't add the header, just keep
                # going.
                continue
            else:
                # It's not a header line; throw it back and stop here.
                if not self.dict:
                    self.status = 'No headers'
                else:
                    self.status = 'Non-header line where header expected'
                # Try to undo the read.
                if unread:
                    unread(line)
                elif tell:
                    self.fp.seek(startofline)
                else:
                    self.status = self.status + '; bad seek'
                break


def isheader(self, line):
        """Determine whether a given line is a legal header.

        This method should return the header name, suitably canonicalized.
        You may override this method in order to use Message parsing on tagged
        data in RFC 2822-like formats with special header formats.
        """
        i = line.find(':')
        if i > -1:
            return line[:i].lower()
        return None

def isheader ( self , line ) : i = line . find ( ':' ) if i > - 1 : return line [ : i ] . lower ( ) return None

Determine whether a given line is a legal header .


def getfirstmatchingheader(self, name):
        """Get the first header line matching name.

        This is similar to getallmatchingheaders, but it returns only the
        first matching header (and its continuation lines).
        """
        name = name.lower() + ':'
        n = len(name)
        lst = []
        hit = 0
        for line in self.headers:
            if hit:
                if not line[:1].isspace():
                    break
            elif line[:n].lower() == name:
                hit = 1
            if hit:
                lst.append(line)
        return lst

def getfirstmatchingheader ( self , name ) : name = name . lower ( ) + ':' n = len ( name ) lst = [ ] hit = 0 for line in self . headers : if hit : if not line [ : 1 ] . isspace ( ) : break elif line [ : n ] . lower ( ) == name : hit = 1 if hit : lst . append ( line ) return lst

Get the first header line matching name .


def getheader(self, name, default=None):
        """Get the header value for a name.

        This is the normal interface: it returns a stripped version of the
        header value for a given header name, or None if it doesn't exist.
        This uses the dictionary version which finds the *last* such header.
        """
        return self.dict.get(name.lower(), default)

def getheader ( self , name , default = None ) : return self . dict . get ( name . lower ( ) , default )


def getheaders(self, name):
        """Get all values for a header.

        This returns a list of values for headers given more than once; each
        value in the result list is stripped in the same way as the result of
        getheader().  If the header is not given, return an empty list.
        """
        result = []
        current = ''
        have_header = 0
        for s in self.getallmatchingheaders(name):
            if s[0].isspace():
                if current:
                    current = "%s\n %s" % (current, s.strip())
                else:
                    current = s.strip()
            else:
                if have_header:
                    result.append(current)
                current = s[s.find(":") + 1:].strip()
                have_header = 1
        if have_header:
            result.append(current)
        return result

def
getheaders
(
self
,
name
)
:
result
=
[
]
current
=
''
have_header
=
0
for
s
in
self
.
getallmatchingheaders
(
name
)
:
if
s
[
0
]
.
isspace
(
)
:
if
current
:
current
=
"%s\n %s"
%
(
current
,
s
.
strip
(
)
)
else
:
current
=
s
.
strip
(
)
else
:
if
have_header
:
result
.
append
(
current
)
current
=
s
[
s
.
find
(
":"
)
+
1
:
]
.
strip
(
)
have_header
=
1
if
have_header
:
result
.
append
(
current
)
return
result


def getaddrlist(self, name):
        """Get a list of addresses from a header.

        Retrieves a list of addresses from a header, where each address is a
        tuple as returned by getaddr().  Scans all named headers, so it works
        properly with multiple To: or Cc: headers for example.
        """
        raw = []
        for h in self.getallmatchingheaders(name):
            if h[0] in ' \t':
                raw.append(h)
            else:
                if raw:
                    raw.append(', ')
                i = h.find(':')
                if i > 0:
                    addr = h[i+1:]
                raw.append(addr)
        alladdrs = ''.join(raw)
        a = AddressList(alladdrs)
        return a.addresslist

def
getaddrlist
(
self
,
name
)
:
raw
=
[
]
for
h
in
self
.
getallmatchingheaders
(
name
)
:
if
h
[
0
]
in
' \t'
:
raw
.
append
(
h
)
else
:
if
raw
:
raw
.
append
(
', '
)
i
=
h
.
find
(
':'
)
if
i
>
0
:
addr
=
h
[
i
+
1
:
]
raw
.
append
(
addr
)
alladdrs
=
''
.
join
(
raw
)
a
=
AddressList
(
alladdrs
)
return
a
.
addresslist


def gotonext(self):
        """Parse up to the start of the next address."""
        while self.pos < len(self.field):
            if self.field[self.pos] in self.LWS + '\n\r':
                self.pos = self.pos + 1
            elif self.field[self.pos] == '(':
                self.commentlist.append(self.getcomment())
            else: break

def gotonext ( self ) : while self . pos < len ( self . field ) : if self . field [ self . pos ] in self . LWS + '\n\r' : self . pos = self . pos + 1 elif self . field [ self . pos ] == '(' : self . commentlist . append ( self . getcomment ( ) ) else : break

Parse up to the start of the next address .


def getaddrlist(self):
        """Parse all addresses.

        Returns a list containing all of the addresses.
        """
        result = []
        ad = self.getaddress()
        while ad:
            result += ad
            ad = self.getaddress()
        return result

def getaddrlist ( self ) : result = [ ] ad = self . getaddress ( ) while ad : result += ad ad = self . getaddress ( ) return result


def getaddrspec(self):
        """Parse an RFC 2822 addr-spec."""
        aslist = []

        self.gotonext()
        while self.pos < len(self.field):
            if self.field[self.pos] == '.':
                aslist.append('.')
                self.pos += 1
            elif self.field[self.pos] == '"':
                aslist.append('"%s"' % self.getquote())
            elif self.field[self.pos] in self.atomends:
                break
            else: aslist.append(self.getatom())
            self.gotonext()

        if self.pos >= len(self.field) or self.field[self.pos] != '@':
            return ''.join(aslist)

        aslist.append('@')
        self.pos += 1
        self.gotonext()
        return ''.join(aslist) + self.getdomain()

def getaddrspec ( self ) : aslist = [ ] self . gotonext ( ) while self . pos < len ( self . field ) : if self . field [ self . pos ] == '.' : aslist . append ( '.' ) self . pos += 1 elif self . field [ self . pos ] == '"' : aslist . append ( '"%s"' % self . getquote ( ) ) elif self . field [ self . pos ] in self . atomends : break else : aslist . append ( self . getatom ( ) ) self . gotonext ( ) if self . pos >= len ( self . field ) or self . field [ self . pos ] != '@' : return '' . join ( aslist ) aslist . append ( '@' ) self . pos += 1 self . gotonext ( ) return '' . join ( aslist ) + self . getdomain ( )


def getdomain(self):
        """Get the complete domain name from an address."""
        sdlist = []
        while self.pos < len(self.field):
            if self.field[self.pos] in self.LWS:
                self.pos += 1
            elif self.field[self.pos] == '(':
                self.commentlist.append(self.getcomment())
            elif self.field[self.pos] == '[':
                sdlist.append(self.getdomainliteral())
            elif self.field[self.pos] == '.':
                self.pos += 1
                sdlist.append('.')
            elif self.field[self.pos] in self.atomends:
                break
            else: sdlist.append(self.getatom())
        return ''.join(sdlist)

def getdomain ( self ) : sdlist = [ ] while self . pos < len ( self . field ) : if self . field [ self . pos ] in self . LWS : self . pos += 1 elif self . field [ self . pos ] == '(' : self . commentlist . append ( self . getcomment ( ) ) elif self . field [ self . pos ] == '[' : sdlist . append ( self . getdomainliteral ( ) ) elif self . field [ self . pos ] == '.' : self . pos += 1 sdlist . append ( '.' ) elif self . field [ self . pos ] in self . atomends : break else : sdlist . append ( self . getatom ( ) ) return '' . join ( sdlist )

Get the complete domain name from an address .


def getdelimited(self, beginchar, endchars, allowcomments = 1):
        """Parse a header fragment delimited by special characters.

        `beginchar' is the start character for the fragment.  If self is not
        looking at an instance of `beginchar' then getdelimited returns the
        empty string.

        `endchars' is a sequence of allowable end-delimiting characters.
        Parsing stops when one of these is encountered.

        If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed
        within the parsed fragment.
        """
        if self.field[self.pos] != beginchar:
            return ''

        slist = ['']
        quote = 0
        self.pos += 1
        while self.pos < len(self.field):
            if quote == 1:
                slist.append(self.field[self.pos])
                quote = 0
            elif self.field[self.pos] in endchars:
                self.pos += 1
                break
            elif allowcomments and self.field[self.pos] == '(':
                slist.append(self.getcomment())
                continue        # have already advanced pos from getcomment
            elif self.field[self.pos] == '\\':
                quote = 1
            else:
                slist.append(self.field[self.pos])
            self.pos += 1

        return ''.join(slist)

Parse a header fragment delimited by special characters .


def getphraselist(self):
        """Parse a sequence of RFC 2822 phrases.

        A phrase is a sequence of words, which are in turn either RFC 2822
        atoms or quoted-strings.  Phrases are canonicalized by squeezing all
        runs of continuous whitespace into one space.
        """
        plist = []

        while self.pos < len(self.field):
            if self.field[self.pos] in self.LWS:
                self.pos += 1
            elif self.field[self.pos] == '"':
                plist.append(self.getquote())
            elif self.field[self.pos] == '(':
                self.commentlist.append(self.getcomment())
            elif self.field[self.pos] in self.phraseends:
                break
            else:
                plist.append(self.getatom(self.phraseends))

        return plist

def getphraselist ( self ) : plist = [ ] while self . pos < len ( self . field ) : if self . field [ self . pos ] in self . LWS : self . pos += 1 elif self . field [ self . pos ] == '"' : plist . append ( self . getquote ( ) ) elif self . field [ self . pos ] == '(' : self . commentlist . append ( self . getcomment ( ) ) elif self . field [ self . pos ] in self . phraseends : break else : plist . append ( self . getatom ( self . phraseends ) ) return plist


def _days_in_month(year, month):
    "year, month -> number of days in that month in that year."
    assert 1 <= month <= 12, month
    if month == 2 and _is_leap(year):
        return 29
    return _DAYS_IN_MONTH[month]

def _days_in_month ( year , month ) : assert 1 <= month <= 12 , month if month == 2 and _is_leap ( year ) : return 29 return _DAYS_IN_MONTH [ month ]

year month - > number of days in that month in that year .


def _ymd2ord(year, month, day):
    "year, month, day -> ordinal, considering 01-Jan-0001 as day 1."
    assert 1 <= month <= 12, 'month must be in 1..12'
    dim = _days_in_month(year, month)
    assert 1 <= day <= dim, ('day must be in 1..%d' % dim)
    return (_days_before_year(year) +
            _days_before_month(year, month) +
            day)

def
_ymd2ord
(
year
,
month
,
day
)
:
assert
1
<=
month
<=
12
,
'month must be in 1..12'
dim
=
_days_in_month
(
year
,
month
)
assert
1
<=
day
<=
dim
,
(
'day must be in 1..%d'
%
dim
)
return
(
_days_before_year
(
year
)
+
_days_before_month
(
year
,
month
)
+
day
)

year month day - > ordinal considering 01 - Jan - 0001 as day 1 .


def fromordinal(cls, n):
        """Contruct a date from a proleptic Gregorian ordinal.

        January 1 of year 1 is day 1.  Only the year, month and day are
        non-zero in the result.
        """
        y, m, d = _ord2ymd(n)
        return cls(y, m, d)

def fromordinal ( cls , n ) : y , m , d = _ord2ymd ( n ) return cls ( y , m , d )

Contruct a date from a proleptic Gregorian ordinal .


def isoformat(self):
        """Return the date formatted according to ISO.

        This is 'YYYY-MM-DD'.

        References:
        - http://www.w3.org/TR/NOTE-datetime
        - http://www.cl.cam.ac.uk/~mgk25/iso-time.html
        """
        # return "%04d-%02d-%02d" % (self._year, self._month, self._day)
        return "%s-%s-%s" % (str(self._year).zfill(4), str(self._month).zfill(2), str(self._day).zfill(2))

Return the date formatted according to ISO .


def replace(self, year=None, month=None, day=None):
        """Return a new date with new values for the specified fields."""
        if year is None:
            year = self._year
        if month is None:
            month = self._month
        if day is None:
            day = self._day
        return date.__new__(type(self), year, month, day)

def replace ( self , year = None , month = None , day = None ) : if year is None : year = self . _year if month is None : month = self . _month if day is None : day = self . _day return date . __new__ ( type ( self ) , year , month , day )

Return a new date with new values for the specified fields .


def isocalendar(self):
        """Return a 3-tuple containing ISO year, week number, and weekday.

        The first ISO week of the year is the (Mon-Sun) week
        containing the year's first Thursday; everything else derives
        from that.

        The first week is 1; Monday is 1 ... Sunday is 7.

        ISO calendar algorithm taken from
        http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
        """
        year = self._year
        week1monday = _isoweek1monday(year)
        today = _ymd2ord(self._year, self._month, self._day)
        # Internally, week and day have origin 0
        week, day = divmod(today - week1monday, 7)
        if week < 0:
            year -= 1
            week1monday = _isoweek1monday(year)
            week, day = divmod(today - week1monday, 7)
        elif week >= 52:
            if today >= _isoweek1monday(year+1):
                year += 1
                week = 0
        return year, week+1, day+1

Return a 3 - tuple containing ISO year week number and weekday .


def tzname(self):
        """Return the timezone name.

        Note that the name is 100% informational -- there's no requirement that
        it mean anything in particular. For example, "GMT", "UTC", "-500",
        "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies.
        """
        if self._tzinfo is None:
            return None
        name = self._tzinfo.tzname(None)
        _check_tzname(name)
        return name

def tzname ( self ) : if self . _tzinfo is None : return None name = self . _tzinfo . tzname ( None ) _check_tzname ( name ) return name


def replace(self, hour=None, minute=None, second=None, microsecond=None,
                tzinfo=True):
        """Return a new time with new values for the specified fields."""
        if hour is None:
            hour = self.hour
        if minute is None:
            minute = self.minute
        if second is None:
            second = self.second
        if microsecond is None:
            microsecond = self.microsecond
        if tzinfo is True:
            tzinfo = self.tzinfo
        return time.__new__(type(self),
                            hour, minute, second, microsecond, tzinfo)

def replace ( self , hour = None , minute = None , second = None , microsecond = None , tzinfo = True ) : if hour is None : hour = self . hour if minute is None : minute = self . minute if second is None : second = self . second if microsecond is None : microsecond = self . microsecond if tzinfo is True : tzinfo = self . tzinfo return time . __new__ ( type ( self ) , hour , minute , second , microsecond , tzinfo )

Return a new time with new values for the specified fields .


def combine(cls, date, time):
        "Construct a datetime from a given date and a given time."
        if not isinstance(date, _date_class):
            raise TypeError("date argument must be a date instance")
        if not isinstance(time, _time_class):
            raise TypeError("time argument must be a time instance")
        return cls(date.year, date.month, date.day,
                   time.hour, time.minute, time.second, time.microsecond,
                   time.tzinfo)

def
combine
(
cls
,
date
,
time
)
:
if
not
isinstance
(
date
,
_date_class
)
:
raise
TypeError
(
"date argument must be a date instance"
)
if
not
isinstance
(
time
,
_time_class
)
:
raise
TypeError
(
"time argument must be a time instance"
)
return
cls
(
date
.
year
,
date
.
month
,
date
.
day
,
time
.
hour
,
time
.
minute
,
time
.
second
,
time
.
microsecond
,
time
.
tzinfo
)

Construct a datetime from a given date and a given time .


def time(self):
        "Return the time part, with tzinfo None."
        return time(self.hour, self.minute, self.second, self.microsecond)

def time ( self ) : return time ( self . hour , self . minute , self . second , self . microsecond )


def timetz(self):
        "Return the time part, with same tzinfo."
        return time(self.hour, self.minute, self.second, self.microsecond,
                    self._tzinfo)

def timetz ( self ) : return time ( self . hour , self . minute , self . second , self . microsecond , self . _tzinfo )


def replace(self, year=None, month=None, day=None, hour=None,
                minute=None, second=None, microsecond=None, tzinfo=True):
        """Return a new datetime with new values for the specified fields."""
        if year is None:
            year = self.year
        if month is None:
            month = self.month
        if day is None:
            day = self.day
        if hour is None:
            hour = self.hour
        if minute is None:
            minute = self.minute
        if second is None:
            second = self.second
        if microsecond is None:
            microsecond = self.microsecond
        if tzinfo is True:
            tzinfo = self.tzinfo
        return datetime.__new__(type(self),
                                year, month, day, hour, minute, second,
                                microsecond, tzinfo)

def replace ( self , year = None , month = None , day = None , hour = None , minute = None , second = None , microsecond = None , tzinfo = True ) : if year is None : year = self . year if month is None : month = self . month if day is None : day = self . day if hour is None : hour = self . hour if minute is None : minute = self . minute if second is None : second = self . second if microsecond is None : microsecond = self . microsecond if tzinfo is True : tzinfo = self . tzinfo return datetime . __new__ ( type ( self ) , year , month , day , hour , minute , second , microsecond , tzinfo )

Return a new datetime with new values for the specified fields .


def concat(a, b):
    "Same as a + b, for a and b sequences."
    if not hasattr(a, '__getitem__'):
        msg = "'%s' object can't be concatenated" % type(a).__name__
        raise TypeError(msg)
    return a + b

def
concat
(
a
,
b
)
:
if
not
hasattr
(
a
,
'__getitem__'
)
:
msg
=
"'%s' object can't be concatenated"
%
type
(
a
)
.
__name__
raise
TypeError
(
msg
)
return
a
+
b


def countOf(a, b):
    "Return the number of times b occurs in a."
    count = 0
    for i in a:
        if i == b:
            count += 1
    return count

def countOf ( a , b ) : count = 0 for i in a : if i == b : count += 1 return count

Return the number of times b occurs in a .


def indexOf(a, b):
    "Return the first index of b in a."
    for i, j in enumerate(a):
        if j == b:
            return i
    else:
        raise ValueError('sequence.index(x): x not in sequence')

def
indexOf
(
a
,
b
)
:
for
i
,
j
in
enumerate
(
a
)
:
if
j
==
b
:
return
i
else
:
raise
ValueError
(
'sequence.index(x): x not in sequence'
)


def iconcat(a, b):
    "Same as a += b, for a and b sequences."
    if not hasattr(a, '__getitem__'):
        msg = "'%s' object can't be concatenated" % type(a).__name__
        raise TypeError(msg)
    a += b
    return a

def
iconcat
(
a
,
b
)
:
if
not
hasattr
(
a
,
'__getitem__'
)
:
msg
=
"'%s' object can't be concatenated"
%
type
(
a
)
.
__name__
raise
TypeError
(
msg
)
a
+=
b
return
a


def encode_basestring(s):
    """Return a JSON representation of a Python string

    """
    def replace(match):
        return ESCAPE_DCT[match.group(0)]
    return '"' + ESCAPE.sub(replace, s) + '"'

def encode_basestring ( s ) : def replace ( match ) : return ESCAPE_DCT [ match . group ( 0 ) ] return '"' + ESCAPE . sub ( replace , s ) + '"'


def sub(pattern, repl, string, count=0, flags=0):
    """Return the string obtained by replacing the leftmost
    non-overlapping occurrences of the pattern in string by the
    replacement repl.  repl can be either a string or a callable;
    if a string, backslash escapes in it are processed.  If it is
    a callable, it's passed the match object and must return
    a replacement string to be used."""
    return _compile(pattern, flags).sub(repl, string, count)

def sub ( pattern , repl , string , count = 0 , flags = 0 ) : return _compile ( pattern , flags ) . sub ( repl , string , count )

Return the string obtained by replacing the leftmost non - overlapping occurrences of the pattern in string by the replacement repl . repl can be either a string or a callable ; if a string backslash escapes in it are processed . If it is a callable it s passed the match object and must return a replacement string to be used .


def split(pattern, string, maxsplit=0, flags=0):
    """Split the source string by the occurrences of the pattern,
    returning a list containing the resulting substrings."""
    return _compile(pattern, flags).split(string, maxsplit)

def split ( pattern , string , maxsplit = 0 , flags = 0 ) : return _compile ( pattern , flags ) . split ( string , maxsplit )

Split the source string by the occurrences of the pattern returning a list containing the resulting substrings .


def findall(pattern, string, flags=0):
    """Return a list of all non-overlapping matches in the string.

    If one or more groups are present in the pattern, return a
    list of groups; this will be a list of tuples if the pattern
    has more than one group.

    Empty matches are included in the result."""
    return _compile(pattern, flags).findall(string)

    # if sys.hexversion >= 0x02020000:
    #     __all__.append("finditer")
    def finditer(pattern, string, flags=0):
        """Return an iterator over all non-overlapping matches in the
        string.  For each match, the iterator returns a match object.

        Empty matches are included in the result."""
        return _compile(pattern, flags).finditer(string)

Return a list of all non - overlapping matches in the string .


def escape(pattern):
    "Escape all non-alphanumeric characters in pattern."
    s = list(pattern)
    alphanum = _alphanum
    for i, c in enumerate(pattern):
        if c not in alphanum:
            if c == "\000":
                s[i] = "\\000"
            else:
                s[i] = "\\" + c
    return pattern[:0].join(s)

def escape ( pattern ) : s = list ( pattern ) alphanum = _alphanum for i , c in enumerate ( pattern ) : if c not in alphanum : if c == "\000" : s [ i ] = "\\000" else : s [ i ] = "\\" + c return pattern [ : 0 ] . join ( s )

Escape all non - alphanumeric characters in pattern .


def free_temp(self, v):
    """Release the GeneratedTempVar v so it can be reused."""
    self.used_temps.remove(v)
    self.free_temps.add(v)

def free_temp ( self , v ) : self . used_temps . remove ( v ) self . free_temps . add ( v )

Release the GeneratedTempVar v so it can be reused .


def decode(in_file, out_file=None, mode=None, quiet=0):
    """Decode uuencoded file"""
    #
    # Open the input file, if needed.
    #
    opened_files = []
    if in_file == '-':
        in_file = sys.stdin
    elif isinstance(in_file, basestring):
        in_file = open(in_file)
        opened_files.append(in_file)
    try:
        #
        # Read until a begin is encountered or we've exhausted the file
        #
        while True:
            hdr = in_file.readline()
            if not hdr:
                raise Error('No valid begin line found in input file')
            if not hdr.startswith('begin'):
                continue
            hdrfields = hdr.split(' ', 2)
            if len(hdrfields) == 3 and hdrfields[0] == 'begin':
                try:
                    int(hdrfields[1], 8)
                    break
                except ValueError:
                    pass
        if out_file is None:
            out_file = hdrfields[2].rstrip()
            if os.path.exists(out_file):
                raise Error('Cannot overwrite existing file: %s' % out_file)
        if mode is None:
            mode = int(hdrfields[1], 8)
        #
        # Open the output file
        #
        if out_file == '-':
            out_file = sys.stdout
        elif isinstance(out_file, basestring):
            fp = open(out_file, 'wb')
            try:
                os.path.chmod(out_file, mode)
            except AttributeError:
                pass
            out_file = fp
            opened_files.append(out_file)
        #
        # Main decoding loop
        #
        s = in_file.readline()
        while s and s.strip() != 'end':
            try:
                data = binascii.a2b_uu(s)
            except binascii.Error, v:
                # Workaround for broken uuencoders by /Fredrik Lundh
                nbytes = (((ord(s[0])-32) & 63) * 4 + 5) // 3
                data = binascii.a2b_uu(s[:nbytes])
                if not quiet:
                    sys.stderr.write("Warning: %s\n" % v)
            out_file.write(data)
            s = in_file.readline()
        if not s:
            raise Error('Truncated input file')
    finally:
        for f in opened_files:
            f.close()


def get_close_matches(word, possibilities, n=3, cutoff=0.6):
    """Use SequenceMatcher to return list of the best "good enough" matches.

    word is a sequence for which close matches are desired (typically a
    string).

    possibilities is a list of sequences against which to match word
    (typically a list of strings).

    Optional arg n (default 3) is the maximum number of close matches to
    return.  n must be > 0.

    Optional arg cutoff (default 0.6) is a float in [0, 1].  Possibilities
    that don't score at least that similar to word are ignored.

    The best (no more than n) matches among the possibilities are returned
    in a list, sorted by similarity score, most similar first.

    >>> get_close_matches("appel", ["ape", "apple", "peach", "puppy"])
    ['apple', 'ape']
    >>> import keyword as _keyword
    >>> get_close_matches("wheel", _keyword.kwlist)
    ['while']
    >>> get_close_matches("apple", _keyword.kwlist)
    []
    >>> get_close_matches("accept", _keyword.kwlist)
    ['except']
    """

    if not n >  0:
        raise ValueError("n must be > 0: %r" % (n,))
    if not 0.0 <= cutoff <= 1.0:
        raise ValueError("cutoff must be in [0.0, 1.0]: %r" % (cutoff,))
    result = []
    s = SequenceMatcher()
    s.set_seq2(word)
    for x in possibilities:
        s.set_seq1(x)
        if s.real_quick_ratio() >= cutoff and \
           s.quick_ratio() >= cutoff and \
           s.ratio() >= cutoff:
            result.append((s.ratio(), x))

    # Move the best scorers to head of list
    result = heapq.nlargest(n, result)
    # Strip scores for the best n matches
    return [x for score, x in result]

def
get_close_matches
(
word
,
possibilities
,
n
=
3
,
cutoff
=
0.6
)
:
if
not
n
>
0
:
raise
ValueError
(
"n must be > 0: %r"
%
(
n
,
)
)
if
not
0.0
<=
cutoff
<=
1.0
:
raise
ValueError
(
"cutoff must be in [0.0, 1.0]: %r"
%
(
cutoff
,
)
)
result
=
[
]
s
=
SequenceMatcher
(
)
s
.
set_seq2
(
word
)
for
x
in
possibilities
:
s
.
set_seq1
(
x
)
if
s
.
real_quick_ratio
(
)
>=
cutoff
and
s
.
quick_ratio
(
)
>=
cutoff
and
s
.
ratio
(
)
>=
cutoff
:
result
.
append
(
(
s
.
ratio
(
)
,
x
)
)
# Move the best scorers to head of list
result
=
heapq
.
nlargest
(
n
,
result
)
# Strip scores for the best n matches
return
[
x
for
score
,
x
in
result
]

Use SequenceMatcher to return list of the best good enough matches .


def _count_leading(line, ch):
    """
    Return number of `ch` characters at the start of `line`.

    Example:

    >>> _count_leading('   abc', ' ')
    3
    """

    i, n = 0, len(line)
    while i < n and line[i] == ch:
        i += 1
    return i

def _count_leading ( line , ch ) : i , n = 0 , len ( line ) while i < n and line [ i ] == ch : i += 1 return i

Return number of ch characters at the start of line .


def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
                 tofiledate='', n=3, lineterm='\n'):
    r"""
    Compare two sequences of lines; generate the delta as a unified diff.

    Unified diffs are a compact way of showing line changes and a few
    lines of context.  The number of context lines is set by 'n' which
    defaults to three.

    By default, the diff control lines (those with ---, +++, or @@) are
    created with a trailing newline.  This is helpful so that inputs
    created from file.readlines() result in diffs that are suitable for
    file.writelines() since both the inputs and outputs have trailing
    newlines.

    For inputs that do not have trailing newlines, set the lineterm
    argument to "" so that the output will be uniformly newline free.

    The unidiff format normally has a header for filenames and modification
    times.  Any or all of these may be specified using strings for
    'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
    The modification times are normally expressed in the ISO 8601 format.

    Example:

    >>> for line in unified_diff('one two three four'.split(),
    ...             'zero one tree four'.split(), 'Original', 'Current',
    ...             '2005-01-26 23:30:50', '2010-04-02 10:20:52',
    ...             lineterm=''):
    ...     print line                  # doctest: +NORMALIZE_WHITESPACE
    --- Original        2005-01-26 23:30:50
    +++ Current         2010-04-02 10:20:52
    @@ -1,4 +1,4 @@
    +zero
     one
    -two
    -three
    +tree
     four
    """

    started = False
    for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
        if not started:
            started = True
            # fromdate = '\t{}'.format(fromfiledate) if fromfiledate else ''
            fromdate = '\t%s' % (fromfiledate) if fromfiledate else ''
            # todate = '\t{}'.format(tofiledate) if tofiledate else ''
            todate = '\t%s' % (tofiledate) if tofiledate else ''
            # yield '--- {}{}{}'.format(fromfile, fromdate, lineterm)
            yield '--- %s%s%s' % (fromfile, fromdate, lineterm)
            # yield '+++ {}{}{}'.format(tofile, todate, lineterm)
            yield '+++ %s%s%s' % (tofile, todate, lineterm)

        first, last = group[0], group[-1]
        file1_range = _format_range_unified(first[1], last[2])
        file2_range = _format_range_unified(first[3], last[4])
        # yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm)
        yield '@@ -%s +%s @@%s' % (file1_range, file2_range, lineterm)

        for tag, i1, i2, j1, j2 in group:
            if tag == 'equal':
                for line in a[i1:i2]:
                    yield ' ' + line
                continue
            if tag in ('replace', 'delete'):
                for line in a[i1:i2]:
                    yield '-' + line
            if tag in ('replace', 'insert'):
                for line in b[j1:j2]:
                    yield '+' + line

r Compare two sequences of lines ; generate the delta as a unified diff .


def context_diff(a, b, fromfile='', tofile='',
                 fromfiledate='', tofiledate='', n=3, lineterm='\n'):
    r"""
    Compare two sequences of lines; generate the delta as a context diff.

    Context diffs are a compact way of showing line changes and a few
    lines of context.  The number of context lines is set by 'n' which
    defaults to three.

    By default, the diff control lines (those with *** or ---) are
    created with a trailing newline.  This is helpful so that inputs
    created from file.readlines() result in diffs that are suitable for
    file.writelines() since both the inputs and outputs have trailing
    newlines.

    For inputs that do not have trailing newlines, set the lineterm
    argument to "" so that the output will be uniformly newline free.

    The context diff format normally has a header for filenames and
    modification times.  Any or all of these may be specified using
    strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
    The modification times are normally expressed in the ISO 8601 format.
    If not specified, the strings default to blanks.

    Example:

    >>> print ''.join(context_diff('one\ntwo\nthree\nfour\n'.splitlines(1),
    ...       'zero\none\ntree\nfour\n'.splitlines(1), 'Original', 'Current')),
    *** Original
    --- Current
    ***************
    *** 1,4 ****
      one
    ! two
    ! three
      four
    --- 1,4 ----
    + zero
      one
    ! tree
      four
    """

    prefix = dict(insert='+ ', delete='- ', replace='! ', equal='  ')
    started = False
    for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
        if not started:
            started = True
            # fromdate = '\t{}'.format(fromfiledate) if fromfiledate else ''
            fromdate = '\t%s' % (fromfiledate) if fromfiledate else ''
            # todate = '\t{}'.format(tofiledate) if tofiledate else ''
            todate = '\t%s' % (tofiledate) if tofiledate else ''
            # yield '*** {}{}{}'.format(fromfile, fromdate, lineterm)
            yield '*** %s%s%s' % (fromfile, fromdate, lineterm)
            # yield '--- {}{}{}'.format(tofile, todate, lineterm)
            yield '--- %s%s%s' % (tofile, todate, lineterm)

        first, last = group[0], group[-1]
        yield '***************' + lineterm

        file1_range = _format_range_context(first[1], last[2])
        # yield '*** {} ****{}'.format(file1_range, lineterm)
        yield '*** %s ****%s' % (file1_range, lineterm)

        if any(tag in ('replace', 'delete') for tag, _, _, _, _ in group):
            for tag, i1, i2, _, _ in group:
                if tag != 'insert':
                    for line in a[i1:i2]:
                        yield prefix[tag] + line

        file2_range = _format_range_context(first[3], last[4])
        # yield '--- {} ----{}'.format(file2_range, lineterm)
        yield '--- %s ----%s' % (file2_range, lineterm)

        if any(tag in ('replace', 'insert') for tag, _, _, _, _ in group):
            for tag, _, _, j1, j2 in group:
                if tag != 'delete':
                    for line in b[j1:j2]:
                        yield prefix[tag] + line

r Compare two sequences of lines ; generate the delta as a context diff .


def restore(delta, which):
    r"""
    Generate one of the two sequences that generated a delta.

    Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract
    lines originating from file 1 or 2 (parameter `which`), stripping off line
    prefixes.

    Examples:

    >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
    ...              'ore\ntree\nemu\n'.splitlines(1))
    >>> diff = list(diff)
    >>> print ''.join(restore(diff, 1)),
    one
    two
    three
    >>> print ''.join(restore(diff, 2)),
    ore
    tree
    emu
    """
    try:
        tag = {1: "- ", 2: "+ "}[int(which)]
    except KeyError:
        raise ValueError, ('unknown delta choice (must be 1 or 2): %r'
                           % which)
    prefixes = ("  ", tag)
    for line in delta:
        if line[:2] in prefixes:
            yield line[2:]

r Generate one of the two sequences that generated a delta .


def _make(cls, iterable, new=tuple.__new__, len=len):
        'Make a new Match object from a sequence or iterable'
        result = new(cls, iterable)
        if len(result) != 3:
            raise TypeError('Expected 3 arguments, got %d' % len(result))
        return result

def
_make
(
cls
,
iterable
,
new
=
tuple
.
__new__
,
len
=
len
)
:
result
=
new
(
cls
,
iterable
)
if
len
(
result
)
!=
3
:
raise
TypeError
(
'Expected 3 arguments, got %d'
%
len
(
result
)
)
return
result


def set_seq1(self, a):
        """Set the first sequence to be compared.

        The second sequence to be compared is not changed.

        >>> s = SequenceMatcher(None, "abcd", "bcde")
        >>> s.ratio()
        0.75
        >>> s.set_seq1("bcde")
        >>> s.ratio()
        1.0
        >>>

        SequenceMatcher computes and caches detailed information about the
        second sequence, so if you want to compare one sequence S against
        many sequences, use .set_seq2(S) once and call .set_seq1(x)
        repeatedly for each of the other sequences.

        See also set_seqs() and set_seq2().
        """

        if a is self.a:
            return
        self.a = a
        self.matching_blocks = self.opcodes = None

def set_seq1 ( self , a ) : if a is self . a : return self . a = a self . matching_blocks = self . opcodes = None


def set_seq2(self, b):
        """Set the second sequence to be compared.

        The first sequence to be compared is not changed.

        >>> s = SequenceMatcher(None, "abcd", "bcde")
        >>> s.ratio()
        0.75
        >>> s.set_seq2("abcd")
        >>> s.ratio()
        1.0
        >>>

        SequenceMatcher computes and caches detailed information about the
        second sequence, so if you want to compare one sequence S against
        many sequences, use .set_seq2(S) once and call .set_seq1(x)
        repeatedly for each of the other sequences.

        See also set_seqs() and set_seq1().
        """

        if b is self.b:
            return
        self.b = b
        self.matching_blocks = self.opcodes = None
        self.fullbcount = None
        self.__chain_b()

def set_seq2 ( self , b ) : if b is self . b : return self . b = b self . matching_blocks = self . opcodes = None self . fullbcount = None self . __chain_b ( )

Set the second sequence to be compared .


def get_matching_blocks(self):
        """Return list of triples describing matching subsequences.

        Each triple is of the form (i, j, n), and means that
        a[i:i+n] == b[j:j+n].  The triples are monotonically increasing in
        i and in j.  New in Python 2.5, it's also guaranteed that if
        (i, j, n) and (i', j', n') are adjacent triples in the list, and
        the second is not the last triple in the list, then i+n != i' or
        j+n != j'.  IOW, adjacent triples never describe adjacent equal
        blocks.

        The last triple is a dummy, (len(a), len(b), 0), and is the only
        triple with n==0.

        >>> s = SequenceMatcher(None, "abxcd", "abcd")
        >>> s.get_matching_blocks()
        [Match(a=0, b=0, size=2), Match(a=3, b=2, size=2), Match(a=5, b=4, size=0)]
        """

        if self.matching_blocks is not None:
            return self.matching_blocks
        la, lb = len(self.a), len(self.b)

        # This is most naturally expressed as a recursive algorithm, but
        # at least one user bumped into extreme use cases that exceeded
        # the recursion limit on their box.  So, now we maintain a list
        # ('queue`) of blocks we still need to look at, and append partial
        # results to `matching_blocks` in a loop; the matches are sorted
        # at the end.
        queue = [(0, la, 0, lb)]
        matching_blocks = []
        while queue:
            alo, ahi, blo, bhi = queue.pop()
            i, j, k = x = self.find_longest_match(alo, ahi, blo, bhi)
            # a[alo:i] vs b[blo:j] unknown
            # a[i:i+k] same as b[j:j+k]
            # a[i+k:ahi] vs b[j+k:bhi] unknown
            if k:   # if k is 0, there was no matching block
                matching_blocks.append(x)
                if alo < i and blo < j:
                    queue.append((alo, i, blo, j))
                if i+k < ahi and j+k < bhi:
                    queue.append((i+k, ahi, j+k, bhi))
        matching_blocks.sort()

        # It's possible that we have adjacent equal blocks in the
        # matching_blocks list now.  Starting with 2.5, this code was added
        # to collapse them.
        i1 = j1 = k1 = 0
        non_adjacent = []
        for i2, j2, k2 in matching_blocks:
            # Is this block adjacent to i1, j1, k1?
            if i1 + k1 == i2 and j1 + k1 == j2:
                # Yes, so collapse them -- this just increases the length of
                # the first block by the length of the second, and the first
                # block so lengthened remains the block to compare against.
                k1 += k2
            else:
                # Not adjacent.  Remember the first block (k1==0 means it's
                # the dummy we started with), and make the second block the
                # new block to compare against.
                if k1:
                    non_adjacent.append((i1, j1, k1))
                i1, j1, k1 = i2, j2, k2
        if k1:
            non_adjacent.append((i1, j1, k1))

        non_adjacent.append( (la, lb, 0) )
        self.matching_blocks = map(Match._make, non_adjacent)
        return self.matching_blocks

Return list of triples describing matching subsequences .


def get_opcodes(self):
        """Return list of 5-tuples describing how to turn a into b.

        Each tuple is of the form (tag, i1, i2, j1, j2).  The first tuple
        has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the
        tuple preceding it, and likewise for j1 == the previous j2.

        The tags are strings, with these meanings:

        'replace':  a[i1:i2] should be replaced by b[j1:j2]
        'delete':   a[i1:i2] should be deleted.
                    Note that j1==j2 in this case.
        'insert':   b[j1:j2] should be inserted at a[i1:i1].
                    Note that i1==i2 in this case.
        'equal':    a[i1:i2] == b[j1:j2]

        >>> a = "qabxcd"
        >>> b = "abycdf"
        >>> s = SequenceMatcher(None, a, b)
        >>> for tag, i1, i2, j1, j2 in s.get_opcodes():
        ...    print ("%7s a[%d:%d] (%s) b[%d:%d] (%s)" %
        ...           (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2]))
         delete a[0:1] (q) b[0:0] ()
          equal a[1:3] (ab) b[0:2] (ab)
        replace a[3:4] (x) b[2:3] (y)
          equal a[4:6] (cd) b[3:5] (cd)
         insert a[6:6] () b[5:6] (f)
        """

        if self.opcodes is not None:
            return self.opcodes
        i = j = 0
        self.opcodes = answer = []
        for ai, bj, size in self.get_matching_blocks():
            # invariant:  we've pumped out correct diffs to change
            # a[:i] into b[:j], and the next matching block is
            # a[ai:ai+size] == b[bj:bj+size].  So we need to pump
            # out a diff to change a[i:ai] into b[j:bj], pump out
            # the matching block, and move (i,j) beyond the match
            tag = ''
            if i < ai and j < bj:
                tag = 'replace'
            elif i < ai:
                tag = 'delete'
            elif j < bj:
                tag = 'insert'
            if tag:
                answer.append( (tag, i, ai, j, bj) )
            i, j = ai+size, bj+size
            # the list of matching blocks is terminated by a
            # sentinel with size 0
            if size:
                answer.append( ('equal', ai, i, bj, j) )
        return answer

Return list of 5 - tuples describing how to turn a into b .


def get_grouped_opcodes(self, n=3):
        """ Isolate change clusters by eliminating ranges with no changes.

        Return a generator of groups with up to n lines of context.
        Each group is in the same format as returned by get_opcodes().

        >>> from pprint import pprint
        >>> a = map(str, range(1,40))
        >>> b = a[:]
        >>> b[8:8] = ['i']     # Make an insertion
        >>> b[20] += 'x'       # Make a replacement
        >>> b[23:28] = []      # Make a deletion
        >>> b[30] += 'y'       # Make another replacement
        >>> pprint(list(SequenceMatcher(None,a,b).get_grouped_opcodes()))
        [[('equal', 5, 8, 5, 8), ('insert', 8, 8, 8, 9), ('equal', 8, 11, 9, 12)],
         [('equal', 16, 19, 17, 20),
          ('replace', 19, 20, 20, 21),
          ('equal', 20, 22, 21, 23),
          ('delete', 22, 27, 23, 23),
          ('equal', 27, 30, 23, 26)],
         [('equal', 31, 34, 27, 30),
          ('replace', 34, 35, 30, 31),
          ('equal', 35, 38, 31, 34)]]
        """

        codes = self.get_opcodes()
        if not codes:
            codes = [("equal", 0, 1, 0, 1)]
        # Fixup leading and trailing groups if they show no changes.
        if codes[0][0] == 'equal':
            tag, i1, i2, j1, j2 = codes[0]
            codes[0] = tag, max(i1, i2-n), i2, max(j1, j2-n), j2
        if codes[-1][0] == 'equal':
            tag, i1, i2, j1, j2 = codes[-1]
            codes[-1] = tag, i1, min(i2, i1+n), j1, min(j2, j1+n)

        nn = n + n
        group = []
        for tag, i1, i2, j1, j2 in codes:
            # End the current group and start a new one whenever
            # there is a large range with no changes.
            if tag == 'equal' and i2-i1 > nn:
                group.append((tag, i1, min(i2, i1+n), j1, min(j2, j1+n)))
                yield group
                group = []
                i1, j1 = max(i1, i2-n), max(j1, j2-n)
            group.append((tag, i1, i2, j1 ,j2))
        if group and not (len(group)==1 and group[0][0] == 'equal'):
            yield group

Isolate change clusters by eliminating ranges with no changes .


def compare(self, a, b):
        r"""
        Compare two sequences of lines; generate the resulting delta.

        Each sequence must contain individual single-line strings ending with
        newlines. Such sequences can be obtained from the `readlines()` method
        of file-like objects.  The delta generated also consists of newline-
        terminated strings, ready to be printed as-is via the writeline()
        method of a file-like object.

        Example:

        >>> print ''.join(Differ().compare('one\ntwo\nthree\n'.splitlines(1),
        ...                                'ore\ntree\nemu\n'.splitlines(1))),
        - one
        ?  ^
        + ore
        ?  ^
        - two
        - three
        ?  -
        + tree
        + emu
        """

        cruncher = SequenceMatcher(self.linejunk, a, b)
        for tag, alo, ahi, blo, bhi in cruncher.get_opcodes():
            if tag == 'replace':
                g = self._fancy_replace(a, alo, ahi, b, blo, bhi)
            elif tag == 'delete':
                g = self._dump('-', a, alo, ahi)
            elif tag == 'insert':
                g = self._dump('+', b, blo, bhi)
            elif tag == 'equal':
                g = self._dump(' ', a, alo, ahi)
            else:
                raise ValueError, 'unknown tag %r' % (tag,)

            for line in g:
                yield line

def
compare
(
self
,
a
,
b
)
:
cruncher
=
SequenceMatcher
(
self
.
linejunk
,
a
,
b
)
for
tag
,
alo
,
ahi
,
blo
,
bhi
in
cruncher
.
get_opcodes
(
)
:
if
tag
==
'replace'
:
g
=
self
.
_fancy_replace
(
a
,
alo
,
ahi
,
b
,
blo
,
bhi
)
elif
tag
==
'delete'
:
g
=
self
.
_dump
(
'-'
,
a
,
alo
,
ahi
)
elif
tag
==
'insert'
:
g
=
self
.
_dump
(
'+'
,
b
,
blo
,
bhi
)
elif
tag
==
'equal'
:
g
=
self
.
_dump
(
' '
,
a
,
alo
,
ahi
)
else
:
raise
ValueError
,
'unknown tag %r'
%
(
tag
,
)
for
line
in
g
:
yield
line

r Compare two sequences of lines ; generate the resulting delta .


def _dump(self, tag, x, lo, hi):
        """Generate comparison results for a same-tagged range."""
        for i in xrange(lo, hi):
            yield '%s %s' % (tag, x[i])

def
_dump
(
self
,
tag
,
x
,
lo
,
hi
)
:
for
i
in
xrange
(
lo
,
hi
)
:
yield
'%s %s'
%
(
tag
,
x
[
i
]
)

Generate comparison results for a same - tagged range .


def _qformat(self, aline, bline, atags, btags):
        r"""
        Format "?" output and deal with leading tabs.

        Example:

        >>> d = Differ()
        >>> results = d._qformat('\tabcDefghiJkl\n', '\tabcdefGhijkl\n',
        ...                      '  ^ ^  ^      ', '  ^ ^  ^      ')
        >>> for line in results: print repr(line)
        ...
        '- \tabcDefghiJkl\n'
        '? \t ^ ^  ^\n'
        '+ \tabcdefGhijkl\n'
        '? \t ^ ^  ^\n'
        """

        # Can hurt, but will probably help most of the time.
        common = min(_count_leading(aline, "\t"),
                     _count_leading(bline, "\t"))
        common = min(common, _count_leading(atags[:common], " "))
        common = min(common, _count_leading(btags[:common], " "))
        atags = atags[common:].rstrip()
        btags = btags[common:].rstrip()

        yield "- " + aline
        if atags:
            yield "? %s%s\n" % ("\t" * common, atags)

        yield "+ " + bline
        if btags:
            yield "? %s%s\n" % ("\t" * common, btags)

r Format ? output and deal with leading tabs .


def make_file(self,fromlines,tolines,fromdesc='',todesc='',context=False,
                  numlines=5):
        """Returns HTML file of side by side comparison with change highlights

        Arguments:
        fromlines -- list of "from" lines
        tolines -- list of "to" lines
        fromdesc -- "from" file column header string
        todesc -- "to" file column header string
        context -- set to True for contextual differences (defaults to False
            which shows full differences).
        numlines -- number of context lines.  When context is set True,
            controls number of lines displayed before and after the change.
            When context is False, controls the number of lines to place
            the "next" link anchors before the next change (so click of
            "next" link jumps to just before the change).
        """

        return self._file_template % dict(
            styles = self._styles,
            legend = self._legend,
            table = self.make_table(fromlines,tolines,fromdesc,todesc,
                                    context=context,numlines=numlines))

def make_file ( self , fromlines , tolines , fromdesc = '' , todesc = '' , context = False , numlines = 5 ) : return self . _file_template % dict ( styles = self . _styles , legend = self . _legend , table = self . make_table ( fromlines , tolines , fromdesc , todesc , context = context , numlines = numlines ) )


def _split_line(self,data_list,line_num,text):
        """Builds list of text lines by splitting text lines at wrap point

        This function will determine if the input text line needs to be
        wrapped (split) into separate lines.  If so, the first wrap point
        will be determined and the first line appended to the output
        text line list.  This function is used recursively to handle
        the second part of the split line to further split it.
        """
        # if blank line or context separator, just add it to the output list
        if not line_num:
            data_list.append((line_num,text))
            return

        # if line text doesn't need wrapping, just add it to the output list
        size = len(text)
        max = self._wrapcolumn
        if (size <= max) or ((size -(text.count('\0')*3)) <= max):
            data_list.append((line_num,text))
            return

        # scan text looking for the wrap point, keeping track if the wrap
        # point is inside markers
        i = 0
        n = 0
        mark = ''
        while n < max and i < size:
            if text[i] == '\0':
                i += 1
                mark = text[i]
                i += 1
            elif text[i] == '\1':
                i += 1
                mark = ''
            else:
                i += 1
                n += 1

        # wrap point is inside text, break it up into separate lines
        line1 = text[:i]
        line2 = text[i:]

        # if wrap point is inside markers, place end marker at end of first
        # line and start marker at beginning of second line because each
        # line will have its own table tag markup around it.
        if mark:
            line1 = line1 + '\1'
            line2 = '\0' + mark + line2

        # tack on first line onto the output list
        data_list.append((line_num,line1))

        # use this routine again to wrap the remaining text
        self._split_line(data_list,'>',line2)


def _collect_lines(self,diffs):
        """Collects mdiff output into separate lists

        Before storing the mdiff from/to data into a list, it is converted
        into a single line of text with HTML markup.
        """

        fromlist,tolist,flaglist = [],[],[]
        # pull from/to data and flags from mdiff style iterator
        for fromdata,todata,flag in diffs:
            try:
                # store HTML markup of the lines into the lists
                fromlist.append(self._format_line(0,flag,*fromdata))
                tolist.append(self._format_line(1,flag,*todata))
            except TypeError:
                # exceptions occur for lines where context separators go
                fromlist.append(None)
                tolist.append(None)
            flaglist.append(flag)
        return fromlist,tolist,flaglist


def _make_prefix(self):
        """Create unique anchor prefixes"""

        # Generate a unique anchor prefix so multiple tables
        # can exist on the same HTML page without conflicts.
        fromprefix = "from%d_" % HtmlDiff._default_prefix
        toprefix = "to%d_" % HtmlDiff._default_prefix
        HtmlDiff._default_prefix += 1
        # store prefixes so line format method has access
        self._prefix = [fromprefix,toprefix]


def _convert_flags(self,fromlist,tolist,flaglist,context,numlines):
        """Makes list of "next" links"""

        # all anchor names will be generated using the unique "to" prefix
        toprefix = self._prefix[1]

        # process change flags, generating middle column of next anchors/links
        next_id = ['']*len(flaglist)
        next_href = ['']*len(flaglist)
        num_chg, in_change = 0, False
        last = 0
        for i,flag in enumerate(flaglist):
            if flag:
                if not in_change:
                    in_change = True
                    last = i
                    # at the beginning of a change, drop an anchor a few lines
                    # (the context lines) before the change for the previous
                    # link
                    i = max([0,i-numlines])
                    next_id[i] = ' id="difflib_chg_%s_%d"' % (toprefix,num_chg)
                    # at the beginning of a change, drop a link to the next
                    # change
                    num_chg += 1
                    next_href[last] = 'n' % (
                         toprefix,num_chg)
            else:
                in_change = False
        # check for cases where there is no content to avoid exceptions
        if not flaglist:
            flaglist = [False]
            next_id = ['']
            next_href = ['']
            last = 0
            if context:
                fromlist = ['	 No Differences Found 	']
                tolist = fromlist
            else:
                fromlist = tolist = ['	 Empty File 	']
        # if not a change on first line, drop a link
        if not flaglist[0]:
            next_href[0] = 'f' % toprefix
        # redo the last link to link to the top
        next_href[last] = 't' % (toprefix)

        return fromlist,tolist,flaglist,next_href,next_id


def make_table(self,fromlines,tolines,fromdesc='',todesc='',context=False,
                   numlines=5):
        """Returns HTML table of side by side comparison with change highlights

        Arguments:
        fromlines -- list of "from" lines
        tolines -- list of "to" lines
        fromdesc -- "from" file column header string
        todesc -- "to" file column header string
        context -- set to True for contextual differences (defaults to False
            which shows full differences).
        numlines -- number of context lines.  When context is set True,
            controls number of lines displayed before and after the change.
            When context is False, controls the number of lines to place
            the "next" link anchors before the next change (so click of
            "next" link jumps to just before the change).
        """

        # make unique anchor prefixes so that multiple tables may exist
        # on the same page without conflict.
        self._make_prefix()

        # change tabs to spaces before it gets more difficult after we insert
        # markup
        fromlines,tolines = self._tab_newline_replace(fromlines,tolines)

        # create diffs iterator which generates side by side from/to data
        if context:
            context_lines = numlines
        else:
            context_lines = None
        diffs = _mdiff(fromlines,tolines,context_lines,linejunk=self._linejunk,
                      charjunk=self._charjunk)

        # set up iterator to wrap lines that exceed desired width
        if self._wrapcolumn:
            diffs = self._line_wrapper(diffs)

        # collect up from/to lines and flags into lists (also format the lines)
        fromlist,tolist,flaglist = self._collect_lines(diffs)

        # process change flags, generating middle column of next anchors/links
        fromlist,tolist,flaglist,next_href,next_id = self._convert_flags(
            fromlist,tolist,flaglist,context,numlines)

        s = []
        fmt = '
%s	%s' + \
              '%s	%s
\n'
        for i in range(len(flaglist)):
            if flaglist[i] is None:
                # mdiff yields None on separator lines skip the bogus ones
                # generated for the first line
                if i > 0:
                    s.append('
        \n
\n')
            else:
                s.append( fmt % (next_id[i],next_href[i],fromlist[i],
                                           next_href[i],tolist[i]))
        if fromdesc or todesc:
            header_row = '

%s%s%s%s

' % (
                '
	',
                '%s	' % fromdesc,
                '
	',
                '%s	' % todesc)
        else:
            header_row = ''

        table = self._table_template % dict(
            data_rows=''.join(s),
            header_row=header_row,
            prefix=self._prefix[1])

        return table.replace('\0+',''). \
                     replace('\0-',''). \
                     replace('\0^',''). \
                     replace('\1',''). \
                     replace('\t',' ')

'        </tbody>        \n        <tbody>\n'


def _MakeParallelBenchmark(p, work_func, *args):
  """Create and return a benchmark that runs work_func p times in parallel."""
  def Benchmark(b):  # pylint: disable=missing-docstring
    e = threading.Event()
    def Target():
      e.wait()
      for _ in xrange(b.N / p):
        work_func(*args)
    threads = []
    for _ in xrange(p):
      t = threading.Thread(target=Target)
      t.start()
      threads.append(t)
    b.ResetTimer()
    e.set()
    for t in threads:
      t.join()
  return Benchmark

def
_MakeParallelBenchmark
(
p
,
work_func
,
*
args
)
:
def
Benchmark
(
b
)
:
# pylint: disable=missing-docstring
e
=
threading
.
Event
(
)
def
Target
(
)
:
e
.
wait
(
)
for
_
in
xrange
(
b
.
N
/
p
)
:
work_func
(
*
args
)
threads
=
[
]
for
_
in
xrange
(
p
)
:
t
=
threading
.
Thread
(
target
=
Target
)
t
.
start
(
)
threads
.
append
(
t
)
b
.
ResetTimer
(
)
e
.
set
(
)
for
t
in
threads
:
t
.
join
(
)
return
Benchmark

Create and return a benchmark that runs work_func p times in parallel .


def listdir(path):
    """List directory contents, using cache."""
    try:
        cached_mtime, list = cache[path]
        del cache[path]
    except KeyError:
        cached_mtime, list = -1, []
    mtime = os.stat(path).st_mtime
    if mtime != cached_mtime:
        list = os.listdir(path)
        list.sort()
    cache[path] = mtime, list
    return list

def listdir ( path ) : try : cached_mtime , list = cache [ path ] del cache [ path ] except KeyError : cached_mtime , list = - 1 , [ ] mtime = os . stat ( path ) . st_mtime if mtime != cached_mtime : list = os . listdir ( path ) list . sort ( ) cache [ path ] = mtime , list return list


def pformat(o, indent=1, width=80, depth=None):
    """Format a Python o into a pretty-printed representation."""
    return PrettyPrinter(indent=indent, width=width, depth=depth).pformat(o)

def pformat ( o , indent = 1 , width = 80 , depth = None ) : return PrettyPrinter ( indent = indent , width = width , depth = depth ) . pformat ( o )

Format a Python o into a pretty - printed representation .


def format(self, o, context, maxlevels, level):
        """Format o for a specific context, returning a string
        and flags indicating whether the representation is 'readable'
        and whether the o represents a recursive construct.
        """
        return _safe_repr(o, context, maxlevels, level)

def format ( self , o , context , maxlevels , level ) : return _safe_repr ( o , context , maxlevels , level )

Format o for a specific context returning a string and flags indicating whether the representation is readable and whether the o represents a recursive construct .


def action(inner_rule, loc=None):
    """
    A decorator returning a function that first runs ``inner_rule`` and then, if its
    return value is not None, maps that value using ``mapper``.

    If the value being mapped is a tuple, it is expanded into multiple arguments.

    Similar to attaching semantic actions to rules in traditional parser generators.
    """
    def decorator(mapper):
        @llrule(loc, inner_rule.expected)
        def outer_rule(parser):
            result = inner_rule(parser)
            if result is unmatched:
                return result
            if isinstance(result, tuple):
                return mapper(parser, *result)
            else:
                return mapper(parser, result)
        return outer_rule
    return decorator

def action ( inner_rule , loc = None ) : def decorator ( mapper ) : @ llrule ( loc , inner_rule . expected ) def outer_rule ( parser ) : result = inner_rule ( parser ) if result is unmatched : return result if isinstance ( result , tuple ) : return mapper ( parser , * result ) else : return mapper ( parser , result ) return outer_rule return decorator

A decorator returning a function that first runs inner_rule and then if its return value is not None maps that value using mapper .


def Tok(kind, loc=None):
    """A rule that accepts a token of kind ``kind`` and returns it, or returns None."""
    @llrule(loc, lambda parser: [kind])
    def rule(parser):
        return parser._accept(kind)
    return rule

def Tok ( kind , loc = None ) : @ llrule ( loc , lambda parser : [ kind ] ) def rule ( parser ) : return parser . _accept ( kind ) return rule

A rule that accepts a token of kind kind and returns it or returns None .


def Loc(kind, loc=None):
    """A rule that accepts a token of kind ``kind`` and returns its location, or returns None."""
    @llrule(loc, lambda parser: [kind])
    def rule(parser):
        result = parser._accept(kind)
        if result is unmatched:
            return result
        return result.loc
    return rule

def Loc ( kind , loc = None ) : @ llrule ( loc , lambda parser : [ kind ] ) def rule ( parser ) : result = parser . _accept ( kind ) if result is unmatched : return result return result . loc return rule

A rule that accepts a token of kind kind and returns its location or returns None .