diff --git a/libs/dateutil/__init__.py b/libs/dateutil/__init__.py index 290814c..0f91a31 100644 --- a/libs/dateutil/__init__.py +++ b/libs/dateutil/__init__.py @@ -1,9 +1,10 @@ +# -*- coding: utf-8 -*- """ Copyright (c) 2003-2010 Gustavo Niemeyer -This module offers extensions to the standard python 2.3+ +This module offers extensions to the standard Python datetime module. """ -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" -__version__ = "1.5" +__author__ = "Tomi Pieviläinen " +__license__ = "Simplified BSD" +__version__ = "2.1" diff --git a/libs/dateutil/easter.py b/libs/dateutil/easter.py index d794410..d8a3884 100644 --- a/libs/dateutil/easter.py +++ b/libs/dateutil/easter.py @@ -1,11 +1,10 @@ """ Copyright (c) 2003-2007 Gustavo Niemeyer -This module offers extensions to the standard python 2.3+ +This module offers extensions to the standard Python datetime module. """ -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" +__license__ = "Simplified BSD" import datetime @@ -52,7 +51,7 @@ def easter(year, method=EASTER_WESTERN): """ if not (1 <= method <= 3): - raise ValueError, "invalid method" + raise ValueError("invalid method") # g - Golden year - 1 # c - Century @@ -88,5 +87,5 @@ def easter(year, method=EASTER_WESTERN): p = i-j+e d = 1+(p+27+(p+6)//40)%31 m = 3+(p+26)//30 - return datetime.date(int(y),int(m),int(d)) + return datetime.date(int(y), int(m), int(d)) diff --git a/libs/dateutil/parser.py b/libs/dateutil/parser.py index 5d824e4..2f41cf7 100644 --- a/libs/dateutil/parser.py +++ b/libs/dateutil/parser.py @@ -2,25 +2,27 @@ """ Copyright (c) 2003-2007 Gustavo Niemeyer -This module offers extensions to the standard python 2.3+ +This module offers extensions to the standard Python datetime module. """ -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" +from __future__ import unicode_literals +__license__ = "Simplified BSD" + import datetime import string import time -import sys -import os +import collections try: - from cStringIO import StringIO + from io import StringIO except ImportError: - from StringIO import StringIO + from io import StringIO + +from six import text_type, binary_type, integer_types -import relativedelta -import tz +from . import relativedelta +from . import tz __all__ = ["parse", "parserinfo"] @@ -39,7 +41,7 @@ __all__ = ["parse", "parserinfo"] class _timelex(object): def __init__(self, instream): - if isinstance(instream, basestring): + if isinstance(instream, text_type): instream = StringIO(instream) self.instream = instream self.wordchars = ('abcdfeghijklmnopqrstuvwxyz' @@ -133,12 +135,15 @@ class _timelex(object): def __iter__(self): return self - def next(self): + def __next__(self): token = self.get_token() if token is None: raise StopIteration return token + def next(self): + return self.__next__() # Python 2.x support + def split(cls, s): return list(cls(s)) split = classmethod(split) @@ -155,7 +160,7 @@ class _resultbase(object): for attr in self.__slots__: value = getattr(self, attr) if value is not None: - l.append("%s=%s" % (attr, `value`)) + l.append("%s=%s" % (attr, repr(value))) return "%s(%s)" % (classname, ", ".join(l)) def __repr__(self): @@ -167,7 +172,7 @@ class parserinfo(object): # m from a.m/p.m, t from ISO T separator JUMP = [" ", ".", ",", ";", "-", "/", "'", "at", "on", "and", "ad", "m", "t", "of", - "st", "nd", "rd", "th"] + "st", "nd", "rd", "th"] WEEKDAYS = [("Mon", "Monday"), ("Tue", "Tuesday"), @@ -176,7 +181,7 @@ class parserinfo(object): ("Fri", "Friday"), ("Sat", "Saturday"), ("Sun", "Sunday")] - MONTHS = [("Jan", "January"), + MONTHS = [("Jan", "January"), ("Feb", "February"), ("Mar", "March"), ("Apr", "April"), @@ -184,7 +189,7 @@ class parserinfo(object): ("Jun", "June"), ("Jul", "July"), ("Aug", "August"), - ("Sep", "September"), + ("Sep", "Sept", "September"), ("Oct", "October"), ("Nov", "November"), ("Dec", "December")] @@ -197,7 +202,7 @@ class parserinfo(object): PERTAIN = ["of"] TZOFFSET = {} - def __init__(self, dayfirst=False, yearfirst=False): + def __init__(self, dayfirst = False, yearfirst = False): self._jump = self._convert(self.JUMP) self._weekdays = self._convert(self.WEEKDAYS) self._months = self._convert(self.MONTHS) @@ -210,7 +215,7 @@ class parserinfo(object): self.yearfirst = yearfirst self._year = time.localtime().tm_year - self._century = self._year//100*100 + self._century = self._year // 100 * 100 def _convert(self, lst): dct = {} @@ -237,7 +242,7 @@ class parserinfo(object): def month(self, name): if len(name) >= 3: try: - return self._months[name.lower()]+1 + return self._months[name.lower()] + 1 except KeyError: pass return None @@ -268,7 +273,7 @@ class parserinfo(object): def convertyear(self, year): if year < 100: year += self._century - if abs(year-self._year) >= 50: + if abs(year - self._year) >= 50: if year < self._year: year += 100 else: @@ -289,18 +294,18 @@ class parserinfo(object): class parser(object): - def __init__(self, info=None): + def __init__(self, info = None): self.info = info or parserinfo() - def parse(self, timestr, default=None, - ignoretz=False, tzinfos=None, + def parse(self, timestr, default = None, + ignoretz = False, tzinfos = None, **kwargs): if not default: - default = datetime.datetime.now().replace(hour=0, minute=0, - second=0, microsecond=0) + default = datetime.datetime.now().replace(hour = 0, minute = 0, + second = 0, microsecond = 0) res = self._parse(timestr, **kwargs) if res is None: - raise ValueError, "unknown string format" + raise ValueError("unknown string format") repl = {} for attr in ["year", "month", "day", "hour", "minute", "second", "microsecond"]: @@ -309,29 +314,29 @@ class parser(object): repl[attr] = value ret = default.replace(**repl) if res.weekday is not None and not res.day: - ret = ret+relativedelta.relativedelta(weekday=res.weekday) + ret = ret + relativedelta.relativedelta(weekday = res.weekday) if not ignoretz: - if callable(tzinfos) or tzinfos and res.tzname in tzinfos: - if callable(tzinfos): + if isinstance(tzinfos, collections.Callable) or tzinfos and res.tzname in tzinfos: + if isinstance(tzinfos, collections.Callable): tzdata = tzinfos(res.tzname, res.tzoffset) else: tzdata = tzinfos.get(res.tzname) if isinstance(tzdata, datetime.tzinfo): tzinfo = tzdata - elif isinstance(tzdata, basestring): + elif isinstance(tzdata, text_type): tzinfo = tz.tzstr(tzdata) - elif isinstance(tzdata, int): + elif isinstance(tzdata, integer_types): tzinfo = tz.tzoffset(res.tzname, tzdata) else: - raise ValueError, "offset must be tzinfo subclass, " \ - "tz string, or int offset" - ret = ret.replace(tzinfo=tzinfo) + raise ValueError("offset must be tzinfo subclass, " \ + "tz string, or int offset") + ret = ret.replace(tzinfo = tzinfo) elif res.tzname and res.tzname in time.tzname: - ret = ret.replace(tzinfo=tz.tzlocal()) + ret = ret.replace(tzinfo = tz.tzlocal()) elif res.tzoffset == 0: - ret = ret.replace(tzinfo=tz.tzutc()) + ret = ret.replace(tzinfo = tz.tzutc()) elif res.tzoffset: - ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) + ret = ret.replace(tzinfo = tz.tzoffset(res.tzname, res.tzoffset)) return ret class _result(_resultbase): @@ -339,7 +344,7 @@ class parser(object): "hour", "minute", "second", "microsecond", "tzname", "tzoffset"] - def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False): + def _parse(self, timestr, dayfirst = None, yearfirst = None, fuzzy = False): info = self.info if dayfirst is None: dayfirst = info.dayfirst @@ -374,14 +379,14 @@ class parser(object): and (i >= len_l or (l[i] != ':' and info.hms(l[i]) is None))): # 19990101T23[59] - s = l[i-1] + s = l[i - 1] res.hour = int(s[:2]) if len_li == 4: res.minute = int(s[2:]) - elif len_li == 6 or (len_li > 6 and l[i-1].find('.') == 6): + elif len_li == 6 or (len_li > 6 and l[i - 1].find('.') == 6): # YYMMDD or HHMMSS[.ss] - s = l[i-1] - if not ymd and l[i-1].find('.') == -1: + s = l[i - 1] + if not ymd and l[i - 1].find('.') == -1: ymd.append(info.convertyear(int(s[:2]))) ymd.append(int(s[2:4])) ymd.append(int(s[4:])) @@ -392,13 +397,13 @@ class parser(object): res.second, res.microsecond = _parsems(s[4:]) elif len_li == 8: # YYYYMMDD - s = l[i-1] + s = l[i - 1] ymd.append(int(s[:4])) ymd.append(int(s[4:6])) ymd.append(int(s[6:])) elif len_li in (12, 14): # YYYYMMDDhhmm[ss] - s = l[i-1] + s = l[i - 1] ymd.append(int(s[:4])) ymd.append(int(s[4:6])) ymd.append(int(s[6:8])) @@ -407,8 +412,8 @@ class parser(object): if len_li == 14: res.second = int(s[12:]) elif ((i < len_l and info.hms(l[i]) is not None) or - (i+1 < len_l and l[i] == ' ' and - info.hms(l[i+1]) is not None)): + (i + 1 < len_l and l[i] == ' ' and + info.hms(l[i + 1]) is not None)): # HH[ ]h or MM[ ]m or SS[.ss][ ]s if l[i] == ' ': i += 1 @@ -416,12 +421,12 @@ class parser(object): while True: if idx == 0: res.hour = int(value) - if value%1: - res.minute = int(60*(value%1)) + if value % 1: + res.minute = int(60 * (value % 1)) elif idx == 1: res.minute = int(value) - if value%1: - res.second = int(60*(value%1)) + if value % 1: + res.second = int(60 * (value % 1)) elif idx == 2: res.second, res.microsecond = \ _parsems(value_repr) @@ -441,17 +446,28 @@ class parser(object): newidx = info.hms(l[i]) if newidx is not None: idx = newidx - elif i+1 < len_l and l[i] == ':': + elif i == len_l and l[i - 2] == ' ' and info.hms(l[i - 3]) is not None: + # X h MM or X m SS + idx = info.hms(l[i - 3]) + 1 + if idx == 1: + res.minute = int(value) + if value % 1: + res.second = int(60 * (value % 1)) + elif idx == 2: + res.second, res.microsecond = \ + _parsems(value_repr) + i += 1 + elif i + 1 < len_l and l[i] == ':': # HH:MM[:SS[.ss]] res.hour = int(value) i += 1 value = float(l[i]) res.minute = int(value) - if value%1: - res.second = int(60*(value%1)) + if value % 1: + res.second = int(60 * (value % 1)) i += 1 if i < len_l and l[i] == ':': - res.second, res.microsecond = _parsems(l[i+1]) + res.second, res.microsecond = _parsems(l[i + 1]) i += 2 elif i < len_l and l[i] in ('-', '/', '.'): sep = l[i] @@ -467,7 +483,7 @@ class parser(object): if value is not None: ymd.append(value) assert mstridx == -1 - mstridx = len(ymd)-1 + mstridx = len(ymd) - 1 else: return None i += 1 @@ -477,18 +493,18 @@ class parser(object): value = info.month(l[i]) if value is not None: ymd.append(value) - mstridx = len(ymd)-1 + mstridx = len(ymd) - 1 assert mstridx == -1 else: ymd.append(int(l[i])) i += 1 elif i >= len_l or info.jump(l[i]): - if i+1 < len_l and info.ampm(l[i+1]) is not None: + if i + 1 < len_l and info.ampm(l[i + 1]) is not None: # 12 am res.hour = int(value) - if res.hour < 12 and info.ampm(l[i+1]) == 1: + if res.hour < 12 and info.ampm(l[i + 1]) == 1: res.hour += 12 - elif res.hour == 12 and info.ampm(l[i+1]) == 0: + elif res.hour == 12 and info.ampm(l[i + 1]) == 0: res.hour = 0 i += 1 else: @@ -521,7 +537,7 @@ class parser(object): if value is not None: ymd.append(value) assert mstridx == -1 - mstridx = len(ymd)-1 + mstridx = len(ymd) - 1 i += 1 if i < len_l: if l[i] in ('-', '/'): @@ -535,12 +551,12 @@ class parser(object): i += 1 ymd.append(int(l[i])) i += 1 - elif (i+3 < len_l and l[i] == l[i+2] == ' ' - and info.pertain(l[i+1])): + elif (i + 3 < len_l and l[i] == l[i + 2] == ' ' + and info.pertain(l[i + 1])): # Jan of 01 # In this case, 01 is clearly year try: - value = int(l[i+3]) + value = int(l[i + 3]) except ValueError: # Wrong guess pass @@ -585,32 +601,32 @@ class parser(object): # Check for a numbered timezone if res.hour is not None and l[i] in ('+', '-'): - signal = (-1,1)[l[i] == '+'] + signal = (-1, 1)[l[i] == '+'] i += 1 len_li = len(l[i]) if len_li == 4: # -0300 - res.tzoffset = int(l[i][:2])*3600+int(l[i][2:])*60 - elif i+1 < len_l and l[i+1] == ':': + res.tzoffset = int(l[i][:2]) * 3600 + int(l[i][2:]) * 60 + elif i + 1 < len_l and l[i + 1] == ':': # -03:00 - res.tzoffset = int(l[i])*3600+int(l[i+2])*60 + res.tzoffset = int(l[i]) * 3600 + int(l[i + 2]) * 60 i += 2 elif len_li <= 2: # -[0]3 - res.tzoffset = int(l[i][:2])*3600 + res.tzoffset = int(l[i][:2]) * 3600 else: return None i += 1 res.tzoffset *= signal # Look for a timezone name between parenthesis - if (i+3 < len_l and - info.jump(l[i]) and l[i+1] == '(' and l[i+3] == ')' and - 3 <= len(l[i+2]) <= 5 and - not [x for x in l[i+2] + if (i + 3 < len_l and + info.jump(l[i]) and l[i + 1] == '(' and l[i + 3] == ')' and + 3 <= len(l[i + 2]) <= 5 and + not [x for x in l[i + 2] if x not in string.ascii_uppercase]): # -0300 (BRST) - res.tzname = l[i+2] + res.tzname = l[i + 2] i += 4 continue @@ -690,7 +706,12 @@ class parser(object): return res DEFAULTPARSER = parser() -def parse(timestr, parserinfo=None, **kwargs): +def parse(timestr, parserinfo = None, **kwargs): + # Python 2.x support: datetimes return their string presentation as + # bytes in 2.x and unicode in 3.x, so it's reasonable to expect that + # the parser will get both kinds. Internally we use unicode only. + if isinstance(timestr, binary_type): + timestr = timestr.decode() if parserinfo: return parser(parserinfo).parse(timestr, **kwargs) else: @@ -743,7 +764,7 @@ class _tzparser(object): if l[i] in ('+', '-'): # Yes, that's right. See the TZ variable # documentation. - signal = (1,-1)[l[i] == '+'] + signal = (1, -1)[l[i] == '+'] i += 1 else: signal = -1 @@ -751,16 +772,16 @@ class _tzparser(object): if len_li == 4: # -0300 setattr(res, offattr, - (int(l[i][:2])*3600+int(l[i][2:])*60)*signal) - elif i+1 < len_l and l[i+1] == ':': + (int(l[i][:2]) * 3600 + int(l[i][2:]) * 60) * signal) + elif i + 1 < len_l and l[i + 1] == ':': # -03:00 setattr(res, offattr, - (int(l[i])*3600+int(l[i+2])*60)*signal) + (int(l[i]) * 3600 + int(l[i + 2]) * 60) * signal) i += 2 elif len_li <= 2: # -[0]3 setattr(res, offattr, - int(l[i][:2])*3600*signal) + int(l[i][:2]) * 3600 * signal) else: return None i += 1 @@ -787,29 +808,29 @@ class _tzparser(object): x.month = int(l[i]) i += 2 if l[i] == '-': - value = int(l[i+1])*-1 + value = int(l[i + 1]) * -1 i += 1 else: value = int(l[i]) i += 2 if value: x.week = value - x.weekday = (int(l[i])-1)%7 + x.weekday = (int(l[i]) - 1) % 7 else: x.day = int(l[i]) i += 2 x.time = int(l[i]) i += 2 if i < len_l: - if l[i] in ('-','+'): - signal = (-1,1)[l[i] == "+"] + if l[i] in ('-', '+'): + signal = (-1, 1)[l[i] == "+"] i += 1 else: signal = 1 - res.dstoffset = (res.stdoffset+int(l[i]))*signal + res.dstoffset = (res.stdoffset + int(l[i])) * signal elif (l.count(',') == 2 and l[i:].count('/') <= 2 and - not [y for x in l[i:] if x not in (',','/','J','M', - '.','-',':') + not [y for x in l[i:] if x not in (',', '/', 'J', 'M', + '.', '-', ':') for y in x if y not in "0123456789"]): for x in (res.start, res.end): if l[i] == 'J': @@ -829,10 +850,10 @@ class _tzparser(object): i += 1 assert l[i] in ('-', '.') i += 1 - x.weekday = (int(l[i])-1)%7 + x.weekday = (int(l[i]) - 1) % 7 else: # year day (zero based) - x.yday = int(l[i])+1 + x.yday = int(l[i]) + 1 i += 1 @@ -842,17 +863,17 @@ class _tzparser(object): len_li = len(l[i]) if len_li == 4: # -0300 - x.time = (int(l[i][:2])*3600+int(l[i][2:])*60) - elif i+1 < len_l and l[i+1] == ':': + x.time = (int(l[i][:2]) * 3600 + int(l[i][2:]) * 60) + elif i + 1 < len_l and l[i + 1] == ':': # -03:00 - x.time = int(l[i])*3600+int(l[i+2])*60 + x.time = int(l[i]) * 3600 + int(l[i + 2]) * 60 i += 2 - if i+1 < len_l and l[i+1] == ':': + if i + 1 < len_l and l[i + 1] == ':': i += 2 x.time += int(l[i]) elif len_li <= 2: # -[0]3 - x.time = (int(l[i][:2])*3600) + x.time = (int(l[i][:2]) * 3600) else: return None i += 1 @@ -865,7 +886,7 @@ class _tzparser(object): except (IndexError, ValueError, AssertionError): return None - + return res diff --git a/libs/dateutil/relativedelta.py b/libs/dateutil/relativedelta.py index 0c72a81..4393bcb 100644 --- a/libs/dateutil/relativedelta.py +++ b/libs/dateutil/relativedelta.py @@ -1,15 +1,16 @@ """ Copyright (c) 2003-2010 Gustavo Niemeyer -This module offers extensions to the standard python 2.3+ +This module offers extensions to the standard Python datetime module. """ -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" +__license__ = "Simplified BSD" import datetime import calendar +from six import integer_types + __all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"] class weekday(object): @@ -42,7 +43,7 @@ class weekday(object): MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) -class relativedelta: +class relativedelta(object): """ The relativedelta type is based on the specification of the excelent work done by M.-A. Lemburg in his mx.DateTime extension. However, @@ -113,10 +114,9 @@ Here is the behavior of operations with relativedelta: yearday=None, nlyearday=None, hour=None, minute=None, second=None, microsecond=None): if dt1 and dt2: - if not isinstance(dt1, datetime.date) or \ - not isinstance(dt2, datetime.date): - raise TypeError, "relativedelta only diffs datetime/date" - if type(dt1) is not type(dt2): + if (not isinstance(dt1, datetime.date)) or (not isinstance(dt2, datetime.date)): + raise TypeError("relativedelta only diffs datetime/date") + if not type(dt1) == type(dt2): #isinstance(dt1, type(dt2)): if not isinstance(dt1, datetime.datetime): dt1 = datetime.datetime.fromordinal(dt1.toordinal()) elif not isinstance(dt2, datetime.datetime): @@ -172,7 +172,7 @@ Here is the behavior of operations with relativedelta: self.second = second self.microsecond = microsecond - if type(weekday) is int: + if isinstance(weekday, integer_types): self.weekday = weekdays[weekday] else: self.weekday = weekday @@ -185,7 +185,7 @@ Here is the behavior of operations with relativedelta: if yearday > 59: self.leapdays = -1 if yday: - ydayidx = [31,59,90,120,151,181,212,243,273,304,334,366] + ydayidx = [31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 366] for idx, ydays in enumerate(ydayidx): if yday <= ydays: self.month = idx+1 @@ -195,7 +195,7 @@ Here is the behavior of operations with relativedelta: self.day = yday-ydayidx[idx-1] break else: - raise ValueError, "invalid year day (%d)" % yday + raise ValueError("invalid year day (%d)" % yday) self._fix() @@ -242,9 +242,26 @@ Here is the behavior of operations with relativedelta: else: self.years = 0 - def __radd__(self, other): + def __add__(self, other): + if isinstance(other, relativedelta): + return relativedelta(years=other.years+self.years, + months=other.months+self.months, + days=other.days+self.days, + hours=other.hours+self.hours, + minutes=other.minutes+self.minutes, + seconds=other.seconds+self.seconds, + microseconds=other.microseconds+self.microseconds, + leapdays=other.leapdays or self.leapdays, + year=other.year or self.year, + month=other.month or self.month, + day=other.day or self.day, + weekday=other.weekday or self.weekday, + hour=other.hour or self.hour, + minute=other.minute or self.minute, + second=other.second or self.second, + microsecond=other.microsecond or self.microsecond) if not isinstance(other, datetime.date): - raise TypeError, "unsupported type for add operation" + raise TypeError("unsupported type for add operation") elif self._has_time and not isinstance(other, datetime.datetime): other = datetime.datetime.fromordinal(other.toordinal()) year = (self.year or other.year)+self.years @@ -285,48 +302,31 @@ Here is the behavior of operations with relativedelta: ret += datetime.timedelta(days=jumpdays) return ret + def __radd__(self, other): + return self.__add__(other) + def __rsub__(self, other): return self.__neg__().__radd__(other) - def __add__(self, other): - if not isinstance(other, relativedelta): - raise TypeError, "unsupported type for add operation" - return relativedelta(years=other.years+self.years, - months=other.months+self.months, - days=other.days+self.days, - hours=other.hours+self.hours, - minutes=other.minutes+self.minutes, - seconds=other.seconds+self.seconds, - microseconds=other.microseconds+self.microseconds, - leapdays=other.leapdays or self.leapdays, - year=other.year or self.year, - month=other.month or self.month, - day=other.day or self.day, - weekday=other.weekday or self.weekday, - hour=other.hour or self.hour, - minute=other.minute or self.minute, - second=other.second or self.second, - microsecond=other.second or self.microsecond) - def __sub__(self, other): if not isinstance(other, relativedelta): - raise TypeError, "unsupported type for sub operation" - return relativedelta(years=other.years-self.years, - months=other.months-self.months, - days=other.days-self.days, - hours=other.hours-self.hours, - minutes=other.minutes-self.minutes, - seconds=other.seconds-self.seconds, - microseconds=other.microseconds-self.microseconds, - leapdays=other.leapdays or self.leapdays, - year=other.year or self.year, - month=other.month or self.month, - day=other.day or self.day, - weekday=other.weekday or self.weekday, - hour=other.hour or self.hour, - minute=other.minute or self.minute, - second=other.second or self.second, - microsecond=other.second or self.microsecond) + raise TypeError("unsupported type for sub operation") + return relativedelta(years=self.years-other.years, + months=self.months-other.months, + days=self.days-other.days, + hours=self.hours-other.hours, + minutes=self.minutes-other.minutes, + seconds=self.seconds-other.seconds, + microseconds=self.microseconds-other.microseconds, + leapdays=self.leapdays or other.leapdays, + year=self.year or other.year, + month=self.month or other.month, + day=self.day or other.day, + weekday=self.weekday or other.weekday, + hour=self.hour or other.hour, + minute=self.minute or other.minute, + second=self.second or other.second, + microsecond=self.microsecond or other.microsecond) def __neg__(self): return relativedelta(years=-self.years, @@ -346,7 +346,7 @@ Here is the behavior of operations with relativedelta: second=self.second, microsecond=self.microsecond) - def __nonzero__(self): + def __bool__(self): return not (not self.years and not self.months and not self.days and @@ -366,13 +366,13 @@ Here is the behavior of operations with relativedelta: def __mul__(self, other): f = float(other) - return relativedelta(years=self.years*f, - months=self.months*f, - days=self.days*f, - hours=self.hours*f, - minutes=self.minutes*f, - seconds=self.seconds*f, - microseconds=self.microseconds*f, + return relativedelta(years=int(self.years*f), + months=int(self.months*f), + days=int(self.days*f), + hours=int(self.hours*f), + minutes=int(self.minutes*f), + seconds=int(self.seconds*f), + microseconds=int(self.microseconds*f), leapdays=self.leapdays, year=self.year, month=self.month, @@ -383,6 +383,8 @@ Here is the behavior of operations with relativedelta: second=self.second, microsecond=self.microsecond) + __rmul__ = __mul__ + def __eq__(self, other): if not isinstance(other, relativedelta): return False @@ -415,6 +417,8 @@ Here is the behavior of operations with relativedelta: def __div__(self, other): return self.__mul__(1/float(other)) + __truediv__ = __div__ + def __repr__(self): l = [] for attr in ["years", "months", "days", "leapdays", @@ -426,7 +430,7 @@ Here is the behavior of operations with relativedelta: "hour", "minute", "second", "microsecond"]: value = getattr(self, attr) if value is not None: - l.append("%s=%s" % (attr, `value`)) + l.append("%s=%s" % (attr, repr(value))) return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) # vim:ts=4:sw=4:et diff --git a/libs/dateutil/rrule.py b/libs/dateutil/rrule.py index 6bd83ca..ad4d3ba 100644 --- a/libs/dateutil/rrule.py +++ b/libs/dateutil/rrule.py @@ -1,18 +1,22 @@ """ Copyright (c) 2003-2010 Gustavo Niemeyer -This module offers extensions to the standard python 2.3+ +This module offers extensions to the standard Python datetime module. """ -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" +__license__ = "Simplified BSD" import itertools import datetime import calendar -import thread +try: + import _thread +except ImportError: + import thread as _thread import sys +from six import advance_iterator, integer_types + __all__ = ["rrule", "rruleset", "rrulestr", "YEARLY", "MONTHLY", "WEEKLY", "DAILY", "HOURLY", "MINUTELY", "SECONDLY", @@ -22,15 +26,15 @@ __all__ = ["rrule", "rruleset", "rrulestr", M366MASK = tuple([1]*31+[2]*29+[3]*31+[4]*30+[5]*31+[6]*30+ [7]*31+[8]*31+[9]*30+[10]*31+[11]*30+[12]*31+[1]*7) M365MASK = list(M366MASK) -M29, M30, M31 = range(1,30), range(1,31), range(1,32) +M29, M30, M31 = list(range(1, 30)), list(range(1, 31)), list(range(1, 32)) MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) MDAY365MASK = list(MDAY366MASK) -M29, M30, M31 = range(-29,0), range(-30,0), range(-31,0) +M29, M30, M31 = list(range(-29, 0)), list(range(-30, 0)), list(range(-31, 0)) NMDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) NMDAY365MASK = list(NMDAY366MASK) -M366RANGE = (0,31,60,91,121,152,182,213,244,274,305,335,366) -M365RANGE = (0,31,59,90,120,151,181,212,243,273,304,334,365) -WDAYMASK = [0,1,2,3,4,5,6]*55 +M366RANGE = (0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366) +M365RANGE = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365) +WDAYMASK = [0, 1, 2, 3, 4, 5, 6]*55 del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31] MDAY365MASK = tuple(MDAY365MASK) M365MASK = tuple(M365MASK) @@ -41,7 +45,7 @@ M365MASK = tuple(M365MASK) DAILY, HOURLY, MINUTELY, - SECONDLY) = range(7) + SECONDLY) = list(range(7)) # Imported on demand. easter = None @@ -52,7 +56,7 @@ class weekday(object): def __init__(self, weekday, n=None): if n == 0: - raise ValueError, "Can't create weekday with n == 0" + raise ValueError("Can't create weekday with n == 0") self.weekday = weekday self.n = n @@ -79,11 +83,11 @@ class weekday(object): MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) -class rrulebase: +class rrulebase(object): def __init__(self, cache=False): if cache: self._cache = [] - self._cache_lock = thread.allocate_lock() + self._cache_lock = _thread.allocate_lock() self._cache_gen = self._iter() self._cache_complete = False else: @@ -112,7 +116,7 @@ class rrulebase: break try: for j in range(10): - cache.append(gen.next()) + cache.append(advance_iterator(gen)) except StopIteration: self._cache_gen = gen = None self._cache_complete = True @@ -133,13 +137,13 @@ class rrulebase: else: return list(itertools.islice(self, item.start or 0, - item.stop or sys.maxint, + item.stop or sys.maxsize, item.step or 1)) elif item >= 0: gen = iter(self) try: for i in range(item+1): - res = gen.next() + res = advance_iterator(gen) except StopIteration: raise IndexError return res @@ -232,7 +236,7 @@ class rrule(rrulebase): byweekno=None, byweekday=None, byhour=None, byminute=None, bysecond=None, cache=False): - rrulebase.__init__(self, cache) + super(rrule, self).__init__(cache) global easter if not dtstart: dtstart = datetime.datetime.now().replace(microsecond=0) @@ -250,13 +254,13 @@ class rrule(rrulebase): self._until = until if wkst is None: self._wkst = calendar.firstweekday() - elif type(wkst) is int: + elif isinstance(wkst, integer_types): self._wkst = wkst else: self._wkst = wkst.weekday if bysetpos is None: self._bysetpos = None - elif type(bysetpos) is int: + elif isinstance(bysetpos, integer_types): if bysetpos == 0 or not (-366 <= bysetpos <= 366): raise ValueError("bysetpos must be between 1 and 366, " "or between -366 and -1") @@ -280,14 +284,14 @@ class rrule(rrulebase): # bymonth if not bymonth: self._bymonth = None - elif type(bymonth) is int: + elif isinstance(bymonth, integer_types): self._bymonth = (bymonth,) else: self._bymonth = tuple(bymonth) # byyearday if not byyearday: self._byyearday = None - elif type(byyearday) is int: + elif isinstance(byyearday, integer_types): self._byyearday = (byyearday,) else: self._byyearday = tuple(byyearday) @@ -295,7 +299,7 @@ class rrule(rrulebase): if byeaster is not None: if not easter: from dateutil import easter - if type(byeaster) is int: + if isinstance(byeaster, integer_types): self._byeaster = (byeaster,) else: self._byeaster = tuple(byeaster) @@ -305,7 +309,7 @@ class rrule(rrulebase): if not bymonthday: self._bymonthday = () self._bynmonthday = () - elif type(bymonthday) is int: + elif isinstance(bymonthday, integer_types): if bymonthday < 0: self._bynmonthday = (bymonthday,) self._bymonthday = () @@ -318,7 +322,7 @@ class rrule(rrulebase): # byweekno if byweekno is None: self._byweekno = None - elif type(byweekno) is int: + elif isinstance(byweekno, integer_types): self._byweekno = (byweekno,) else: self._byweekno = tuple(byweekno) @@ -326,7 +330,7 @@ class rrule(rrulebase): if byweekday is None: self._byweekday = None self._bynweekday = None - elif type(byweekday) is int: + elif isinstance(byweekday, integer_types): self._byweekday = (byweekday,) self._bynweekday = None elif hasattr(byweekday, "n"): @@ -340,7 +344,7 @@ class rrule(rrulebase): self._byweekday = [] self._bynweekday = [] for wday in byweekday: - if type(wday) is int: + if isinstance(wday, integer_types): self._byweekday.append(wday) elif not wday.n or freq > MONTHLY: self._byweekday.append(wday.weekday) @@ -358,7 +362,7 @@ class rrule(rrulebase): self._byhour = (dtstart.hour,) else: self._byhour = None - elif type(byhour) is int: + elif isinstance(byhour, integer_types): self._byhour = (byhour,) else: self._byhour = tuple(byhour) @@ -368,7 +372,7 @@ class rrule(rrulebase): self._byminute = (dtstart.minute,) else: self._byminute = None - elif type(byminute) is int: + elif isinstance(byminute, integer_types): self._byminute = (byminute,) else: self._byminute = tuple(byminute) @@ -378,7 +382,7 @@ class rrule(rrulebase): self._bysecond = (dtstart.second,) else: self._bysecond = None - elif type(bysecond) is int: + elif isinstance(bysecond, integer_types): self._bysecond = (bysecond,) else: self._bysecond = tuple(bysecond) @@ -716,7 +720,7 @@ class _iterinfo(object): # days from last year's last week number in # this year. if -1 not in rr._byweekno: - lyearweekday = datetime.date(year-1,1,1).weekday() + lyearweekday = datetime.date(year-1, 1, 1).weekday() lno1wkst = (7-lyearweekday+rr._wkst)%7 lyearlen = 365+calendar.isleap(year-1) if lno1wkst >= 4: @@ -768,7 +772,7 @@ class _iterinfo(object): self.lastmonth = month def ydayset(self, year, month, day): - return range(self.yearlen), 0, self.yearlen + return list(range(self.yearlen)), 0, self.yearlen def mdayset(self, year, month, day): set = [None]*self.yearlen @@ -823,27 +827,38 @@ class _iterinfo(object): class rruleset(rrulebase): - class _genitem: + class _genitem(object): def __init__(self, genlist, gen): try: - self.dt = gen() + self.dt = advance_iterator(gen) genlist.append(self) except StopIteration: pass self.genlist = genlist self.gen = gen - def next(self): + def __next__(self): try: - self.dt = self.gen() + self.dt = advance_iterator(self.gen) except StopIteration: self.genlist.remove(self) - def __cmp__(self, other): - return cmp(self.dt, other.dt) + next = __next__ + + def __lt__(self, other): + return self.dt < other.dt + + def __gt__(self, other): + return self.dt > other.dt + + def __eq__(self, other): + return self.dt == other.dt + + def __ne__(self, other): + return self.dt != other.dt def __init__(self, cache=False): - rrulebase.__init__(self, cache) + super(rruleset, self).__init__(cache) self._rrule = [] self._rdate = [] self._exrule = [] @@ -851,7 +866,7 @@ class rruleset(rrulebase): def rrule(self, rrule): self._rrule.append(rrule) - + def rdate(self, rdate): self._rdate.append(rdate) @@ -864,14 +879,14 @@ class rruleset(rrulebase): def _iter(self): rlist = [] self._rdate.sort() - self._genitem(rlist, iter(self._rdate).next) - for gen in [iter(x).next for x in self._rrule]: + self._genitem(rlist, iter(self._rdate)) + for gen in [iter(x) for x in self._rrule]: self._genitem(rlist, gen) rlist.sort() exlist = [] self._exdate.sort() - self._genitem(exlist, iter(self._exdate).next) - for gen in [iter(x).next for x in self._exrule]: + self._genitem(exlist, iter(self._exdate)) + for gen in [iter(x) for x in self._exrule]: self._genitem(exlist, gen) exlist.sort() lastdt = None @@ -880,17 +895,17 @@ class rruleset(rrulebase): ritem = rlist[0] if not lastdt or lastdt != ritem.dt: while exlist and exlist[0] < ritem: - exlist[0].next() + advance_iterator(exlist[0]) exlist.sort() if not exlist or ritem != exlist[0]: total += 1 yield ritem.dt lastdt = ritem.dt - ritem.next() + advance_iterator(ritem) rlist.sort() self._len = total -class _rrulestr: +class _rrulestr(object): _freq_map = {"YEARLY": YEARLY, "MONTHLY": MONTHLY, @@ -932,7 +947,7 @@ class _rrulestr: ignoretz=kwargs.get("ignoretz"), tzinfos=kwargs.get("tzinfos")) except ValueError: - raise ValueError, "invalid until date" + raise ValueError("invalid until date") def _handle_WKST(self, rrkwargs, name, value, **kwargs): rrkwargs["wkst"] = self._weekday_map[value] @@ -959,7 +974,7 @@ class _rrulestr: if line.find(':') != -1: name, value = line.split(':') if name != "RRULE": - raise ValueError, "unknown parameter name" + raise ValueError("unknown parameter name") else: value = line rrkwargs = {} @@ -972,9 +987,9 @@ class _rrulestr: ignoretz=ignoretz, tzinfos=tzinfos) except AttributeError: - raise ValueError, "unknown parameter '%s'" % name + raise ValueError("unknown parameter '%s'" % name) except (KeyError, ValueError): - raise ValueError, "invalid '%s': %s" % (name, value) + raise ValueError("invalid '%s': %s" % (name, value)) return rrule(dtstart=dtstart, cache=cache, **rrkwargs) def _parse_rfc(self, s, @@ -991,7 +1006,7 @@ class _rrulestr: unfold = True s = s.upper() if not s.strip(): - raise ValueError, "empty string" + raise ValueError("empty string") if unfold: lines = s.splitlines() i = 0 @@ -1026,36 +1041,36 @@ class _rrulestr: name, value = line.split(':', 1) parms = name.split(';') if not parms: - raise ValueError, "empty property name" + raise ValueError("empty property name") name = parms[0] parms = parms[1:] if name == "RRULE": for parm in parms: - raise ValueError, "unsupported RRULE parm: "+parm + raise ValueError("unsupported RRULE parm: "+parm) rrulevals.append(value) elif name == "RDATE": for parm in parms: if parm != "VALUE=DATE-TIME": - raise ValueError, "unsupported RDATE parm: "+parm + raise ValueError("unsupported RDATE parm: "+parm) rdatevals.append(value) elif name == "EXRULE": for parm in parms: - raise ValueError, "unsupported EXRULE parm: "+parm + raise ValueError("unsupported EXRULE parm: "+parm) exrulevals.append(value) elif name == "EXDATE": for parm in parms: if parm != "VALUE=DATE-TIME": - raise ValueError, "unsupported RDATE parm: "+parm + raise ValueError("unsupported RDATE parm: "+parm) exdatevals.append(value) elif name == "DTSTART": for parm in parms: - raise ValueError, "unsupported DTSTART parm: "+parm + raise ValueError("unsupported DTSTART parm: "+parm) if not parser: from dateutil import parser dtstart = parser.parse(value, ignoretz=ignoretz, tzinfos=tzinfos) else: - raise ValueError, "unsupported property: "+name + raise ValueError("unsupported property: "+name) if (forceset or len(rrulevals) > 1 or rdatevals or exrulevals or exdatevals): if not parser and (rdatevals or exdatevals): diff --git a/libs/dateutil/tz.py b/libs/dateutil/tz.py index 0e28d6b..e849fc2 100644 --- a/libs/dateutil/tz.py +++ b/libs/dateutil/tz.py @@ -1,11 +1,12 @@ """ Copyright (c) 2003-2007 Gustavo Niemeyer -This module offers extensions to the standard python 2.3+ +This module offers extensions to the standard Python datetime module. """ -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" +__license__ = "Simplified BSD" + +from six import string_types, PY3 import datetime import struct @@ -25,6 +26,19 @@ try: except (ImportError, OSError): tzwin, tzwinlocal = None, None +def tzname_in_python2(myfunc): + """Change unicode output into bytestrings in Python 2 + + tzname() API changed in Python 3. It used to return bytes, but was changed + to unicode strings + """ + def inner_func(*args, **kwargs): + if PY3: + return myfunc(*args, **kwargs) + else: + return myfunc(*args, **kwargs).encode() + return inner_func + ZERO = datetime.timedelta(0) EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal() @@ -36,6 +50,7 @@ class tzutc(datetime.tzinfo): def dst(self, dt): return ZERO + @tzname_in_python2 def tzname(self, dt): return "UTC" @@ -63,6 +78,7 @@ class tzoffset(datetime.tzinfo): def dst(self, dt): return ZERO + @tzname_in_python2 def tzname(self, dt): return self._name @@ -75,7 +91,7 @@ class tzoffset(datetime.tzinfo): def __repr__(self): return "%s(%s, %s)" % (self.__class__.__name__, - `self._name`, + repr(self._name), self._offset.days*86400+self._offset.seconds) __reduce__ = object.__reduce__ @@ -100,6 +116,7 @@ class tzlocal(datetime.tzinfo): else: return ZERO + @tzname_in_python2 def tzname(self, dt): return time.tzname[self._isdst(dt)] @@ -161,7 +178,7 @@ class _ttinfo(object): for attr in self.__slots__: value = getattr(self, attr) if value is not None: - l.append("%s=%s" % (attr, `value`)) + l.append("%s=%s" % (attr, repr(value))) return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) def __eq__(self, other): @@ -191,16 +208,16 @@ class _ttinfo(object): class tzfile(datetime.tzinfo): # http://www.twinsun.com/tz/tz-link.htm - # ftp://elsie.nci.nih.gov/pub/tz*.tar.gz + # ftp://ftp.iana.org/tz/tz*.tar.gz def __init__(self, fileobj): - if isinstance(fileobj, basestring): + if isinstance(fileobj, string_types): self._filename = fileobj - fileobj = open(fileobj) + fileobj = open(fileobj, 'rb') elif hasattr(fileobj, "name"): self._filename = fileobj.name else: - self._filename = `fileobj` + self._filename = repr(fileobj) # From tzfile(5): # @@ -212,8 +229,8 @@ class tzfile(datetime.tzinfo): # ``standard'' byte order (the high-order byte # of the value is written first). - if fileobj.read(4) != "TZif": - raise ValueError, "magic not found" + if fileobj.read(4).decode() != "TZif": + raise ValueError("magic not found") fileobj.read(16) @@ -284,7 +301,7 @@ class tzfile(datetime.tzinfo): for i in range(typecnt): ttinfo.append(struct.unpack(">lbb", fileobj.read(6))) - abbr = fileobj.read(charcnt) + abbr = fileobj.read(charcnt).decode() # Then there are tzh_leapcnt pairs of four-byte # values, written in standard byte order; the @@ -360,7 +377,7 @@ class tzfile(datetime.tzinfo): if not self._trans_list: self._ttinfo_std = self._ttinfo_first = self._ttinfo_list[0] else: - for i in range(timecnt-1,-1,-1): + for i in range(timecnt-1, -1, -1): tti = self._trans_idx[i] if not self._ttinfo_std and not tti.isdst: self._ttinfo_std = tti @@ -448,6 +465,7 @@ class tzfile(datetime.tzinfo): # dst offset, so I belive that this wouldn't be the right # way to implement this. + @tzname_in_python2 def tzname(self, dt): if not self._ttinfo_std: return None @@ -465,11 +483,11 @@ class tzfile(datetime.tzinfo): def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, `self._filename`) + return "%s(%s)" % (self.__class__.__name__, repr(self._filename)) def __reduce__(self): if not os.path.isfile(self._filename): - raise ValueError, "Unpickable %s class" % self.__class__.__name__ + raise ValueError("Unpickable %s class" % self.__class__.__name__) return (self.__class__, (self._filename,)) class tzrange(datetime.tzinfo): @@ -515,6 +533,7 @@ class tzrange(datetime.tzinfo): else: return ZERO + @tzname_in_python2 def tzname(self, dt): if self._isdst(dt): return self._dst_abbr @@ -524,7 +543,7 @@ class tzrange(datetime.tzinfo): def _isdst(self, dt): if not self._start_delta: return False - year = datetime.datetime(dt.year,1,1) + year = datetime.datetime(dt.year, 1, 1) start = year+self._start_delta end = year+self._end_delta dt = dt.replace(tzinfo=None) @@ -561,7 +580,7 @@ class tzstr(tzrange): res = parser._parsetz(s) if res is None: - raise ValueError, "unknown string format" + raise ValueError("unknown string format") # Here we break the compatibility with the TZ variable handling. # GMT-3 actually *means* the timezone -3. @@ -624,9 +643,9 @@ class tzstr(tzrange): return relativedelta.relativedelta(**kwargs) def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, `self._s`) + return "%s(%s)" % (self.__class__.__name__, repr(self._s)) -class _tzicalvtzcomp: +class _tzicalvtzcomp(object): def __init__(self, tzoffsetfrom, tzoffsetto, isdst, tzname=None, rrule=None): self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom) @@ -690,51 +709,52 @@ class _tzicalvtz(datetime.tzinfo): else: return ZERO + @tzname_in_python2 def tzname(self, dt): return self._find_comp(dt).tzname def __repr__(self): - return "" % `self._tzid` + return "" % repr(self._tzid) __reduce__ = object.__reduce__ -class tzical: +class tzical(object): def __init__(self, fileobj): global rrule if not rrule: from dateutil import rrule - if isinstance(fileobj, basestring): + if isinstance(fileobj, string_types): self._s = fileobj - fileobj = open(fileobj) + fileobj = open(fileobj, 'r') # ical should be encoded in UTF-8 with CRLF elif hasattr(fileobj, "name"): self._s = fileobj.name else: - self._s = `fileobj` + self._s = repr(fileobj) self._vtz = {} self._parse_rfc(fileobj.read()) def keys(self): - return self._vtz.keys() + return list(self._vtz.keys()) def get(self, tzid=None): if tzid is None: - keys = self._vtz.keys() + keys = list(self._vtz.keys()) if len(keys) == 0: - raise ValueError, "no timezones defined" + raise ValueError("no timezones defined") elif len(keys) > 1: - raise ValueError, "more than one timezone available" + raise ValueError("more than one timezone available") tzid = keys[0] return self._vtz.get(tzid) def _parse_offset(self, s): s = s.strip() if not s: - raise ValueError, "empty offset" + raise ValueError("empty offset") if s[0] in ('+', '-'): - signal = (-1,+1)[s[0]=='+'] + signal = (-1, +1)[s[0]=='+'] s = s[1:] else: signal = +1 @@ -743,12 +763,12 @@ class tzical: elif len(s) == 6: return (int(s[:2])*3600+int(s[2:4])*60+int(s[4:]))*signal else: - raise ValueError, "invalid offset: "+s + raise ValueError("invalid offset: "+s) def _parse_rfc(self, s): lines = s.splitlines() if not lines: - raise ValueError, "empty string" + raise ValueError("empty string") # Unfold i = 0 @@ -772,7 +792,7 @@ class tzical: name, value = line.split(':', 1) parms = name.split(';') if not parms: - raise ValueError, "empty property name" + raise ValueError("empty property name") name = parms[0].upper() parms = parms[1:] if invtz: @@ -781,7 +801,7 @@ class tzical: # Process component pass else: - raise ValueError, "unknown component: "+value + raise ValueError("unknown component: "+value) comptype = value founddtstart = False tzoffsetfrom = None @@ -791,27 +811,21 @@ class tzical: elif name == "END": if value == "VTIMEZONE": if comptype: - raise ValueError, \ - "component not closed: "+comptype + raise ValueError("component not closed: "+comptype) if not tzid: - raise ValueError, \ - "mandatory TZID not found" + raise ValueError("mandatory TZID not found") if not comps: - raise ValueError, \ - "at least one component is needed" + raise ValueError("at least one component is needed") # Process vtimezone self._vtz[tzid] = _tzicalvtz(tzid, comps) invtz = False elif value == comptype: if not founddtstart: - raise ValueError, \ - "mandatory DTSTART not found" + raise ValueError("mandatory DTSTART not found") if tzoffsetfrom is None: - raise ValueError, \ - "mandatory TZOFFSETFROM not found" + raise ValueError("mandatory TZOFFSETFROM not found") if tzoffsetto is None: - raise ValueError, \ - "mandatory TZOFFSETFROM not found" + raise ValueError("mandatory TZOFFSETFROM not found") # Process component rr = None if rrulelines: @@ -825,8 +839,7 @@ class tzical: comps.append(comp) comptype = None else: - raise ValueError, \ - "invalid component end: "+value + raise ValueError("invalid component end: "+value) elif comptype: if name == "DTSTART": rrulelines.append(line) @@ -835,40 +848,36 @@ class tzical: rrulelines.append(line) elif name == "TZOFFSETFROM": if parms: - raise ValueError, \ - "unsupported %s parm: %s "%(name, parms[0]) + raise ValueError("unsupported %s parm: %s "%(name, parms[0])) tzoffsetfrom = self._parse_offset(value) elif name == "TZOFFSETTO": if parms: - raise ValueError, \ - "unsupported TZOFFSETTO parm: "+parms[0] + raise ValueError("unsupported TZOFFSETTO parm: "+parms[0]) tzoffsetto = self._parse_offset(value) elif name == "TZNAME": if parms: - raise ValueError, \ - "unsupported TZNAME parm: "+parms[0] + raise ValueError("unsupported TZNAME parm: "+parms[0]) tzname = value elif name == "COMMENT": pass else: - raise ValueError, "unsupported property: "+name + raise ValueError("unsupported property: "+name) else: if name == "TZID": if parms: - raise ValueError, \ - "unsupported TZID parm: "+parms[0] + raise ValueError("unsupported TZID parm: "+parms[0]) tzid = value elif name in ("TZURL", "LAST-MODIFIED", "COMMENT"): pass else: - raise ValueError, "unsupported property: "+name + raise ValueError("unsupported property: "+name) elif name == "BEGIN" and value == "VTIMEZONE": tzid = None comps = [] invtz = True def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, `self._s`) + return "%s(%s)" % (self.__class__.__name__, repr(self._s)) if sys.platform != "win32": TZFILES = ["/etc/localtime", "localtime"] @@ -914,7 +923,7 @@ def gettz(name=None): for path in TZPATHS: filepath = os.path.join(path, name) if not os.path.isfile(filepath): - filepath = filepath.replace(' ','_') + filepath = filepath.replace(' ', '_') if not os.path.isfile(filepath): continue try: diff --git a/libs/dateutil/tzwin.py b/libs/dateutil/tzwin.py index 073e0ff..041c6cc 100644 --- a/libs/dateutil/tzwin.py +++ b/libs/dateutil/tzwin.py @@ -1,9 +1,8 @@ # This code was originally contributed by Jeffrey Harris. import datetime import struct -import _winreg +import winreg -__author__ = "Jeffrey Harris & Gustavo Niemeyer " __all__ = ["tzwin", "tzwinlocal"] @@ -15,9 +14,9 @@ TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation" def _settzkeyname(): global TZKEYNAME - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) try: - _winreg.OpenKey(handle, TZKEYNAMENT).Close() + winreg.OpenKey(handle, TZKEYNAMENT).Close() TZKEYNAME = TZKEYNAMENT except WindowsError: TZKEYNAME = TZKEYNAME9X @@ -49,10 +48,10 @@ class tzwinbase(datetime.tzinfo): def list(): """Return a list of all time zones known to the system.""" - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - tzkey = _winreg.OpenKey(handle, TZKEYNAME) - result = [_winreg.EnumKey(tzkey, i) - for i in range(_winreg.QueryInfoKey(tzkey)[0])] + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) + tzkey = winreg.OpenKey(handle, TZKEYNAME) + result = [winreg.EnumKey(tzkey, i) + for i in range(winreg.QueryInfoKey(tzkey)[0])] tzkey.Close() handle.Close() return result @@ -79,8 +78,8 @@ class tzwin(tzwinbase): def __init__(self, name): self._name = name - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - tzkey = _winreg.OpenKey(handle, "%s\%s" % (TZKEYNAME, name)) + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) + tzkey = winreg.OpenKey(handle, "%s\%s" % (TZKEYNAME, name)) keydict = valuestodict(tzkey) tzkey.Close() handle.Close() @@ -118,9 +117,9 @@ class tzwinlocal(tzwinbase): def __init__(self): - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) - tzlocalkey = _winreg.OpenKey(handle, TZLOCALKEYNAME) + tzlocalkey = winreg.OpenKey(handle, TZLOCALKEYNAME) keydict = valuestodict(tzlocalkey) tzlocalkey.Close() @@ -128,7 +127,7 @@ class tzwinlocal(tzwinbase): self._dstname = keydict["DaylightName"].encode("iso-8859-1") try: - tzkey = _winreg.OpenKey(handle, "%s\%s"%(TZKEYNAME, self._stdname)) + tzkey = winreg.OpenKey(handle, "%s\%s"%(TZKEYNAME, self._stdname)) _keydict = valuestodict(tzkey) self._display = _keydict["Display"] tzkey.Close() @@ -165,7 +164,7 @@ def picknthweekday(year, month, dayofweek, hour, minute, whichweek): """dayofweek == 0 means Sunday, whichweek 5 means last instance""" first = datetime.datetime(year, month, 1, hour, minute) weekdayone = first.replace(day=((dayofweek-first.isoweekday())%7+1)) - for n in xrange(whichweek): + for n in range(whichweek): dt = weekdayone+(whichweek-n)*ONEWEEK if dt.month == month: return dt @@ -173,8 +172,8 @@ def picknthweekday(year, month, dayofweek, hour, minute, whichweek): def valuestodict(key): """Convert a registry key's values to a dictionary.""" dict = {} - size = _winreg.QueryInfoKey(key)[1] + size = winreg.QueryInfoKey(key)[1] for i in range(size): - data = _winreg.EnumValue(key, i) + data = winreg.EnumValue(key, i) dict[data[0]] = data[1] return dict diff --git a/libs/dateutil/zoneinfo/__init__.py b/libs/dateutil/zoneinfo/__init__.py index 9bed626..a1b3487 100644 --- a/libs/dateutil/zoneinfo/__init__.py +++ b/libs/dateutil/zoneinfo/__init__.py @@ -1,15 +1,16 @@ +# -*- coding: utf-8 -*- """ Copyright (c) 2003-2005 Gustavo Niemeyer -This module offers extensions to the standard python 2.3+ +This module offers extensions to the standard Python datetime module. """ from dateutil.tz import tzfile from tarfile import TarFile import os -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" +__author__ = "Tomi Pieviläinen " +__license__ = "Simplified BSD" __all__ = ["setcachesize", "gettz", "rebuild"] @@ -21,8 +22,7 @@ class tzfile(tzfile): return (gettz, (self._filename,)) def getzoneinfofile(): - filenames = os.listdir(os.path.join(os.path.dirname(__file__))) - filenames.sort() + filenames = sorted(os.listdir(os.path.join(os.path.dirname(__file__)))) filenames.reverse() for entry in filenames: if entry.startswith("zoneinfo") and ".tar." in entry: @@ -66,7 +66,10 @@ def rebuild(filename, tag=None, format="gz"): targetname = "zoneinfo%s.tar.%s" % (tag, format) try: tf = TarFile.open(filename) - for name in tf.getnames(): + # The "backwards" zone file contains links to other files, so must be + # processed as last + for name in sorted(tf.getnames(), + key=lambda k: k != "backward" and k or "z"): if not (name.endswith(".sh") or name.endswith(".tab") or name == "leapseconds"): diff --git a/libs/dateutil/zoneinfo/zoneinfo--latest.tar.gz b/libs/dateutil/zoneinfo/zoneinfo--latest.tar.gz new file mode 100644 index 0000000..12eadff Binary files /dev/null and b/libs/dateutil/zoneinfo/zoneinfo--latest.tar.gz differ diff --git a/libs/dateutil/zoneinfo/zoneinfo-2010g.tar.gz b/libs/dateutil/zoneinfo/zoneinfo-2010g.tar.gz deleted file mode 100644 index 8bd4f96..0000000 Binary files a/libs/dateutil/zoneinfo/zoneinfo-2010g.tar.gz and /dev/null differ diff --git a/libs/six.py b/libs/six.py new file mode 100644 index 0000000..a91961e --- /dev/null +++ b/libs/six.py @@ -0,0 +1,366 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +import operator +import sys +import types + +__author__ = "Benjamin Peterson " +__version__ = "1.2.0" + + +# True if we are running on Python 3. +PY3 = sys.version_info[0] == 3 + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform == "java": + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) + # This is a bit ugly, but it avoids running this again. + delattr(tp, self.name) + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + + +class _MovedItems(types.ModuleType): + """Lazy loading of moved objects""" + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("reload_module", "__builtin__", "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("winreg", "_winreg"), +] +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) +del attr + +moves = sys.modules["six.moves"] = _MovedItems("moves") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_code = "__code__" + _func_defaults = "__defaults__" + + _iterkeys = "keys" + _itervalues = "values" + _iteritems = "items" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_code = "func_code" + _func_defaults = "func_defaults" + + _iterkeys = "iterkeys" + _itervalues = "itervalues" + _iteritems = "iteritems" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +if PY3: + def get_unbound_function(unbound): + return unbound + + Iterator = object + + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) +else: + def get_unbound_function(unbound): + return unbound.im_func + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) + + +def iterkeys(d): + """Return an iterator over the keys of a dictionary.""" + return iter(getattr(d, _iterkeys)()) + +def itervalues(d): + """Return an iterator over the values of a dictionary.""" + return iter(getattr(d, _itervalues)()) + +def iteritems(d): + """Return an iterator over the (key, value) pairs of a dictionary.""" + return iter(getattr(d, _iteritems)()) + + +if PY3: + def b(s): + return s.encode("latin-1") + def u(s): + return s + if sys.version_info[1] <= 1: + def int2byte(i): + return bytes((i,)) + else: + # This is about 2x faster than the implementation above on 3.2+ + int2byte = operator.methodcaller("to_bytes", 1, "big") + import io + StringIO = io.StringIO + BytesIO = io.BytesIO +else: + def b(s): + return s + def u(s): + return unicode(s, "unicode_escape") + int2byte = chr + import StringIO + StringIO = BytesIO = StringIO.StringIO +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +if PY3: + import builtins + exec_ = getattr(builtins, "exec") + + + def reraise(tp, value, tb=None): + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + + + print_ = getattr(builtins, "print") + del builtins + +else: + def exec_(code, globs=None, locs=None): + """Execute code in a namespace.""" + if globs is None: + frame = sys._getframe(1) + globs = frame.f_globals + if locs is None: + locs = frame.f_locals + del frame + elif locs is None: + locs = globs + exec("""exec code in globs, locs""") + + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + + def print_(*args, **kwargs): + """The new-style print function.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + def write(data): + if not isinstance(data, basestring): + data = str(data) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) + +_add_doc(reraise, """Reraise an exception.""") + + +def with_metaclass(meta, base=object): + """Create a base class with a metaclass.""" + return meta("NewBase", (base,), {})