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
readheaders
(
self
)
:
self
.
dict
=
{
}
self
.
unixfrom
=
''
self
.
headers
=
lst
=
[
]
self
.
status
=
''
headerseen
=
""
firstline
=
1
startofline
=
unread
=
tell
=
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
=
self
.
seekable
=
0
line
=
self
.
fp
.
readline
(
)
if
not
line
:
self
.
status
=
'EOF in headers'
break
if
firstline
and
line
.
startswith
(
'From '
)
:
self
.
unixfrom
=
self
.
unixfrom
+
line
continue
firstline
=
0
if
headerseen
and
line
[
0
]
in
' \t'
:
lst
.
append
(
line
)
x
=
(
self
.
dict
[
headerseen
]
+
"\n "
+
line
.
strip
(
)
)
self
.
dict
[
headerseen
]
=
x
.
strip
(
)
continue
elif
self
.
iscomment
(
line
)
:
continue
elif
self
.
islast
(
line
)
:
break
headerseen
=
self
.
isheader
(
line
)
if
headerseen
:
lst
.
append
(
line
)
self
.
dict
[
headerseen
]
=
line
[
len
(
headerseen
)
+
1
:
]
.
strip
(
)
continue
elif
headerseen
is
not
:
continue
else
:
if
not
self
.
dict
:
self
.
status
=
'No headers'
else
:
self
.
status
=
'Non-header line where header expected'
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)

def getdelimited ( self , beginchar , endchars , allowcomments = 1 ) : 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 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]

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)

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))

def isoformat ( self ) : 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

def isocalendar ( self ) : year = self . _year week1monday = _isoweek1monday ( year ) today = _ymd2ord ( self . _year , self . _month , self . _day ) 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)

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 timetz(self):
        "Return the time part, with same tzinfo."
        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
)
:
"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 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

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
)
:
"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 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 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)

def findall ( pattern , string , flags = 0 ) : return _compile ( pattern , flags ) . findall ( string ) def finditer ( pattern , string , flags = 0 ) : 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)

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
)
)
result
=
heapq
.
nlargest
(
n
,
result
)
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

def
unified_diff
(
a
,
b
,
fromfile
=
''
,
tofile
=
''
,
fromfiledate
=
''
,
tofiledate
=
''
,
n
=
3
,
lineterm
=
'\n'
)
:
r
started
=
False
for
group
in
SequenceMatcher
(
,
a
,
b
)
.
get_grouped_opcodes
(
n
)
:
if
not
started
:
started
=
True
fromdate
=
'\t%s'
%
(
fromfiledate
)
if
fromfiledate
else
''
todate
=
'\t%s'
%
(
tofiledate
)
if
tofiledate
else
''
yield
'--- %s%s%s'
%
(
fromfile
,
fromdate
,
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
'@@ -%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

def
context_diff
(
a
,
b
,
fromfile
=
''
,
tofile
=
''
,
fromfiledate
=
''
,
tofiledate
=
''
,
n
=
3
,
lineterm
=
'\n'
)
:
r
prefix
=
dict
(
insert
=
'+ '
,
delete
=
'- '
,
replace
=
'! '
,
equal
=
'  '
)
started
=
False
for
group
in
SequenceMatcher
(
,
a
,
b
)
.
get_grouped_opcodes
(
n
)
:
if
not
started
:
started
=
True
fromdate
=
'\t%s'
%
(
fromfiledate
)
if
fromfiledate
else
''
todate
=
'\t%s'
%
(
tofiledate
)
if
tofiledate
else
''
yield
'*** %s%s%s'
%
(
fromfile
,
fromdate
,
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
'*** %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
'--- %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 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

def get_matching_blocks ( self ) : if self . matching_blocks is not None : return self . matching_blocks la , lb = len ( self . a ) , len ( self . b ) 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 ) if k : 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 ( ) i1 = j1 = k1 = 0 non_adjacent = [ ] for i2 , j2 , k2 in matching_blocks : if i1 + k1 == i2 and j1 + k1 == j2 : k1 += k2 else : 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

def get_opcodes ( self ) : if self . opcodes is not None : return self . opcodes i = j = 0 self . opcodes = answer = [ ] for ai , bj , size in self . get_matching_blocks ( ) : 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 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

def get_grouped_opcodes ( self , n = 3 ) : codes = self . get_opcodes ( ) if not codes : codes = [ ( "equal" , 0 , 1 , 0 , 1 ) ] 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 : 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
)
:
r
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)

def
_qformat
(
self
,
aline
,
bline
,
atags
,
btags
)
:
r
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 _split_line ( self , data_list , line_num , text ) : if not line_num : data_list . append ( ( line_num , text ) ) return size = len ( text ) max = self . _wrapcolumn if ( size <= max ) or ( ( size - ( text . count ( '\0' ) * 3 ) ) <= max ) : data_list . append ( ( line_num , text ) ) return 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 line1 = text [ : i ] line2 = text [ i : ] if mark : line1 = line1 + '\1' line2 = '\0' + mark + line2 data_list . append ( ( line_num , line1 ) ) 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 _collect_lines ( self , diffs ) : fromlist , tolist , flaglist = [ ] , [ ] , [ ] for fromdata , todata , flag in diffs : try : fromlist . append ( self . _format_line ( 0 , flag , * fromdata ) ) tolist . append ( self . _format_line ( 1 , flag , * todata ) ) except TypeError : 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 _make_prefix ( self ) : fromprefix = "from%d_" % HtmlDiff . _default_prefix toprefix = "to%d_" % HtmlDiff . _default_prefix HtmlDiff . _default_prefix += 1 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 ) : 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 .


def Rule(name, loc=None):
    """A proxy for a rule called ``name`` which may not be yet defined."""
    @llrule(loc, lambda parser: getattr(parser, name).expected(parser))
    def rule(parser):
        return getattr(parser, name)()
    return rule

def Rule ( name , loc = None ) : @ llrule ( loc , lambda parser : getattr ( parser , name ) . expected ( parser ) ) def rule ( parser ) : return getattr ( parser , name ) ( ) return rule

A proxy for a rule called name which may not be yet defined .


def Expect(inner_rule, loc=None):
    """A rule that executes ``inner_rule`` and emits a diagnostic error if it returns None."""
    @llrule(loc, inner_rule.expected)
    def rule(parser):
        result = inner_rule(parser)
        if result is unmatched:
            expected = reduce(list.__add__, [rule.expected(parser) for rule in parser._errrules])
            expected = list(sorted(set(expected)))

            if len(expected) > 1:
                expected = " or ".join([", ".join(expected[0:-1]), expected[-1]])
            elif len(expected) == 1:
                expected = expected[0]
            else:
                expected = "(impossible)"

            error_tok = parser._tokens[parser._errindex]
            error = diagnostic.Diagnostic(
                "fatal", "unexpected {actual}: expected {expected}",
                {"actual": error_tok.kind, "expected": expected},
                error_tok.loc)
            parser.diagnostic_engine.process(error)
        return result
    return rule

A rule that executes inner_rule and emits a diagnostic error if it returns None .


def Seq(first_rule, *rest_of_rules, **kwargs):
    """
    A rule that accepts a sequence of tokens satisfying ``rules`` and returns a tuple
    containing their return values, or None if the first rule was not satisfied.
    """
    @llrule(kwargs.get("loc", None), first_rule.expected)
    def rule(parser):
        result = first_rule(parser)
        if result is unmatched:
            return result

        results = [result]
        for rule in rest_of_rules:
            result = rule(parser)
            if result is unmatched:
                return result
            results.append(result)
        return tuple(results)
    return rule

def Seq ( first_rule , * rest_of_rules , ** kwargs ) : @ llrule ( kwargs . get ( "loc" , None ) , first_rule . expected ) def rule ( parser ) : result = first_rule ( parser ) if result is unmatched : return result results = [ result ] for rule in rest_of_rules : result = rule ( parser ) if result is unmatched : return result results . append ( result ) return tuple ( results ) return rule

A rule that accepts a sequence of tokens satisfying rules and returns a tuple containing their return values or None if the first rule was not satisfied .


def SeqN(n, *inner_rules, **kwargs):
    """
    A rule that accepts a sequence of tokens satisfying ``rules`` and returns
    the value returned by rule number ``n``, or None if the first rule was not satisfied.
    """
    @action(Seq(*inner_rules), loc=kwargs.get("loc", None))
    def rule(parser, *values):
        return values[n]
    return rule

def SeqN ( n , * inner_rules , ** kwargs ) : @ action ( Seq ( * inner_rules ) , loc = kwargs . get ( "loc" , None ) ) def rule ( parser , * values ) : return values [ n ] return rule

A rule that accepts a sequence of tokens satisfying rules and returns the value returned by rule number n or None if the first rule was not satisfied .


def Newline(loc=None):
    """A rule that accepts token of kind ``newline`` and returns an empty list."""
    @llrule(loc, lambda parser: ["newline"])
    def rule(parser):
        result = parser._accept("newline")
        if result is unmatched:
            return result
        return []
    return rule

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

A rule that accepts token of kind newline and returns an empty list .


def urljoin(base, url, allow_fragments=True):
    """Join a base URL and a possibly relative URL to form an absolute
    interpretation of the latter."""
    if not base:
        return url
    if not url:
        return base
    bscheme, bnetloc, bpath, bparams, bquery, bfragment = \
            urlparse(base, '', allow_fragments)
    scheme, netloc, path, params, query, fragment = \
            urlparse(url, bscheme, allow_fragments)
    if scheme != bscheme or scheme not in uses_relative:
        return url
    if scheme in uses_netloc:
        if netloc:
            return urlunparse((scheme, netloc, path,
                               params, query, fragment))
        netloc = bnetloc
    if path[:1] == '/':
        return urlunparse((scheme, netloc, path,
                           params, query, fragment))
    if not path and not params:
        path = bpath
        params = bparams
        if not query:
            query = bquery
        return urlunparse((scheme, netloc, path,
                           params, query, fragment))
    segments = bpath.split('/')[:-1] + path.split('/')
    # XXX The stuff below is bogus in various ways...
    if segments[-1] == '.':
        segments[-1] = ''
    while '.' in segments:
        segments.remove('.')
    while 1:
        i = 1
        n = len(segments) - 1
        while i < n:
            if (segments[i] == '..'
                and segments[i-1] not in ('', '..')):
                del segments[i-1:i+1]
                break
            i = i+1
        else:
            break
    if segments == ['', '..']:
        segments[-1] = ''
    elif len(segments) >= 2 and segments[-1] == '..':
        segments[-2:] = ['']
    return urlunparse((scheme, netloc, '/'.join(segments),
                       params, query, fragment))

def urljoin ( base , url , allow_fragments = True ) : if not base : return url if not url : return base bscheme , bnetloc , bpath , bparams , bquery , bfragment = urlparse ( base , '' , allow_fragments ) scheme , netloc , path , params , query , fragment = urlparse ( url , bscheme , allow_fragments ) if scheme != bscheme or scheme not in uses_relative : return url if scheme in uses_netloc : if netloc : return urlunparse ( ( scheme , netloc , path , params , query , fragment ) ) netloc = bnetloc if path [ : 1 ] == '/' : return urlunparse ( ( scheme , netloc , path , params , query , fragment ) ) if not path and not params : path = bpath params = bparams if not query : query = bquery return urlunparse ( ( scheme , netloc , path , params , query , fragment ) ) segments = bpath . split ( '/' ) [ : - 1 ] + path . split ( '/' ) if segments [ - 1 ] == '.' : segments [ - 1 ] = '' while '.' in segments : segments . remove ( '.' ) while 1 : i = 1 n = len ( segments ) - 1 while i < n : if ( segments [ i ] == '..' and segments [ i - 1 ] not in ( '' , '..' ) ) : del segments [ i - 1 : i + 1 ] break i = i + 1 else : break if segments == [ '' , '..' ] : segments [ - 1 ] = '' elif len ( segments ) >= 2 and segments [ - 1 ] == '..' : segments [ - 2 : ] = [ '' ] return urlunparse ( ( scheme , netloc , '/' . join ( segments ) , params , query , fragment ) )

Join a base URL and a possibly relative URL to form an absolute interpretation of the latter .


def urldefrag(url):
    """Removes any existing fragment from URL.

    Returns a tuple of the defragmented URL and the fragment.  If
    the URL contained no fragments, the second element is the
    empty string.
    """
    if '#' in url:
        s, n, p, a, q, frag = urlparse(url)
        defrag = urlunparse((s, n, p, a, q, ''))
        return defrag, frag
    else:
        return url, ''

def urldefrag ( url ) : if '#' in url : s , n , p , a , q , frag = urlparse ( url ) defrag = urlunparse ( ( s , n , p , a , q , '' ) ) return defrag , frag else : return url , ''

Removes any existing fragment from URL .


def _replace(_self, **kwds):
        'Return a new SplitResult object replacing specified fields with new values'
        result = _self._make(map(kwds.pop, ('scheme', 'netloc', 'path', 'query', 'fragment'), _self))
        if kwds:
            raise ValueError('Got unexpected field names: %r' % kwds.keys())
        return result


def getlines(filename, module_globals=None):
    """Get the lines for a file from the cache.
    Update the cache if it doesn't contain an entry for this file already."""

    if filename in cache:
        return cache[filename][2]

    try:
        return updatecache(filename, module_globals)
    except MemoryError:
        clearcache()
        return []

def getlines ( filename , module_globals = None ) : if filename in cache : return cache [ filename ] [ 2 ] try : return updatecache ( filename , module_globals ) except MemoryError : clearcache ( ) return [ ]

Get the lines for a file from the cache . Update the cache if it doesn t contain an entry for this file already .


def updatecache(filename, module_globals=None):
    """Update a cache entry and return its list of lines.
    If something's wrong, print a message, discard the cache entry,
    and return an empty list."""

    if filename in cache:
        del cache[filename]
    if not filename or (filename.startswith('<') and filename.endswith('>')):
        return []

    fullname = filename
    try:
        stat = os.stat(fullname)
    except OSError:
        basename = filename

        # Try for a __loader__, if available
        if module_globals and '__loader__' in module_globals:
            name = module_globals.get('__name__')
            loader = module_globals['__loader__']
            get_source = getattr(loader, 'get_source', None)

            if name and get_source:
                try:
                    data = get_source(name)
                except (ImportError, IOError):
                    pass
                else:
                    if data is None:
                        # No luck, the PEP302 loader cannot find the source
                        # for this module.
                        return []
                    cache[filename] = (
                        len(data), None,
                        [line+'\n' for line in data.splitlines()], fullname
                    )
                    return cache[filename][2]

        # Try looking through the module search path, which is only useful
        # when handling a relative filename.
        if os.path.isabs(filename):
            return []

        for dirname in sys.path:
            # When using imputil, sys.path may contain things other than
            # strings; ignore them when it happens.
            try:
                fullname = os.path.join(dirname, basename)
            except (TypeError, AttributeError):
                # Not sufficiently string-like to do anything useful with.
                continue
            try:
                stat = os.stat(fullname)
                break
            except os.error:
                pass
        else:
            return []
    try:
        with open(fullname, 'rU') as fp:
            lines = fp.readlines()
    except IOError:
        return []
    if lines and not lines[-1].endswith('\n'):
        lines[-1] += '\n'
    size, mtime = stat.st_size, stat.st_mtime
    cache[filename] = size, mtime, lines, fullname
    return lines

def updatecache ( filename , module_globals = None ) : if filename in cache : del cache [ filename ] if not filename or ( filename . startswith ( '<' ) and filename . endswith ( '>' ) ) : return [ ] fullname = filename try : stat = os . stat ( fullname ) except OSError : basename = filename if module_globals and '__loader__' in module_globals : name = module_globals . get ( '__name__' ) loader = module_globals [ '__loader__' ] get_source = getattr ( loader , 'get_source' , None ) if name and get_source : try : data = get_source ( name ) except ( ImportError , IOError ) : pass else : if data is None : return [ ] cache [ filename ] = ( len ( data ) , None , [ line + '\n' for line in data . splitlines ( ) ] , fullname ) return cache [ filename ] [ 2 ] if os . path . isabs ( filename ) : return [ ] for dirname in sys . path : try : fullname = os . path . join ( dirname , basename ) except ( TypeError , AttributeError ) : continue try : stat = os . stat ( fullname ) break except os . error : pass else : return [ ] try : with open ( fullname , 'rU' ) as fp : lines = fp . readlines ( ) except IOError : return [ ] if lines and not lines [ - 1 ] . endswith ( '\n' ) : lines [ - 1 ] += '\n' size , mtime = stat . st_size , stat . st_mtime cache [ filename ] = size , mtime , lines , fullname return lines

Update a cache entry and return its list of lines . If something s wrong print a message discard the cache entry and return an empty list .


def isfile(path):
    """Test whether a path is a regular file"""
    try:
        st = os.stat(path)
    except os.error:
        return False
    return stat.S_ISREG(st.st_mode)

def isfile ( path ) : try : st = os . stat ( path ) except os . error : return False return stat . S_ISREG ( st . st_mode )


def isdir(s):
    """Return true if the pathname refers to an existing directory."""
    try:
        st = os.stat(s)
    except os.error:
        return False
    return stat.S_ISDIR(st.st_mode)

def isdir ( s ) : try : st = os . stat ( s ) except os . error : return False return stat . S_ISDIR ( st . st_mode )

Return true if the pathname refers to an existing directory .


def commonprefix(m):
    "Given a list of pathnames, returns the longest common leading component"
    if not m: return ''
    s1 = min(m)
    s2 = max(m)
    for i, c in enumerate(s1):
        if c != s2[i]:
            return s1[:i]
    return s1

Given a list of pathnames returns the longest common leading component


def _splitext(p, sep, altsep, extsep):
    """Split the extension from a pathname.

    Extension is everything from the last dot to the end, ignoring
    leading dots.  Returns "(root, ext)"; ext may be empty."""

    sepIndex = p.rfind(sep)
    if altsep:
        altsepIndex = p.rfind(altsep)
        sepIndex = max(sepIndex, altsepIndex)

    dotIndex = p.rfind(extsep)
    if dotIndex > sepIndex:
        # skip all leading dots
        filenameIndex = sepIndex + 1
        while filenameIndex < dotIndex:
            if p[filenameIndex] != extsep:
                return p[:dotIndex], p[dotIndex:]
            filenameIndex += 1

    return p, ''

def _splitext ( p , sep , altsep , extsep ) : sepIndex = p . rfind ( sep ) if altsep : altsepIndex = p . rfind ( altsep ) sepIndex = max ( sepIndex , altsepIndex ) dotIndex = p . rfind ( extsep ) if dotIndex > sepIndex : filenameIndex = sepIndex + 1 while filenameIndex < dotIndex : if p [ filenameIndex ] != extsep : return p [ : dotIndex ] , p [ dotIndex : ] filenameIndex += 1 return p , ''


def wrap(text, width=70, **kwargs):
    """Wrap a single paragraph of text, returning a list of wrapped lines.

    Reformat the single paragraph in 'text' so it fits in lines of no
    more than 'width' columns, and return a list of wrapped lines.  By
    default, tabs in 'text' are expanded with string.expandtabs(), and
    all other whitespace characters (including newline) are converted to
    space.  See TextWrapper class for available keyword args to customize
    wrapping behaviour.
    """
    w = TextWrapper(width=width, **kwargs)
    return w.wrap(text)

def wrap ( text , width = 70 , ** kwargs ) : w = TextWrapper ( width = width , ** kwargs ) return w . wrap ( text )

Wrap a single paragraph of text returning a list of wrapped lines .


def fill(text, width=70, **kwargs):
    """Fill a single paragraph of text, returning a new string.

    Reformat the single paragraph in 'text' to fit in lines of no more
    than 'width' columns, and return a new string containing the entire
    wrapped paragraph.  As with wrap(), tabs are expanded and other
    whitespace characters converted to space.  See TextWrapper class for
    available keyword args to customize wrapping behaviour.
    """
    w = TextWrapper(width=width, **kwargs)
    return w.fill(text)

def fill ( text , width = 70 , ** kwargs ) : w = TextWrapper ( width = width , ** kwargs ) return w . fill ( text )

Fill a single paragraph of text returning a new string .


def dedent(text):
    """Remove any common leading whitespace from every line in `text`.

    This can be used to make triple-quoted strings line up with the left
    edge of the display, while still presenting them in the source code
    in indented form.

    Note that tabs and spaces are both treated as whitespace, but they
    are not equal: the lines "  hello" and "\\thello" are
    considered to have no common leading whitespace.  (This behaviour is
    new in Python 2.5; older versions of this module incorrectly
    expanded tabs before searching for common leading whitespace.)
    """
    # Look for the longest leading string of spaces and tabs common to
    # all lines.
    margin = None
    text = _whitespace_only_re.sub('', text)
    indents = _leading_whitespace_re.findall(text)
    for indent in indents:
        if margin is None:
            margin = indent

        # Current line more deeply indented than previous winner:
        # no change (previous winner is still on top).
        elif indent.startswith(margin):
            pass

        # Current line consistent with and no deeper than previous winner:
        # it's the new winner.
        elif margin.startswith(indent):
            margin = indent

        # Find the largest common whitespace between current line and previous
        # winner.
        else:
            for i, (x, y) in enumerate(zip(margin, indent)):
                if x != y:
                    margin = margin[:i]
                    break
            else:
                margin = margin[:len(indent)]

    # sanity check (testing/debugging only)
    if 0 and margin:
        for line in text.split("\n"):
            assert not line or line.startswith(margin), \
                   "line = %r, margin = %r" % (line, margin)

    if margin:
        text = re.sub(r'(?m)^' + margin, '', text)
    return text

def
dedent
(
text
)
:
margin
=
text
=
_whitespace_only_re
.
sub
(
''
,
text
)
indents
=
_leading_whitespace_re
.
findall
(
text
)
for
indent
in
indents
:
if
margin
is
:
margin
=
indent
elif
indent
.
startswith
(
margin
)
:
pass
elif
margin
.
startswith
(
indent
)
:
margin
=
indent
else
:
for
i
,
(
x
,
y
)
in
enumerate
(
zip
(
margin
,
indent
)
)
:
if
x
!=
y
:
margin
=
margin
[
:
i
]
break
else
:
margin
=
margin
[
:
len
(
indent
)
]
if
0
and
margin
:
for
line
in
text
.
split
(
"\n"
)
:
assert
not
line
or
line
.
startswith
(
margin
)
,
"line = %r, margin = %r"
%
(
line
,
margin
)
if
margin
:
text
=
re
.
sub
(
r'(?m)^'
+
margin
,
''
,
text
)
return
text

Remove any common leading whitespace from every line in text .


def _long2bytesBigEndian(n, blocksize=0):
    """Convert a long integer to a byte string.

    If optional blocksize is given and greater than zero, pad the front
    of the byte string with binary zeros so that the length is a multiple
    of blocksize.
    """

    # After much testing, this algorithm was deemed to be the fastest.
    s = b''
    pack = struct.pack
    while n > 0:
        s = pack('>I', n & 0xffffffff) + s
        n = n >> 32

    # Strip off leading zeros.
    for i in range(len(s)):
        if s[i] != '\000':
            break
    else:
        # Only happens when n == 0.
        s = '\000'
        i = 0

    s = s[i:]

    # Add back some pad bytes. This could be done more efficiently
    # w.r.t. the de-padding being done above, but sigh...
    if blocksize > 0 and len(s) % blocksize:
        s = (blocksize - len(s) % blocksize) * '\000' + s

    return s

def _long2bytesBigEndian ( n , blocksize = 0 ) : s = b'' pack = struct . pack while n > 0 : s = pack ( '>I' , n & 0xffffffff ) + s n = n >> 32 for i in range ( len ( s ) ) : if s [ i ] != '\000' : break else : s = '\000' i = 0 s = s [ i : ] if blocksize > 0 and len ( s ) % blocksize : s = ( blocksize - len ( s ) % blocksize ) * '\000' + s return s

Convert a long integer to a byte string .


def _bytelist2longBigEndian(list):
    "Transform a list of characters into a list of longs."

    imax = len(list) // 4
    hl = [0] * imax

    j = 0
    i = 0
    while i < imax:
        b0 = ord(list[j]) << 24
        b1 = ord(list[j+1]) << 16
        b2 = ord(list[j+2]) << 8
        b3 = ord(list[j+3])
        hl[i] = b0 | b1 | b2 | b3
        i = i+1
        j = j+4

    return hl

Transform a list of characters into a list of longs .


def init(self):
        "Initialize the message-digest and set all fields to zero."

        self.length = 0
        self.input = []

        # Initial 160 bit message digest (5 times 32 bit).
        self.H0 = 0x67452301
        self.H1 = 0xEFCDAB89
        self.H2 = 0x98BADCFE
        self.H3 = 0x10325476
        self.H4 = 0xC3D2E1F0

Initialize the message - digest and set all fields to zero .


def enterabs(self, time, priority, action, argument):
        """Enter a new event in the queue at an absolute time.
        Returns an ID for the event which can be used to remove it,
        if necessary.
        """
        event = Event(time, priority, action, argument)
        heapq.heappush(self._queue, event)
        return event

def enterabs ( self , time , priority , action , argument ) : event = Event ( time , priority , action , argument ) heapq . heappush ( self . _queue , event ) return event

Enter a new event in the queue at an absolute time . Returns an ID for the event which can be used to remove it if necessary .


def copy(x):
    """Shallow copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    cls = type(x)

    copier = _copy_dispatch.get(cls)
    if copier:
        return copier(x)

    copier = getattr(cls, "__copy__", None)
    if copier:
        return copier(x)

    reductor = dispatch_table.get(cls)
    if reductor:
        rv = reductor(x)
    else:
        reductor = getattr(x, "__reduce_ex__", None)
        if reductor:
            rv = reductor(2)
        else:
            reductor = getattr(x, "__reduce__", None)
            if reductor:
                rv = reductor()
            else:
                raise Error("un(shallow)copyable object of type %s" % cls)

    return _reconstruct(x, rv, 0)

def
copy
(
x
)
:
cls
=
type
(
x
)
copier
=
_copy_dispatch
.
get
(
cls
)
if
copier
:
return
copier
(
x
)
copier
=
getattr
(
cls
,
"__copy__"
,
)
if
copier
:
return
copier
(
x
)
reductor
=
dispatch_table
.
get
(
cls
)
if
reductor
:
rv
=
reductor
(
x
)
else
:
reductor
=
getattr
(
x
,
"__reduce_ex__"
,
)
if
reductor
:
rv
=
reductor
(
2
)
else
:
reductor
=
getattr
(
x
,
"__reduce__"
,
)
if
reductor
:
rv
=
reductor
(
)
else
:
raise
Error
(
"un(shallow)copyable object of type %s"
%
cls
)
return
_reconstruct
(
x
,
rv
,
0
)

Shallow copy operation on arbitrary Python objects .


def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier:
        y = copier(x, memo)
    else:
        try:
            issc = issubclass(cls, type)
        except TypeError: # cls is not a class (old Boost; see SF #502085)
            issc = 0
        if issc:
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier:
                y = copier(memo)
            else:
                reductor = dispatch_table.get(cls)
                if reductor:
                    rv = reductor(x)
                else:
                    reductor = getattr(x, "__reduce_ex__", None)
                    if reductor:
                        rv = reductor(2)
                    else:
                        reductor = getattr(x, "__reduce__", None)
                        if reductor:
                            rv = reductor()
                        else:
                            raise Error(
                                "un(deep)copyable object of type %s" % cls)
                y = _reconstruct(x, rv, 1, memo)

    memo[d] = y
    _keep_alive(x, memo) # Make sure x lives at least as long as d
    return y

def
deepcopy
(
x
,
memo
=
,
_nil
=
[
]
)
:
if
memo
is
:
memo
=
{
}
d
=
id
(
x
)
y
=
memo
.
get
(
d
,
_nil
)
if
y
is
not
_nil
:
return
y
cls
=
type
(
x
)
copier
=
_deepcopy_dispatch
.
get
(
cls
)
if
copier
:
y
=
copier
(
x
,
memo
)
else
:
try
:
issc
=
issubclass
(
cls
,
type
)
except
TypeError
:
issc
=
0
if
issc
:
y
=
_deepcopy_atomic
(
x
,
memo
)
else
:
copier
=
getattr
(
x
,
"__deepcopy__"
,
)
if
copier
:
y
=
copier
(
memo
)
else
:
reductor
=
dispatch_table
.
get
(
cls
)
if
reductor
:
rv
=
reductor
(
x
)
else
:
reductor
=
getattr
(
x
,
"__reduce_ex__"
,
)
if
reductor
:
rv
=
reductor
(
2
)
else
:
reductor
=
getattr
(
x
,
"__reduce__"
,
)
if
reductor
:
rv
=
reductor
(
)
else
:
raise
Error
(
"un(deep)copyable object of type %s"
%
cls
)
y
=
_reconstruct
(
x
,
rv
,
1
,
memo
)
memo
[
d
]
=
y
_keep_alive
(
x
,
memo
)
return
y

Deep copy operation on arbitrary Python objects .