Browse Source

Module update: dateutil

pull/1178/merge
Ruud 13 years ago
parent
commit
dbbbbb2f84
  1. 9
      libs/dateutil/__init__.py
  2. 9
      libs/dateutil/easter.py
  3. 207
      libs/dateutil/parser.py
  4. 122
      libs/dateutil/relativedelta.py
  5. 131
      libs/dateutil/rrule.py
  6. 129
      libs/dateutil/tz.py
  7. 31
      libs/dateutil/tzwin.py
  8. 15
      libs/dateutil/zoneinfo/__init__.py
  9. BIN
      libs/dateutil/zoneinfo/zoneinfo--latest.tar.gz
  10. BIN
      libs/dateutil/zoneinfo/zoneinfo-2010g.tar.gz
  11. 366
      libs/six.py

9
libs/dateutil/__init__.py

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
""" """
Copyright (c) 2003-2010 Gustavo Niemeyer <gustavo@niemeyer.net> Copyright (c) 2003-2010 Gustavo Niemeyer <gustavo@niemeyer.net>
This module offers extensions to the standard python 2.3+ This module offers extensions to the standard Python
datetime module. datetime module.
""" """
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>" __author__ = "Tomi Pieviläinen <tomi.pievilainen@iki.fi>"
__license__ = "PSF License" __license__ = "Simplified BSD"
__version__ = "1.5" __version__ = "2.1"

9
libs/dateutil/easter.py

@ -1,11 +1,10 @@
""" """
Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net> Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net>
This module offers extensions to the standard python 2.3+ This module offers extensions to the standard Python
datetime module. datetime module.
""" """
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>" __license__ = "Simplified BSD"
__license__ = "PSF License"
import datetime import datetime
@ -52,7 +51,7 @@ def easter(year, method=EASTER_WESTERN):
""" """
if not (1 <= method <= 3): if not (1 <= method <= 3):
raise ValueError, "invalid method" raise ValueError("invalid method")
# g - Golden year - 1 # g - Golden year - 1
# c - Century # c - Century
@ -88,5 +87,5 @@ def easter(year, method=EASTER_WESTERN):
p = i-j+e p = i-j+e
d = 1+(p+27+(p+6)//40)%31 d = 1+(p+27+(p+6)//40)%31
m = 3+(p+26)//30 m = 3+(p+26)//30
return datetime.date(int(y),int(m),int(d)) return datetime.date(int(y), int(m), int(d))

207
libs/dateutil/parser.py

@ -2,25 +2,27 @@
""" """
Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net> Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net>
This module offers extensions to the standard python 2.3+ This module offers extensions to the standard Python
datetime module. datetime module.
""" """
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>" from __future__ import unicode_literals
__license__ = "PSF License" __license__ = "Simplified BSD"
import datetime import datetime
import string import string
import time import time
import sys import collections
import os
try: try:
from cStringIO import StringIO from io import StringIO
except ImportError: except ImportError:
from StringIO import StringIO from io import StringIO
from six import text_type, binary_type, integer_types
import relativedelta from . import relativedelta
import tz from . import tz
__all__ = ["parse", "parserinfo"] __all__ = ["parse", "parserinfo"]
@ -39,7 +41,7 @@ __all__ = ["parse", "parserinfo"]
class _timelex(object): class _timelex(object):
def __init__(self, instream): def __init__(self, instream):
if isinstance(instream, basestring): if isinstance(instream, text_type):
instream = StringIO(instream) instream = StringIO(instream)
self.instream = instream self.instream = instream
self.wordchars = ('abcdfeghijklmnopqrstuvwxyz' self.wordchars = ('abcdfeghijklmnopqrstuvwxyz'
@ -133,12 +135,15 @@ class _timelex(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
token = self.get_token() token = self.get_token()
if token is None: if token is None:
raise StopIteration raise StopIteration
return token return token
def next(self):
return self.__next__() # Python 2.x support
def split(cls, s): def split(cls, s):
return list(cls(s)) return list(cls(s))
split = classmethod(split) split = classmethod(split)
@ -155,7 +160,7 @@ class _resultbase(object):
for attr in self.__slots__: for attr in self.__slots__:
value = getattr(self, attr) value = getattr(self, attr)
if value is not None: if value is not None:
l.append("%s=%s" % (attr, `value`)) l.append("%s=%s" % (attr, repr(value)))
return "%s(%s)" % (classname, ", ".join(l)) return "%s(%s)" % (classname, ", ".join(l))
def __repr__(self): def __repr__(self):
@ -167,7 +172,7 @@ class parserinfo(object):
# m from a.m/p.m, t from ISO T separator # m from a.m/p.m, t from ISO T separator
JUMP = [" ", ".", ",", ";", "-", "/", "'", JUMP = [" ", ".", ",", ";", "-", "/", "'",
"at", "on", "and", "ad", "m", "t", "of", "at", "on", "and", "ad", "m", "t", "of",
"st", "nd", "rd", "th"] "st", "nd", "rd", "th"]
WEEKDAYS = [("Mon", "Monday"), WEEKDAYS = [("Mon", "Monday"),
("Tue", "Tuesday"), ("Tue", "Tuesday"),
@ -176,7 +181,7 @@ class parserinfo(object):
("Fri", "Friday"), ("Fri", "Friday"),
("Sat", "Saturday"), ("Sat", "Saturday"),
("Sun", "Sunday")] ("Sun", "Sunday")]
MONTHS = [("Jan", "January"), MONTHS = [("Jan", "January"),
("Feb", "February"), ("Feb", "February"),
("Mar", "March"), ("Mar", "March"),
("Apr", "April"), ("Apr", "April"),
@ -184,7 +189,7 @@ class parserinfo(object):
("Jun", "June"), ("Jun", "June"),
("Jul", "July"), ("Jul", "July"),
("Aug", "August"), ("Aug", "August"),
("Sep", "September"), ("Sep", "Sept", "September"),
("Oct", "October"), ("Oct", "October"),
("Nov", "November"), ("Nov", "November"),
("Dec", "December")] ("Dec", "December")]
@ -197,7 +202,7 @@ class parserinfo(object):
PERTAIN = ["of"] PERTAIN = ["of"]
TZOFFSET = {} TZOFFSET = {}
def __init__(self, dayfirst=False, yearfirst=False): def __init__(self, dayfirst = False, yearfirst = False):
self._jump = self._convert(self.JUMP) self._jump = self._convert(self.JUMP)
self._weekdays = self._convert(self.WEEKDAYS) self._weekdays = self._convert(self.WEEKDAYS)
self._months = self._convert(self.MONTHS) self._months = self._convert(self.MONTHS)
@ -210,7 +215,7 @@ class parserinfo(object):
self.yearfirst = yearfirst self.yearfirst = yearfirst
self._year = time.localtime().tm_year self._year = time.localtime().tm_year
self._century = self._year//100*100 self._century = self._year // 100 * 100
def _convert(self, lst): def _convert(self, lst):
dct = {} dct = {}
@ -237,7 +242,7 @@ class parserinfo(object):
def month(self, name): def month(self, name):
if len(name) >= 3: if len(name) >= 3:
try: try:
return self._months[name.lower()]+1 return self._months[name.lower()] + 1
except KeyError: except KeyError:
pass pass
return None return None
@ -268,7 +273,7 @@ class parserinfo(object):
def convertyear(self, year): def convertyear(self, year):
if year < 100: if year < 100:
year += self._century year += self._century
if abs(year-self._year) >= 50: if abs(year - self._year) >= 50:
if year < self._year: if year < self._year:
year += 100 year += 100
else: else:
@ -289,18 +294,18 @@ class parserinfo(object):
class parser(object): class parser(object):
def __init__(self, info=None): def __init__(self, info = None):
self.info = info or parserinfo() self.info = info or parserinfo()
def parse(self, timestr, default=None, def parse(self, timestr, default = None,
ignoretz=False, tzinfos=None, ignoretz = False, tzinfos = None,
**kwargs): **kwargs):
if not default: if not default:
default = datetime.datetime.now().replace(hour=0, minute=0, default = datetime.datetime.now().replace(hour = 0, minute = 0,
second=0, microsecond=0) second = 0, microsecond = 0)
res = self._parse(timestr, **kwargs) res = self._parse(timestr, **kwargs)
if res is None: if res is None:
raise ValueError, "unknown string format" raise ValueError("unknown string format")
repl = {} repl = {}
for attr in ["year", "month", "day", "hour", for attr in ["year", "month", "day", "hour",
"minute", "second", "microsecond"]: "minute", "second", "microsecond"]:
@ -309,29 +314,29 @@ class parser(object):
repl[attr] = value repl[attr] = value
ret = default.replace(**repl) ret = default.replace(**repl)
if res.weekday is not None and not res.day: 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 not ignoretz:
if callable(tzinfos) or tzinfos and res.tzname in tzinfos: if isinstance(tzinfos, collections.Callable) or tzinfos and res.tzname in tzinfos:
if callable(tzinfos): if isinstance(tzinfos, collections.Callable):
tzdata = tzinfos(res.tzname, res.tzoffset) tzdata = tzinfos(res.tzname, res.tzoffset)
else: else:
tzdata = tzinfos.get(res.tzname) tzdata = tzinfos.get(res.tzname)
if isinstance(tzdata, datetime.tzinfo): if isinstance(tzdata, datetime.tzinfo):
tzinfo = tzdata tzinfo = tzdata
elif isinstance(tzdata, basestring): elif isinstance(tzdata, text_type):
tzinfo = tz.tzstr(tzdata) tzinfo = tz.tzstr(tzdata)
elif isinstance(tzdata, int): elif isinstance(tzdata, integer_types):
tzinfo = tz.tzoffset(res.tzname, tzdata) tzinfo = tz.tzoffset(res.tzname, tzdata)
else: else:
raise ValueError, "offset must be tzinfo subclass, " \ raise ValueError("offset must be tzinfo subclass, " \
"tz string, or int offset" "tz string, or int offset")
ret = ret.replace(tzinfo=tzinfo) ret = ret.replace(tzinfo = tzinfo)
elif res.tzname and res.tzname in time.tzname: 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: elif res.tzoffset == 0:
ret = ret.replace(tzinfo=tz.tzutc()) ret = ret.replace(tzinfo = tz.tzutc())
elif res.tzoffset: 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 return ret
class _result(_resultbase): class _result(_resultbase):
@ -339,7 +344,7 @@ class parser(object):
"hour", "minute", "second", "microsecond", "hour", "minute", "second", "microsecond",
"tzname", "tzoffset"] "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 info = self.info
if dayfirst is None: if dayfirst is None:
dayfirst = info.dayfirst dayfirst = info.dayfirst
@ -374,14 +379,14 @@ class parser(object):
and (i >= len_l or (l[i] != ':' and and (i >= len_l or (l[i] != ':' and
info.hms(l[i]) is None))): info.hms(l[i]) is None))):
# 19990101T23[59] # 19990101T23[59]
s = l[i-1] s = l[i - 1]
res.hour = int(s[:2]) res.hour = int(s[:2])
if len_li == 4: if len_li == 4:
res.minute = int(s[2:]) 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] # YYMMDD or HHMMSS[.ss]
s = l[i-1] s = l[i - 1]
if not ymd and l[i-1].find('.') == -1: if not ymd and l[i - 1].find('.') == -1:
ymd.append(info.convertyear(int(s[:2]))) ymd.append(info.convertyear(int(s[:2])))
ymd.append(int(s[2:4])) ymd.append(int(s[2:4]))
ymd.append(int(s[4:])) ymd.append(int(s[4:]))
@ -392,13 +397,13 @@ class parser(object):
res.second, res.microsecond = _parsems(s[4:]) res.second, res.microsecond = _parsems(s[4:])
elif len_li == 8: elif len_li == 8:
# YYYYMMDD # YYYYMMDD
s = l[i-1] s = l[i - 1]
ymd.append(int(s[:4])) ymd.append(int(s[:4]))
ymd.append(int(s[4:6])) ymd.append(int(s[4:6]))
ymd.append(int(s[6:])) ymd.append(int(s[6:]))
elif len_li in (12, 14): elif len_li in (12, 14):
# YYYYMMDDhhmm[ss] # YYYYMMDDhhmm[ss]
s = l[i-1] s = l[i - 1]
ymd.append(int(s[:4])) ymd.append(int(s[:4]))
ymd.append(int(s[4:6])) ymd.append(int(s[4:6]))
ymd.append(int(s[6:8])) ymd.append(int(s[6:8]))
@ -407,8 +412,8 @@ class parser(object):
if len_li == 14: if len_li == 14:
res.second = int(s[12:]) res.second = int(s[12:])
elif ((i < len_l and info.hms(l[i]) is not None) or elif ((i < len_l and info.hms(l[i]) is not None) or
(i+1 < len_l and l[i] == ' ' and (i + 1 < len_l and l[i] == ' ' and
info.hms(l[i+1]) is not None)): info.hms(l[i + 1]) is not None)):
# HH[ ]h or MM[ ]m or SS[.ss][ ]s # HH[ ]h or MM[ ]m or SS[.ss][ ]s
if l[i] == ' ': if l[i] == ' ':
i += 1 i += 1
@ -416,12 +421,12 @@ class parser(object):
while True: while True:
if idx == 0: if idx == 0:
res.hour = int(value) res.hour = int(value)
if value%1: if value % 1:
res.minute = int(60*(value%1)) res.minute = int(60 * (value % 1))
elif idx == 1: elif idx == 1:
res.minute = int(value) res.minute = int(value)
if value%1: if value % 1:
res.second = int(60*(value%1)) res.second = int(60 * (value % 1))
elif idx == 2: elif idx == 2:
res.second, res.microsecond = \ res.second, res.microsecond = \
_parsems(value_repr) _parsems(value_repr)
@ -441,17 +446,28 @@ class parser(object):
newidx = info.hms(l[i]) newidx = info.hms(l[i])
if newidx is not None: if newidx is not None:
idx = newidx 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]] # HH:MM[:SS[.ss]]
res.hour = int(value) res.hour = int(value)
i += 1 i += 1
value = float(l[i]) value = float(l[i])
res.minute = int(value) res.minute = int(value)
if value%1: if value % 1:
res.second = int(60*(value%1)) res.second = int(60 * (value % 1))
i += 1 i += 1
if i < len_l and l[i] == ':': 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 i += 2
elif i < len_l and l[i] in ('-', '/', '.'): elif i < len_l and l[i] in ('-', '/', '.'):
sep = l[i] sep = l[i]
@ -467,7 +483,7 @@ class parser(object):
if value is not None: if value is not None:
ymd.append(value) ymd.append(value)
assert mstridx == -1 assert mstridx == -1
mstridx = len(ymd)-1 mstridx = len(ymd) - 1
else: else:
return None return None
i += 1 i += 1
@ -477,18 +493,18 @@ class parser(object):
value = info.month(l[i]) value = info.month(l[i])
if value is not None: if value is not None:
ymd.append(value) ymd.append(value)
mstridx = len(ymd)-1 mstridx = len(ymd) - 1
assert mstridx == -1 assert mstridx == -1
else: else:
ymd.append(int(l[i])) ymd.append(int(l[i]))
i += 1 i += 1
elif i >= len_l or info.jump(l[i]): 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 # 12 am
res.hour = int(value) 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 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 res.hour = 0
i += 1 i += 1
else: else:
@ -521,7 +537,7 @@ class parser(object):
if value is not None: if value is not None:
ymd.append(value) ymd.append(value)
assert mstridx == -1 assert mstridx == -1
mstridx = len(ymd)-1 mstridx = len(ymd) - 1
i += 1 i += 1
if i < len_l: if i < len_l:
if l[i] in ('-', '/'): if l[i] in ('-', '/'):
@ -535,12 +551,12 @@ class parser(object):
i += 1 i += 1
ymd.append(int(l[i])) ymd.append(int(l[i]))
i += 1 i += 1
elif (i+3 < len_l and l[i] == l[i+2] == ' ' elif (i + 3 < len_l and l[i] == l[i + 2] == ' '
and info.pertain(l[i+1])): and info.pertain(l[i + 1])):
# Jan of 01 # Jan of 01
# In this case, 01 is clearly year # In this case, 01 is clearly year
try: try:
value = int(l[i+3]) value = int(l[i + 3])
except ValueError: except ValueError:
# Wrong guess # Wrong guess
pass pass
@ -585,32 +601,32 @@ class parser(object):
# Check for a numbered timezone # Check for a numbered timezone
if res.hour is not None and l[i] in ('+', '-'): if res.hour is not None and l[i] in ('+', '-'):
signal = (-1,1)[l[i] == '+'] signal = (-1, 1)[l[i] == '+']
i += 1 i += 1
len_li = len(l[i]) len_li = len(l[i])
if len_li == 4: if len_li == 4:
# -0300 # -0300
res.tzoffset = int(l[i][:2])*3600+int(l[i][2:])*60 res.tzoffset = int(l[i][:2]) * 3600 + int(l[i][2:]) * 60
elif i+1 < len_l and l[i+1] == ':': elif i + 1 < len_l and l[i + 1] == ':':
# -03:00 # -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 i += 2
elif len_li <= 2: elif len_li <= 2:
# -[0]3 # -[0]3
res.tzoffset = int(l[i][:2])*3600 res.tzoffset = int(l[i][:2]) * 3600
else: else:
return None return None
i += 1 i += 1
res.tzoffset *= signal res.tzoffset *= signal
# Look for a timezone name between parenthesis # Look for a timezone name between parenthesis
if (i+3 < len_l and if (i + 3 < len_l and
info.jump(l[i]) and l[i+1] == '(' and l[i+3] == ')' and info.jump(l[i]) and l[i + 1] == '(' and l[i + 3] == ')' and
3 <= len(l[i+2]) <= 5 and 3 <= len(l[i + 2]) <= 5 and
not [x for x in l[i+2] not [x for x in l[i + 2]
if x not in string.ascii_uppercase]): if x not in string.ascii_uppercase]):
# -0300 (BRST) # -0300 (BRST)
res.tzname = l[i+2] res.tzname = l[i + 2]
i += 4 i += 4
continue continue
@ -690,7 +706,12 @@ class parser(object):
return res return res
DEFAULTPARSER = parser() 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: if parserinfo:
return parser(parserinfo).parse(timestr, **kwargs) return parser(parserinfo).parse(timestr, **kwargs)
else: else:
@ -743,7 +764,7 @@ class _tzparser(object):
if l[i] in ('+', '-'): if l[i] in ('+', '-'):
# Yes, that's right. See the TZ variable # Yes, that's right. See the TZ variable
# documentation. # documentation.
signal = (1,-1)[l[i] == '+'] signal = (1, -1)[l[i] == '+']
i += 1 i += 1
else: else:
signal = -1 signal = -1
@ -751,16 +772,16 @@ class _tzparser(object):
if len_li == 4: if len_li == 4:
# -0300 # -0300
setattr(res, offattr, setattr(res, offattr,
(int(l[i][:2])*3600+int(l[i][2:])*60)*signal) (int(l[i][:2]) * 3600 + int(l[i][2:]) * 60) * signal)
elif i+1 < len_l and l[i+1] == ':': elif i + 1 < len_l and l[i + 1] == ':':
# -03:00 # -03:00
setattr(res, offattr, 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 i += 2
elif len_li <= 2: elif len_li <= 2:
# -[0]3 # -[0]3
setattr(res, offattr, setattr(res, offattr,
int(l[i][:2])*3600*signal) int(l[i][:2]) * 3600 * signal)
else: else:
return None return None
i += 1 i += 1
@ -787,29 +808,29 @@ class _tzparser(object):
x.month = int(l[i]) x.month = int(l[i])
i += 2 i += 2
if l[i] == '-': if l[i] == '-':
value = int(l[i+1])*-1 value = int(l[i + 1]) * -1
i += 1 i += 1
else: else:
value = int(l[i]) value = int(l[i])
i += 2 i += 2
if value: if value:
x.week = value x.week = value
x.weekday = (int(l[i])-1)%7 x.weekday = (int(l[i]) - 1) % 7
else: else:
x.day = int(l[i]) x.day = int(l[i])
i += 2 i += 2
x.time = int(l[i]) x.time = int(l[i])
i += 2 i += 2
if i < len_l: if i < len_l:
if l[i] in ('-','+'): if l[i] in ('-', '+'):
signal = (-1,1)[l[i] == "+"] signal = (-1, 1)[l[i] == "+"]
i += 1 i += 1
else: else:
signal = 1 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 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 y in x if y not in "0123456789"]):
for x in (res.start, res.end): for x in (res.start, res.end):
if l[i] == 'J': if l[i] == 'J':
@ -829,10 +850,10 @@ class _tzparser(object):
i += 1 i += 1
assert l[i] in ('-', '.') assert l[i] in ('-', '.')
i += 1 i += 1
x.weekday = (int(l[i])-1)%7 x.weekday = (int(l[i]) - 1) % 7
else: else:
# year day (zero based) # year day (zero based)
x.yday = int(l[i])+1 x.yday = int(l[i]) + 1
i += 1 i += 1
@ -842,17 +863,17 @@ class _tzparser(object):
len_li = len(l[i]) len_li = len(l[i])
if len_li == 4: if len_li == 4:
# -0300 # -0300
x.time = (int(l[i][:2])*3600+int(l[i][2:])*60) x.time = (int(l[i][:2]) * 3600 + int(l[i][2:]) * 60)
elif i+1 < len_l and l[i+1] == ':': elif i + 1 < len_l and l[i + 1] == ':':
# -03:00 # -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 i += 2
if i+1 < len_l and l[i+1] == ':': if i + 1 < len_l and l[i + 1] == ':':
i += 2 i += 2
x.time += int(l[i]) x.time += int(l[i])
elif len_li <= 2: elif len_li <= 2:
# -[0]3 # -[0]3
x.time = (int(l[i][:2])*3600) x.time = (int(l[i][:2]) * 3600)
else: else:
return None return None
i += 1 i += 1
@ -865,7 +886,7 @@ class _tzparser(object):
except (IndexError, ValueError, AssertionError): except (IndexError, ValueError, AssertionError):
return None return None
return res return res

122
libs/dateutil/relativedelta.py

@ -1,15 +1,16 @@
""" """
Copyright (c) 2003-2010 Gustavo Niemeyer <gustavo@niemeyer.net> Copyright (c) 2003-2010 Gustavo Niemeyer <gustavo@niemeyer.net>
This module offers extensions to the standard python 2.3+ This module offers extensions to the standard Python
datetime module. datetime module.
""" """
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>" __license__ = "Simplified BSD"
__license__ = "PSF License"
import datetime import datetime
import calendar import calendar
from six import integer_types
__all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"] __all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"]
class weekday(object): 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)]) 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 The relativedelta type is based on the specification of the excelent
work done by M.-A. Lemburg in his mx.DateTime extension. However, 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, yearday=None, nlyearday=None,
hour=None, minute=None, second=None, microsecond=None): hour=None, minute=None, second=None, microsecond=None):
if dt1 and dt2: if dt1 and dt2:
if not isinstance(dt1, datetime.date) or \ if (not isinstance(dt1, datetime.date)) or (not isinstance(dt2, datetime.date)):
not isinstance(dt2, datetime.date): raise TypeError("relativedelta only diffs datetime/date")
raise TypeError, "relativedelta only diffs datetime/date" if not type(dt1) == type(dt2): #isinstance(dt1, type(dt2)):
if type(dt1) is not type(dt2):
if not isinstance(dt1, datetime.datetime): if not isinstance(dt1, datetime.datetime):
dt1 = datetime.datetime.fromordinal(dt1.toordinal()) dt1 = datetime.datetime.fromordinal(dt1.toordinal())
elif not isinstance(dt2, datetime.datetime): elif not isinstance(dt2, datetime.datetime):
@ -172,7 +172,7 @@ Here is the behavior of operations with relativedelta:
self.second = second self.second = second
self.microsecond = microsecond self.microsecond = microsecond
if type(weekday) is int: if isinstance(weekday, integer_types):
self.weekday = weekdays[weekday] self.weekday = weekdays[weekday]
else: else:
self.weekday = weekday self.weekday = weekday
@ -185,7 +185,7 @@ Here is the behavior of operations with relativedelta:
if yearday > 59: if yearday > 59:
self.leapdays = -1 self.leapdays = -1
if yday: 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): for idx, ydays in enumerate(ydayidx):
if yday <= ydays: if yday <= ydays:
self.month = idx+1 self.month = idx+1
@ -195,7 +195,7 @@ Here is the behavior of operations with relativedelta:
self.day = yday-ydayidx[idx-1] self.day = yday-ydayidx[idx-1]
break break
else: else:
raise ValueError, "invalid year day (%d)" % yday raise ValueError("invalid year day (%d)" % yday)
self._fix() self._fix()
@ -242,9 +242,26 @@ Here is the behavior of operations with relativedelta:
else: else:
self.years = 0 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): 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): elif self._has_time and not isinstance(other, datetime.datetime):
other = datetime.datetime.fromordinal(other.toordinal()) other = datetime.datetime.fromordinal(other.toordinal())
year = (self.year or other.year)+self.years 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) ret += datetime.timedelta(days=jumpdays)
return ret return ret
def __radd__(self, other):
return self.__add__(other)
def __rsub__(self, other): def __rsub__(self, other):
return self.__neg__().__radd__(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): def __sub__(self, other):
if not isinstance(other, relativedelta): if not isinstance(other, relativedelta):
raise TypeError, "unsupported type for sub operation" raise TypeError("unsupported type for sub operation")
return relativedelta(years=other.years-self.years, return relativedelta(years=self.years-other.years,
months=other.months-self.months, months=self.months-other.months,
days=other.days-self.days, days=self.days-other.days,
hours=other.hours-self.hours, hours=self.hours-other.hours,
minutes=other.minutes-self.minutes, minutes=self.minutes-other.minutes,
seconds=other.seconds-self.seconds, seconds=self.seconds-other.seconds,
microseconds=other.microseconds-self.microseconds, microseconds=self.microseconds-other.microseconds,
leapdays=other.leapdays or self.leapdays, leapdays=self.leapdays or other.leapdays,
year=other.year or self.year, year=self.year or other.year,
month=other.month or self.month, month=self.month or other.month,
day=other.day or self.day, day=self.day or other.day,
weekday=other.weekday or self.weekday, weekday=self.weekday or other.weekday,
hour=other.hour or self.hour, hour=self.hour or other.hour,
minute=other.minute or self.minute, minute=self.minute or other.minute,
second=other.second or self.second, second=self.second or other.second,
microsecond=other.second or self.microsecond) microsecond=self.microsecond or other.microsecond)
def __neg__(self): def __neg__(self):
return relativedelta(years=-self.years, return relativedelta(years=-self.years,
@ -346,7 +346,7 @@ Here is the behavior of operations with relativedelta:
second=self.second, second=self.second,
microsecond=self.microsecond) microsecond=self.microsecond)
def __nonzero__(self): def __bool__(self):
return not (not self.years and return not (not self.years and
not self.months and not self.months and
not self.days and not self.days and
@ -366,13 +366,13 @@ Here is the behavior of operations with relativedelta:
def __mul__(self, other): def __mul__(self, other):
f = float(other) f = float(other)
return relativedelta(years=self.years*f, return relativedelta(years=int(self.years*f),
months=self.months*f, months=int(self.months*f),
days=self.days*f, days=int(self.days*f),
hours=self.hours*f, hours=int(self.hours*f),
minutes=self.minutes*f, minutes=int(self.minutes*f),
seconds=self.seconds*f, seconds=int(self.seconds*f),
microseconds=self.microseconds*f, microseconds=int(self.microseconds*f),
leapdays=self.leapdays, leapdays=self.leapdays,
year=self.year, year=self.year,
month=self.month, month=self.month,
@ -383,6 +383,8 @@ Here is the behavior of operations with relativedelta:
second=self.second, second=self.second,
microsecond=self.microsecond) microsecond=self.microsecond)
__rmul__ = __mul__
def __eq__(self, other): def __eq__(self, other):
if not isinstance(other, relativedelta): if not isinstance(other, relativedelta):
return False return False
@ -415,6 +417,8 @@ Here is the behavior of operations with relativedelta:
def __div__(self, other): def __div__(self, other):
return self.__mul__(1/float(other)) return self.__mul__(1/float(other))
__truediv__ = __div__
def __repr__(self): def __repr__(self):
l = [] l = []
for attr in ["years", "months", "days", "leapdays", for attr in ["years", "months", "days", "leapdays",
@ -426,7 +430,7 @@ Here is the behavior of operations with relativedelta:
"hour", "minute", "second", "microsecond"]: "hour", "minute", "second", "microsecond"]:
value = getattr(self, attr) value = getattr(self, attr)
if value is not None: 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)) return "%s(%s)" % (self.__class__.__name__, ", ".join(l))
# vim:ts=4:sw=4:et # vim:ts=4:sw=4:et

131
libs/dateutil/rrule.py

@ -1,18 +1,22 @@
""" """
Copyright (c) 2003-2010 Gustavo Niemeyer <gustavo@niemeyer.net> Copyright (c) 2003-2010 Gustavo Niemeyer <gustavo@niemeyer.net>
This module offers extensions to the standard python 2.3+ This module offers extensions to the standard Python
datetime module. datetime module.
""" """
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>" __license__ = "Simplified BSD"
__license__ = "PSF License"
import itertools import itertools
import datetime import datetime
import calendar import calendar
import thread try:
import _thread
except ImportError:
import thread as _thread
import sys import sys
from six import advance_iterator, integer_types
__all__ = ["rrule", "rruleset", "rrulestr", __all__ = ["rrule", "rruleset", "rrulestr",
"YEARLY", "MONTHLY", "WEEKLY", "DAILY", "YEARLY", "MONTHLY", "WEEKLY", "DAILY",
"HOURLY", "MINUTELY", "SECONDLY", "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+ 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) [7]*31+[8]*31+[9]*30+[10]*31+[11]*30+[12]*31+[1]*7)
M365MASK = list(M366MASK) 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]) MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7])
MDAY365MASK = list(MDAY366MASK) 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]) NMDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7])
NMDAY365MASK = list(NMDAY366MASK) NMDAY365MASK = list(NMDAY366MASK)
M366RANGE = (0,31,60,91,121,152,182,213,244,274,305,335,366) 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) M365RANGE = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365)
WDAYMASK = [0,1,2,3,4,5,6]*55 WDAYMASK = [0, 1, 2, 3, 4, 5, 6]*55
del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31] del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31]
MDAY365MASK = tuple(MDAY365MASK) MDAY365MASK = tuple(MDAY365MASK)
M365MASK = tuple(M365MASK) M365MASK = tuple(M365MASK)
@ -41,7 +45,7 @@ M365MASK = tuple(M365MASK)
DAILY, DAILY,
HOURLY, HOURLY,
MINUTELY, MINUTELY,
SECONDLY) = range(7) SECONDLY) = list(range(7))
# Imported on demand. # Imported on demand.
easter = None easter = None
@ -52,7 +56,7 @@ class weekday(object):
def __init__(self, weekday, n=None): def __init__(self, weekday, n=None):
if n == 0: 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.weekday = weekday
self.n = n 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)]) 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): def __init__(self, cache=False):
if cache: if cache:
self._cache = [] self._cache = []
self._cache_lock = thread.allocate_lock() self._cache_lock = _thread.allocate_lock()
self._cache_gen = self._iter() self._cache_gen = self._iter()
self._cache_complete = False self._cache_complete = False
else: else:
@ -112,7 +116,7 @@ class rrulebase:
break break
try: try:
for j in range(10): for j in range(10):
cache.append(gen.next()) cache.append(advance_iterator(gen))
except StopIteration: except StopIteration:
self._cache_gen = gen = None self._cache_gen = gen = None
self._cache_complete = True self._cache_complete = True
@ -133,13 +137,13 @@ class rrulebase:
else: else:
return list(itertools.islice(self, return list(itertools.islice(self,
item.start or 0, item.start or 0,
item.stop or sys.maxint, item.stop or sys.maxsize,
item.step or 1)) item.step or 1))
elif item >= 0: elif item >= 0:
gen = iter(self) gen = iter(self)
try: try:
for i in range(item+1): for i in range(item+1):
res = gen.next() res = advance_iterator(gen)
except StopIteration: except StopIteration:
raise IndexError raise IndexError
return res return res
@ -232,7 +236,7 @@ class rrule(rrulebase):
byweekno=None, byweekday=None, byweekno=None, byweekday=None,
byhour=None, byminute=None, bysecond=None, byhour=None, byminute=None, bysecond=None,
cache=False): cache=False):
rrulebase.__init__(self, cache) super(rrule, self).__init__(cache)
global easter global easter
if not dtstart: if not dtstart:
dtstart = datetime.datetime.now().replace(microsecond=0) dtstart = datetime.datetime.now().replace(microsecond=0)
@ -250,13 +254,13 @@ class rrule(rrulebase):
self._until = until self._until = until
if wkst is None: if wkst is None:
self._wkst = calendar.firstweekday() self._wkst = calendar.firstweekday()
elif type(wkst) is int: elif isinstance(wkst, integer_types):
self._wkst = wkst self._wkst = wkst
else: else:
self._wkst = wkst.weekday self._wkst = wkst.weekday
if bysetpos is None: if bysetpos is None:
self._bysetpos = None self._bysetpos = None
elif type(bysetpos) is int: elif isinstance(bysetpos, integer_types):
if bysetpos == 0 or not (-366 <= bysetpos <= 366): if bysetpos == 0 or not (-366 <= bysetpos <= 366):
raise ValueError("bysetpos must be between 1 and 366, " raise ValueError("bysetpos must be between 1 and 366, "
"or between -366 and -1") "or between -366 and -1")
@ -280,14 +284,14 @@ class rrule(rrulebase):
# bymonth # bymonth
if not bymonth: if not bymonth:
self._bymonth = None self._bymonth = None
elif type(bymonth) is int: elif isinstance(bymonth, integer_types):
self._bymonth = (bymonth,) self._bymonth = (bymonth,)
else: else:
self._bymonth = tuple(bymonth) self._bymonth = tuple(bymonth)
# byyearday # byyearday
if not byyearday: if not byyearday:
self._byyearday = None self._byyearday = None
elif type(byyearday) is int: elif isinstance(byyearday, integer_types):
self._byyearday = (byyearday,) self._byyearday = (byyearday,)
else: else:
self._byyearday = tuple(byyearday) self._byyearday = tuple(byyearday)
@ -295,7 +299,7 @@ class rrule(rrulebase):
if byeaster is not None: if byeaster is not None:
if not easter: if not easter:
from dateutil import easter from dateutil import easter
if type(byeaster) is int: if isinstance(byeaster, integer_types):
self._byeaster = (byeaster,) self._byeaster = (byeaster,)
else: else:
self._byeaster = tuple(byeaster) self._byeaster = tuple(byeaster)
@ -305,7 +309,7 @@ class rrule(rrulebase):
if not bymonthday: if not bymonthday:
self._bymonthday = () self._bymonthday = ()
self._bynmonthday = () self._bynmonthday = ()
elif type(bymonthday) is int: elif isinstance(bymonthday, integer_types):
if bymonthday < 0: if bymonthday < 0:
self._bynmonthday = (bymonthday,) self._bynmonthday = (bymonthday,)
self._bymonthday = () self._bymonthday = ()
@ -318,7 +322,7 @@ class rrule(rrulebase):
# byweekno # byweekno
if byweekno is None: if byweekno is None:
self._byweekno = None self._byweekno = None
elif type(byweekno) is int: elif isinstance(byweekno, integer_types):
self._byweekno = (byweekno,) self._byweekno = (byweekno,)
else: else:
self._byweekno = tuple(byweekno) self._byweekno = tuple(byweekno)
@ -326,7 +330,7 @@ class rrule(rrulebase):
if byweekday is None: if byweekday is None:
self._byweekday = None self._byweekday = None
self._bynweekday = None self._bynweekday = None
elif type(byweekday) is int: elif isinstance(byweekday, integer_types):
self._byweekday = (byweekday,) self._byweekday = (byweekday,)
self._bynweekday = None self._bynweekday = None
elif hasattr(byweekday, "n"): elif hasattr(byweekday, "n"):
@ -340,7 +344,7 @@ class rrule(rrulebase):
self._byweekday = [] self._byweekday = []
self._bynweekday = [] self._bynweekday = []
for wday in byweekday: for wday in byweekday:
if type(wday) is int: if isinstance(wday, integer_types):
self._byweekday.append(wday) self._byweekday.append(wday)
elif not wday.n or freq > MONTHLY: elif not wday.n or freq > MONTHLY:
self._byweekday.append(wday.weekday) self._byweekday.append(wday.weekday)
@ -358,7 +362,7 @@ class rrule(rrulebase):
self._byhour = (dtstart.hour,) self._byhour = (dtstart.hour,)
else: else:
self._byhour = None self._byhour = None
elif type(byhour) is int: elif isinstance(byhour, integer_types):
self._byhour = (byhour,) self._byhour = (byhour,)
else: else:
self._byhour = tuple(byhour) self._byhour = tuple(byhour)
@ -368,7 +372,7 @@ class rrule(rrulebase):
self._byminute = (dtstart.minute,) self._byminute = (dtstart.minute,)
else: else:
self._byminute = None self._byminute = None
elif type(byminute) is int: elif isinstance(byminute, integer_types):
self._byminute = (byminute,) self._byminute = (byminute,)
else: else:
self._byminute = tuple(byminute) self._byminute = tuple(byminute)
@ -378,7 +382,7 @@ class rrule(rrulebase):
self._bysecond = (dtstart.second,) self._bysecond = (dtstart.second,)
else: else:
self._bysecond = None self._bysecond = None
elif type(bysecond) is int: elif isinstance(bysecond, integer_types):
self._bysecond = (bysecond,) self._bysecond = (bysecond,)
else: else:
self._bysecond = tuple(bysecond) self._bysecond = tuple(bysecond)
@ -716,7 +720,7 @@ class _iterinfo(object):
# days from last year's last week number in # days from last year's last week number in
# this year. # this year.
if -1 not in rr._byweekno: 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 lno1wkst = (7-lyearweekday+rr._wkst)%7
lyearlen = 365+calendar.isleap(year-1) lyearlen = 365+calendar.isleap(year-1)
if lno1wkst >= 4: if lno1wkst >= 4:
@ -768,7 +772,7 @@ class _iterinfo(object):
self.lastmonth = month self.lastmonth = month
def ydayset(self, year, month, day): 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): def mdayset(self, year, month, day):
set = [None]*self.yearlen set = [None]*self.yearlen
@ -823,27 +827,38 @@ class _iterinfo(object):
class rruleset(rrulebase): class rruleset(rrulebase):
class _genitem: class _genitem(object):
def __init__(self, genlist, gen): def __init__(self, genlist, gen):
try: try:
self.dt = gen() self.dt = advance_iterator(gen)
genlist.append(self) genlist.append(self)
except StopIteration: except StopIteration:
pass pass
self.genlist = genlist self.genlist = genlist
self.gen = gen self.gen = gen
def next(self): def __next__(self):
try: try:
self.dt = self.gen() self.dt = advance_iterator(self.gen)
except StopIteration: except StopIteration:
self.genlist.remove(self) self.genlist.remove(self)
def __cmp__(self, other): next = __next__
return cmp(self.dt, other.dt)
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): def __init__(self, cache=False):
rrulebase.__init__(self, cache) super(rruleset, self).__init__(cache)
self._rrule = [] self._rrule = []
self._rdate = [] self._rdate = []
self._exrule = [] self._exrule = []
@ -851,7 +866,7 @@ class rruleset(rrulebase):
def rrule(self, rrule): def rrule(self, rrule):
self._rrule.append(rrule) self._rrule.append(rrule)
def rdate(self, rdate): def rdate(self, rdate):
self._rdate.append(rdate) self._rdate.append(rdate)
@ -864,14 +879,14 @@ class rruleset(rrulebase):
def _iter(self): def _iter(self):
rlist = [] rlist = []
self._rdate.sort() self._rdate.sort()
self._genitem(rlist, iter(self._rdate).next) self._genitem(rlist, iter(self._rdate))
for gen in [iter(x).next for x in self._rrule]: for gen in [iter(x) for x in self._rrule]:
self._genitem(rlist, gen) self._genitem(rlist, gen)
rlist.sort() rlist.sort()
exlist = [] exlist = []
self._exdate.sort() self._exdate.sort()
self._genitem(exlist, iter(self._exdate).next) self._genitem(exlist, iter(self._exdate))
for gen in [iter(x).next for x in self._exrule]: for gen in [iter(x) for x in self._exrule]:
self._genitem(exlist, gen) self._genitem(exlist, gen)
exlist.sort() exlist.sort()
lastdt = None lastdt = None
@ -880,17 +895,17 @@ class rruleset(rrulebase):
ritem = rlist[0] ritem = rlist[0]
if not lastdt or lastdt != ritem.dt: if not lastdt or lastdt != ritem.dt:
while exlist and exlist[0] < ritem: while exlist and exlist[0] < ritem:
exlist[0].next() advance_iterator(exlist[0])
exlist.sort() exlist.sort()
if not exlist or ritem != exlist[0]: if not exlist or ritem != exlist[0]:
total += 1 total += 1
yield ritem.dt yield ritem.dt
lastdt = ritem.dt lastdt = ritem.dt
ritem.next() advance_iterator(ritem)
rlist.sort() rlist.sort()
self._len = total self._len = total
class _rrulestr: class _rrulestr(object):
_freq_map = {"YEARLY": YEARLY, _freq_map = {"YEARLY": YEARLY,
"MONTHLY": MONTHLY, "MONTHLY": MONTHLY,
@ -932,7 +947,7 @@ class _rrulestr:
ignoretz=kwargs.get("ignoretz"), ignoretz=kwargs.get("ignoretz"),
tzinfos=kwargs.get("tzinfos")) tzinfos=kwargs.get("tzinfos"))
except ValueError: except ValueError:
raise ValueError, "invalid until date" raise ValueError("invalid until date")
def _handle_WKST(self, rrkwargs, name, value, **kwargs): def _handle_WKST(self, rrkwargs, name, value, **kwargs):
rrkwargs["wkst"] = self._weekday_map[value] rrkwargs["wkst"] = self._weekday_map[value]
@ -959,7 +974,7 @@ class _rrulestr:
if line.find(':') != -1: if line.find(':') != -1:
name, value = line.split(':') name, value = line.split(':')
if name != "RRULE": if name != "RRULE":
raise ValueError, "unknown parameter name" raise ValueError("unknown parameter name")
else: else:
value = line value = line
rrkwargs = {} rrkwargs = {}
@ -972,9 +987,9 @@ class _rrulestr:
ignoretz=ignoretz, ignoretz=ignoretz,
tzinfos=tzinfos) tzinfos=tzinfos)
except AttributeError: except AttributeError:
raise ValueError, "unknown parameter '%s'" % name raise ValueError("unknown parameter '%s'" % name)
except (KeyError, ValueError): except (KeyError, ValueError):
raise ValueError, "invalid '%s': %s" % (name, value) raise ValueError("invalid '%s': %s" % (name, value))
return rrule(dtstart=dtstart, cache=cache, **rrkwargs) return rrule(dtstart=dtstart, cache=cache, **rrkwargs)
def _parse_rfc(self, s, def _parse_rfc(self, s,
@ -991,7 +1006,7 @@ class _rrulestr:
unfold = True unfold = True
s = s.upper() s = s.upper()
if not s.strip(): if not s.strip():
raise ValueError, "empty string" raise ValueError("empty string")
if unfold: if unfold:
lines = s.splitlines() lines = s.splitlines()
i = 0 i = 0
@ -1026,36 +1041,36 @@ class _rrulestr:
name, value = line.split(':', 1) name, value = line.split(':', 1)
parms = name.split(';') parms = name.split(';')
if not parms: if not parms:
raise ValueError, "empty property name" raise ValueError("empty property name")
name = parms[0] name = parms[0]
parms = parms[1:] parms = parms[1:]
if name == "RRULE": if name == "RRULE":
for parm in parms: for parm in parms:
raise ValueError, "unsupported RRULE parm: "+parm raise ValueError("unsupported RRULE parm: "+parm)
rrulevals.append(value) rrulevals.append(value)
elif name == "RDATE": elif name == "RDATE":
for parm in parms: for parm in parms:
if parm != "VALUE=DATE-TIME": if parm != "VALUE=DATE-TIME":
raise ValueError, "unsupported RDATE parm: "+parm raise ValueError("unsupported RDATE parm: "+parm)
rdatevals.append(value) rdatevals.append(value)
elif name == "EXRULE": elif name == "EXRULE":
for parm in parms: for parm in parms:
raise ValueError, "unsupported EXRULE parm: "+parm raise ValueError("unsupported EXRULE parm: "+parm)
exrulevals.append(value) exrulevals.append(value)
elif name == "EXDATE": elif name == "EXDATE":
for parm in parms: for parm in parms:
if parm != "VALUE=DATE-TIME": if parm != "VALUE=DATE-TIME":
raise ValueError, "unsupported RDATE parm: "+parm raise ValueError("unsupported RDATE parm: "+parm)
exdatevals.append(value) exdatevals.append(value)
elif name == "DTSTART": elif name == "DTSTART":
for parm in parms: for parm in parms:
raise ValueError, "unsupported DTSTART parm: "+parm raise ValueError("unsupported DTSTART parm: "+parm)
if not parser: if not parser:
from dateutil import parser from dateutil import parser
dtstart = parser.parse(value, ignoretz=ignoretz, dtstart = parser.parse(value, ignoretz=ignoretz,
tzinfos=tzinfos) tzinfos=tzinfos)
else: else:
raise ValueError, "unsupported property: "+name raise ValueError("unsupported property: "+name)
if (forceset or len(rrulevals) > 1 or if (forceset or len(rrulevals) > 1 or
rdatevals or exrulevals or exdatevals): rdatevals or exrulevals or exdatevals):
if not parser and (rdatevals or exdatevals): if not parser and (rdatevals or exdatevals):

129
libs/dateutil/tz.py

@ -1,11 +1,12 @@
""" """
Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net> Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net>
This module offers extensions to the standard python 2.3+ This module offers extensions to the standard Python
datetime module. datetime module.
""" """
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>" __license__ = "Simplified BSD"
__license__ = "PSF License"
from six import string_types, PY3
import datetime import datetime
import struct import struct
@ -25,6 +26,19 @@ try:
except (ImportError, OSError): except (ImportError, OSError):
tzwin, tzwinlocal = None, None 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) ZERO = datetime.timedelta(0)
EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal() EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal()
@ -36,6 +50,7 @@ class tzutc(datetime.tzinfo):
def dst(self, dt): def dst(self, dt):
return ZERO return ZERO
@tzname_in_python2
def tzname(self, dt): def tzname(self, dt):
return "UTC" return "UTC"
@ -63,6 +78,7 @@ class tzoffset(datetime.tzinfo):
def dst(self, dt): def dst(self, dt):
return ZERO return ZERO
@tzname_in_python2
def tzname(self, dt): def tzname(self, dt):
return self._name return self._name
@ -75,7 +91,7 @@ class tzoffset(datetime.tzinfo):
def __repr__(self): def __repr__(self):
return "%s(%s, %s)" % (self.__class__.__name__, return "%s(%s, %s)" % (self.__class__.__name__,
`self._name`, repr(self._name),
self._offset.days*86400+self._offset.seconds) self._offset.days*86400+self._offset.seconds)
__reduce__ = object.__reduce__ __reduce__ = object.__reduce__
@ -100,6 +116,7 @@ class tzlocal(datetime.tzinfo):
else: else:
return ZERO return ZERO
@tzname_in_python2
def tzname(self, dt): def tzname(self, dt):
return time.tzname[self._isdst(dt)] return time.tzname[self._isdst(dt)]
@ -161,7 +178,7 @@ class _ttinfo(object):
for attr in self.__slots__: for attr in self.__slots__:
value = getattr(self, attr) value = getattr(self, attr)
if value is not None: 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)) return "%s(%s)" % (self.__class__.__name__, ", ".join(l))
def __eq__(self, other): def __eq__(self, other):
@ -191,16 +208,16 @@ class _ttinfo(object):
class tzfile(datetime.tzinfo): class tzfile(datetime.tzinfo):
# http://www.twinsun.com/tz/tz-link.htm # 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): def __init__(self, fileobj):
if isinstance(fileobj, basestring): if isinstance(fileobj, string_types):
self._filename = fileobj self._filename = fileobj
fileobj = open(fileobj) fileobj = open(fileobj, 'rb')
elif hasattr(fileobj, "name"): elif hasattr(fileobj, "name"):
self._filename = fileobj.name self._filename = fileobj.name
else: else:
self._filename = `fileobj` self._filename = repr(fileobj)
# From tzfile(5): # From tzfile(5):
# #
@ -212,8 +229,8 @@ class tzfile(datetime.tzinfo):
# ``standard'' byte order (the high-order byte # ``standard'' byte order (the high-order byte
# of the value is written first). # of the value is written first).
if fileobj.read(4) != "TZif": if fileobj.read(4).decode() != "TZif":
raise ValueError, "magic not found" raise ValueError("magic not found")
fileobj.read(16) fileobj.read(16)
@ -284,7 +301,7 @@ class tzfile(datetime.tzinfo):
for i in range(typecnt): for i in range(typecnt):
ttinfo.append(struct.unpack(">lbb", fileobj.read(6))) 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 # Then there are tzh_leapcnt pairs of four-byte
# values, written in standard byte order; the # values, written in standard byte order; the
@ -360,7 +377,7 @@ class tzfile(datetime.tzinfo):
if not self._trans_list: if not self._trans_list:
self._ttinfo_std = self._ttinfo_first = self._ttinfo_list[0] self._ttinfo_std = self._ttinfo_first = self._ttinfo_list[0]
else: else:
for i in range(timecnt-1,-1,-1): for i in range(timecnt-1, -1, -1):
tti = self._trans_idx[i] tti = self._trans_idx[i]
if not self._ttinfo_std and not tti.isdst: if not self._ttinfo_std and not tti.isdst:
self._ttinfo_std = tti self._ttinfo_std = tti
@ -448,6 +465,7 @@ class tzfile(datetime.tzinfo):
# dst offset, so I belive that this wouldn't be the right # dst offset, so I belive that this wouldn't be the right
# way to implement this. # way to implement this.
@tzname_in_python2
def tzname(self, dt): def tzname(self, dt):
if not self._ttinfo_std: if not self._ttinfo_std:
return None return None
@ -465,11 +483,11 @@ class tzfile(datetime.tzinfo):
def __repr__(self): def __repr__(self):
return "%s(%s)" % (self.__class__.__name__, `self._filename`) return "%s(%s)" % (self.__class__.__name__, repr(self._filename))
def __reduce__(self): def __reduce__(self):
if not os.path.isfile(self._filename): 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,)) return (self.__class__, (self._filename,))
class tzrange(datetime.tzinfo): class tzrange(datetime.tzinfo):
@ -515,6 +533,7 @@ class tzrange(datetime.tzinfo):
else: else:
return ZERO return ZERO
@tzname_in_python2
def tzname(self, dt): def tzname(self, dt):
if self._isdst(dt): if self._isdst(dt):
return self._dst_abbr return self._dst_abbr
@ -524,7 +543,7 @@ class tzrange(datetime.tzinfo):
def _isdst(self, dt): def _isdst(self, dt):
if not self._start_delta: if not self._start_delta:
return False return False
year = datetime.datetime(dt.year,1,1) year = datetime.datetime(dt.year, 1, 1)
start = year+self._start_delta start = year+self._start_delta
end = year+self._end_delta end = year+self._end_delta
dt = dt.replace(tzinfo=None) dt = dt.replace(tzinfo=None)
@ -561,7 +580,7 @@ class tzstr(tzrange):
res = parser._parsetz(s) res = parser._parsetz(s)
if res is None: if res is None:
raise ValueError, "unknown string format" raise ValueError("unknown string format")
# Here we break the compatibility with the TZ variable handling. # Here we break the compatibility with the TZ variable handling.
# GMT-3 actually *means* the timezone -3. # GMT-3 actually *means* the timezone -3.
@ -624,9 +643,9 @@ class tzstr(tzrange):
return relativedelta.relativedelta(**kwargs) return relativedelta.relativedelta(**kwargs)
def __repr__(self): 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, def __init__(self, tzoffsetfrom, tzoffsetto, isdst,
tzname=None, rrule=None): tzname=None, rrule=None):
self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom) self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom)
@ -690,51 +709,52 @@ class _tzicalvtz(datetime.tzinfo):
else: else:
return ZERO return ZERO
@tzname_in_python2
def tzname(self, dt): def tzname(self, dt):
return self._find_comp(dt).tzname return self._find_comp(dt).tzname
def __repr__(self): def __repr__(self):
return "<tzicalvtz %s>" % `self._tzid` return "<tzicalvtz %s>" % repr(self._tzid)
__reduce__ = object.__reduce__ __reduce__ = object.__reduce__
class tzical: class tzical(object):
def __init__(self, fileobj): def __init__(self, fileobj):
global rrule global rrule
if not rrule: if not rrule:
from dateutil import rrule from dateutil import rrule
if isinstance(fileobj, basestring): if isinstance(fileobj, string_types):
self._s = fileobj self._s = fileobj
fileobj = open(fileobj) fileobj = open(fileobj, 'r') # ical should be encoded in UTF-8 with CRLF
elif hasattr(fileobj, "name"): elif hasattr(fileobj, "name"):
self._s = fileobj.name self._s = fileobj.name
else: else:
self._s = `fileobj` self._s = repr(fileobj)
self._vtz = {} self._vtz = {}
self._parse_rfc(fileobj.read()) self._parse_rfc(fileobj.read())
def keys(self): def keys(self):
return self._vtz.keys() return list(self._vtz.keys())
def get(self, tzid=None): def get(self, tzid=None):
if tzid is None: if tzid is None:
keys = self._vtz.keys() keys = list(self._vtz.keys())
if len(keys) == 0: if len(keys) == 0:
raise ValueError, "no timezones defined" raise ValueError("no timezones defined")
elif len(keys) > 1: elif len(keys) > 1:
raise ValueError, "more than one timezone available" raise ValueError("more than one timezone available")
tzid = keys[0] tzid = keys[0]
return self._vtz.get(tzid) return self._vtz.get(tzid)
def _parse_offset(self, s): def _parse_offset(self, s):
s = s.strip() s = s.strip()
if not s: if not s:
raise ValueError, "empty offset" raise ValueError("empty offset")
if s[0] in ('+', '-'): if s[0] in ('+', '-'):
signal = (-1,+1)[s[0]=='+'] signal = (-1, +1)[s[0]=='+']
s = s[1:] s = s[1:]
else: else:
signal = +1 signal = +1
@ -743,12 +763,12 @@ class tzical:
elif len(s) == 6: elif len(s) == 6:
return (int(s[:2])*3600+int(s[2:4])*60+int(s[4:]))*signal return (int(s[:2])*3600+int(s[2:4])*60+int(s[4:]))*signal
else: else:
raise ValueError, "invalid offset: "+s raise ValueError("invalid offset: "+s)
def _parse_rfc(self, s): def _parse_rfc(self, s):
lines = s.splitlines() lines = s.splitlines()
if not lines: if not lines:
raise ValueError, "empty string" raise ValueError("empty string")
# Unfold # Unfold
i = 0 i = 0
@ -772,7 +792,7 @@ class tzical:
name, value = line.split(':', 1) name, value = line.split(':', 1)
parms = name.split(';') parms = name.split(';')
if not parms: if not parms:
raise ValueError, "empty property name" raise ValueError("empty property name")
name = parms[0].upper() name = parms[0].upper()
parms = parms[1:] parms = parms[1:]
if invtz: if invtz:
@ -781,7 +801,7 @@ class tzical:
# Process component # Process component
pass pass
else: else:
raise ValueError, "unknown component: "+value raise ValueError("unknown component: "+value)
comptype = value comptype = value
founddtstart = False founddtstart = False
tzoffsetfrom = None tzoffsetfrom = None
@ -791,27 +811,21 @@ class tzical:
elif name == "END": elif name == "END":
if value == "VTIMEZONE": if value == "VTIMEZONE":
if comptype: if comptype:
raise ValueError, \ raise ValueError("component not closed: "+comptype)
"component not closed: "+comptype
if not tzid: if not tzid:
raise ValueError, \ raise ValueError("mandatory TZID not found")
"mandatory TZID not found"
if not comps: if not comps:
raise ValueError, \ raise ValueError("at least one component is needed")
"at least one component is needed"
# Process vtimezone # Process vtimezone
self._vtz[tzid] = _tzicalvtz(tzid, comps) self._vtz[tzid] = _tzicalvtz(tzid, comps)
invtz = False invtz = False
elif value == comptype: elif value == comptype:
if not founddtstart: if not founddtstart:
raise ValueError, \ raise ValueError("mandatory DTSTART not found")
"mandatory DTSTART not found"
if tzoffsetfrom is None: if tzoffsetfrom is None:
raise ValueError, \ raise ValueError("mandatory TZOFFSETFROM not found")
"mandatory TZOFFSETFROM not found"
if tzoffsetto is None: if tzoffsetto is None:
raise ValueError, \ raise ValueError("mandatory TZOFFSETFROM not found")
"mandatory TZOFFSETFROM not found"
# Process component # Process component
rr = None rr = None
if rrulelines: if rrulelines:
@ -825,8 +839,7 @@ class tzical:
comps.append(comp) comps.append(comp)
comptype = None comptype = None
else: else:
raise ValueError, \ raise ValueError("invalid component end: "+value)
"invalid component end: "+value
elif comptype: elif comptype:
if name == "DTSTART": if name == "DTSTART":
rrulelines.append(line) rrulelines.append(line)
@ -835,40 +848,36 @@ class tzical:
rrulelines.append(line) rrulelines.append(line)
elif name == "TZOFFSETFROM": elif name == "TZOFFSETFROM":
if parms: if parms:
raise ValueError, \ raise ValueError("unsupported %s parm: %s "%(name, parms[0]))
"unsupported %s parm: %s "%(name, parms[0])
tzoffsetfrom = self._parse_offset(value) tzoffsetfrom = self._parse_offset(value)
elif name == "TZOFFSETTO": elif name == "TZOFFSETTO":
if parms: if parms:
raise ValueError, \ raise ValueError("unsupported TZOFFSETTO parm: "+parms[0])
"unsupported TZOFFSETTO parm: "+parms[0]
tzoffsetto = self._parse_offset(value) tzoffsetto = self._parse_offset(value)
elif name == "TZNAME": elif name == "TZNAME":
if parms: if parms:
raise ValueError, \ raise ValueError("unsupported TZNAME parm: "+parms[0])
"unsupported TZNAME parm: "+parms[0]
tzname = value tzname = value
elif name == "COMMENT": elif name == "COMMENT":
pass pass
else: else:
raise ValueError, "unsupported property: "+name raise ValueError("unsupported property: "+name)
else: else:
if name == "TZID": if name == "TZID":
if parms: if parms:
raise ValueError, \ raise ValueError("unsupported TZID parm: "+parms[0])
"unsupported TZID parm: "+parms[0]
tzid = value tzid = value
elif name in ("TZURL", "LAST-MODIFIED", "COMMENT"): elif name in ("TZURL", "LAST-MODIFIED", "COMMENT"):
pass pass
else: else:
raise ValueError, "unsupported property: "+name raise ValueError("unsupported property: "+name)
elif name == "BEGIN" and value == "VTIMEZONE": elif name == "BEGIN" and value == "VTIMEZONE":
tzid = None tzid = None
comps = [] comps = []
invtz = True invtz = True
def __repr__(self): def __repr__(self):
return "%s(%s)" % (self.__class__.__name__, `self._s`) return "%s(%s)" % (self.__class__.__name__, repr(self._s))
if sys.platform != "win32": if sys.platform != "win32":
TZFILES = ["/etc/localtime", "localtime"] TZFILES = ["/etc/localtime", "localtime"]
@ -914,7 +923,7 @@ def gettz(name=None):
for path in TZPATHS: for path in TZPATHS:
filepath = os.path.join(path, name) filepath = os.path.join(path, name)
if not os.path.isfile(filepath): if not os.path.isfile(filepath):
filepath = filepath.replace(' ','_') filepath = filepath.replace(' ', '_')
if not os.path.isfile(filepath): if not os.path.isfile(filepath):
continue continue
try: try:

31
libs/dateutil/tzwin.py

@ -1,9 +1,8 @@
# This code was originally contributed by Jeffrey Harris. # This code was originally contributed by Jeffrey Harris.
import datetime import datetime
import struct import struct
import _winreg import winreg
__author__ = "Jeffrey Harris & Gustavo Niemeyer <gustavo@niemeyer.net>"
__all__ = ["tzwin", "tzwinlocal"] __all__ = ["tzwin", "tzwinlocal"]
@ -15,9 +14,9 @@ TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
def _settzkeyname(): def _settzkeyname():
global TZKEYNAME global TZKEYNAME
handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
try: try:
_winreg.OpenKey(handle, TZKEYNAMENT).Close() winreg.OpenKey(handle, TZKEYNAMENT).Close()
TZKEYNAME = TZKEYNAMENT TZKEYNAME = TZKEYNAMENT
except WindowsError: except WindowsError:
TZKEYNAME = TZKEYNAME9X TZKEYNAME = TZKEYNAME9X
@ -49,10 +48,10 @@ class tzwinbase(datetime.tzinfo):
def list(): def list():
"""Return a list of all time zones known to the system.""" """Return a list of all time zones known to the system."""
handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
tzkey = _winreg.OpenKey(handle, TZKEYNAME) tzkey = winreg.OpenKey(handle, TZKEYNAME)
result = [_winreg.EnumKey(tzkey, i) result = [winreg.EnumKey(tzkey, i)
for i in range(_winreg.QueryInfoKey(tzkey)[0])] for i in range(winreg.QueryInfoKey(tzkey)[0])]
tzkey.Close() tzkey.Close()
handle.Close() handle.Close()
return result return result
@ -79,8 +78,8 @@ class tzwin(tzwinbase):
def __init__(self, name): def __init__(self, name):
self._name = name self._name = name
handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
tzkey = _winreg.OpenKey(handle, "%s\%s" % (TZKEYNAME, name)) tzkey = winreg.OpenKey(handle, "%s\%s" % (TZKEYNAME, name))
keydict = valuestodict(tzkey) keydict = valuestodict(tzkey)
tzkey.Close() tzkey.Close()
handle.Close() handle.Close()
@ -118,9 +117,9 @@ class tzwinlocal(tzwinbase):
def __init__(self): 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) keydict = valuestodict(tzlocalkey)
tzlocalkey.Close() tzlocalkey.Close()
@ -128,7 +127,7 @@ class tzwinlocal(tzwinbase):
self._dstname = keydict["DaylightName"].encode("iso-8859-1") self._dstname = keydict["DaylightName"].encode("iso-8859-1")
try: try:
tzkey = _winreg.OpenKey(handle, "%s\%s"%(TZKEYNAME, self._stdname)) tzkey = winreg.OpenKey(handle, "%s\%s"%(TZKEYNAME, self._stdname))
_keydict = valuestodict(tzkey) _keydict = valuestodict(tzkey)
self._display = _keydict["Display"] self._display = _keydict["Display"]
tzkey.Close() tzkey.Close()
@ -165,7 +164,7 @@ def picknthweekday(year, month, dayofweek, hour, minute, whichweek):
"""dayofweek == 0 means Sunday, whichweek 5 means last instance""" """dayofweek == 0 means Sunday, whichweek 5 means last instance"""
first = datetime.datetime(year, month, 1, hour, minute) first = datetime.datetime(year, month, 1, hour, minute)
weekdayone = first.replace(day=((dayofweek-first.isoweekday())%7+1)) weekdayone = first.replace(day=((dayofweek-first.isoweekday())%7+1))
for n in xrange(whichweek): for n in range(whichweek):
dt = weekdayone+(whichweek-n)*ONEWEEK dt = weekdayone+(whichweek-n)*ONEWEEK
if dt.month == month: if dt.month == month:
return dt return dt
@ -173,8 +172,8 @@ def picknthweekday(year, month, dayofweek, hour, minute, whichweek):
def valuestodict(key): def valuestodict(key):
"""Convert a registry key's values to a dictionary.""" """Convert a registry key's values to a dictionary."""
dict = {} dict = {}
size = _winreg.QueryInfoKey(key)[1] size = winreg.QueryInfoKey(key)[1]
for i in range(size): for i in range(size):
data = _winreg.EnumValue(key, i) data = winreg.EnumValue(key, i)
dict[data[0]] = data[1] dict[data[0]] = data[1]
return dict return dict

15
libs/dateutil/zoneinfo/__init__.py

@ -1,15 +1,16 @@
# -*- coding: utf-8 -*-
""" """
Copyright (c) 2003-2005 Gustavo Niemeyer <gustavo@niemeyer.net> Copyright (c) 2003-2005 Gustavo Niemeyer <gustavo@niemeyer.net>
This module offers extensions to the standard python 2.3+ This module offers extensions to the standard Python
datetime module. datetime module.
""" """
from dateutil.tz import tzfile from dateutil.tz import tzfile
from tarfile import TarFile from tarfile import TarFile
import os import os
__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>" __author__ = "Tomi Pieviläinen <tomi.pievilainen@iki.fi>"
__license__ = "PSF License" __license__ = "Simplified BSD"
__all__ = ["setcachesize", "gettz", "rebuild"] __all__ = ["setcachesize", "gettz", "rebuild"]
@ -21,8 +22,7 @@ class tzfile(tzfile):
return (gettz, (self._filename,)) return (gettz, (self._filename,))
def getzoneinfofile(): def getzoneinfofile():
filenames = os.listdir(os.path.join(os.path.dirname(__file__))) filenames = sorted(os.listdir(os.path.join(os.path.dirname(__file__))))
filenames.sort()
filenames.reverse() filenames.reverse()
for entry in filenames: for entry in filenames:
if entry.startswith("zoneinfo") and ".tar." in entry: 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) targetname = "zoneinfo%s.tar.%s" % (tag, format)
try: try:
tf = TarFile.open(filename) 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 if not (name.endswith(".sh") or
name.endswith(".tab") or name.endswith(".tab") or
name == "leapseconds"): name == "leapseconds"):

BIN
libs/dateutil/zoneinfo/zoneinfo--latest.tar.gz

Binary file not shown.

BIN
libs/dateutil/zoneinfo/zoneinfo-2010g.tar.gz

Binary file not shown.

366
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 <benjamin@python.org>"
__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,), {})
Loading…
Cancel
Save