Update prop.py (#482)

Update prop.py
pull/481/head
Pronoy Mandal 2022-10-31 13:51:59 +05:30 zatwierdzone przez GitHub
rodzic eb0348676b
commit cb2ccaa049
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
2 zmienionych plików z 61 dodań i 66 usunięć

Wyświetl plik

@ -6,7 +6,7 @@ Changelog
Minor changes:
- Refactored parser.py. Ref: #483 [pronoym99]
- Refactored prop.py. Ref: #482 [pronoym99]
- Calendar.from_ical no longer throws long errors
Ref: #473

Wyświetl plik

@ -90,6 +90,7 @@ DSTDIFF = DSTOFFSET - STDOFFSET
class FixedOffset(tzinfo):
"""Fixed offset in minutes east from UTC.
"""
def __init__(self, offset, name):
self.__offset = timedelta(minutes=offset)
self.__name = name
@ -107,17 +108,12 @@ class FixedOffset(tzinfo):
class LocalTimezone(tzinfo):
"""Timezone of the machine where the code is running.
"""
def utcoffset(self, dt):
if self._isdst(dt):
return DSTOFFSET
else:
return STDOFFSET
return DSTOFFSET if self._isdst(dt) else STDOFFSET
def dst(self, dt):
if self._isdst(dt):
return DSTDIFF
else:
return ZERO
return DSTDIFF if self._isdst(dt) else ZERO
def tzname(self, dt):
return _time.tzname[self._isdst(dt)]
@ -140,7 +136,7 @@ class vBinary:
self.params = Parameters(encoding='BASE64', value="BINARY")
def __repr__(self):
return "vBinary('%s')" % self.to_ical()
return f"vBinary('{self.to_ical()}')"
def to_ical(self):
return binascii.b2a_base64(self.obj.encode('utf-8'))[:-1]
@ -164,16 +160,14 @@ class vBoolean(int):
return self
def to_ical(self):
if self:
return b'TRUE'
return b'FALSE'
return b'TRUE' if self else b'FALSE'
@classmethod
def from_ical(cls, ical):
try:
return cls.BOOL_MAP[ical]
except Exception:
raise ValueError("Expected 'TRUE' or 'FALSE'. Got %s" % ical)
raise ValueError(f"Expected 'TRUE' or 'FALSE'. Got {ical}")
class vCalAddress(str):
@ -186,7 +180,7 @@ class vCalAddress(str):
return self
def __repr__(self):
return "vCalAddress('%s')" % self.to_ical()
return f"vCalAddress('{self.to_ical()}')"
def to_ical(self):
return self.encode(DEFAULT_ENCODING)
@ -212,7 +206,7 @@ class vFloat(float):
try:
return cls(ical)
except Exception:
raise ValueError('Expected float value, got: %s' % ical)
raise ValueError(f'Expected float value, got: {ical}')
class vInt(int):
@ -231,12 +225,13 @@ class vInt(int):
try:
return cls(ical)
except Exception:
raise ValueError('Expected int, got: %s' % ical)
raise ValueError(f'Expected int, got: {ical}')
class vDDDLists:
"""A list of vDDDTypes values.
"""
def __init__(self, dt_list):
if not hasattr(dt_list, '__iter__'):
dt_list = [dt_list]
@ -265,6 +260,7 @@ class vDDDLists:
out.append(vDDDTypes.from_ical(ical_dt, timezone=timezone))
return out
class vCategory:
def __init__(self, c_list):
@ -287,6 +283,7 @@ class vDDDTypes:
cannot be confused, and often values can be of either types.
So this is practical.
"""
def __init__(self, dt):
if not isinstance(dt, (datetime, date, timedelta, time, tuple)):
raise ValueError('You must use datetime, date, timedelta, '
@ -346,13 +343,14 @@ class vDDDTypes:
return vTime.from_ical(ical)
else:
raise ValueError(
"Expected datetime, date, or time, got: '%s'" % ical
f"Expected datetime, date, or time, got: '{ical}'"
)
class vDate:
"""Render and generates iCalendar date format.
"""
def __init__(self, dt):
if not isinstance(dt, date):
raise ValueError('Value MUST be a date instance')
@ -360,7 +358,7 @@ class vDate:
self.params = Parameters({'value': 'DATE'})
def to_ical(self):
s = "%04d%02d%02d" % (self.dt.year, self.dt.month, self.dt.day)
s = f"{self.dt.year:04}{self.dt.month:02}{self.dt.day:02}"
return s.encode('utf-8')
@staticmethod
@ -373,7 +371,7 @@ class vDate:
)
return date(*timetuple)
except Exception:
raise ValueError('Wrong date format %s' % ical)
raise ValueError(f'Wrong date format {ical}')
class vDatetime:
@ -387,6 +385,7 @@ class vDatetime:
created. Be aware that there are certain limitations with timezone naive
DATE-TIME components in the icalendar standard.
"""
def __init__(self, dt):
self.dt = dt
self.params = Parameters()
@ -395,14 +394,7 @@ class vDatetime:
dt = self.dt
tzid = tzid_from_dt(dt)
s = "%04d%02d%02dT%02d%02d%02d" % (
dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second
)
s = f"{dt.year:04}{dt.month:02}{dt.day:02}T{dt.hour:02}{dt.minute:02}{dt.second:02}"
if tzid == 'UTC':
s += "Z"
elif tzid:
@ -417,7 +409,8 @@ class vDatetime:
tzinfo = pytz.timezone(timezone.strip('/'))
except pytz.UnknownTimeZoneError:
if timezone in WINDOWS_TO_OLSON:
tzinfo = pytz.timezone(WINDOWS_TO_OLSON.get(timezone.strip('/')))
tzinfo = pytz.timezone(
WINDOWS_TO_OLSON.get(timezone.strip('/')))
else:
tzinfo = _timezone_cache.get(timezone, None)
@ -439,7 +432,7 @@ class vDatetime:
else:
raise ValueError(ical)
except Exception:
raise ValueError('Wrong datetime format: %s' % ical)
raise ValueError(f'Wrong datetime format: {ical}')
class vDuration:
@ -466,18 +459,18 @@ class vDuration:
minutes = td.seconds % 3600 // 60
seconds = td.seconds % 60
if hours:
timepart += "%dH" % hours
timepart += f"{hours}H"
if minutes or (hours and seconds):
timepart += "%dM" % minutes
timepart += f"{minutes}M"
if seconds:
timepart += "%dS" % seconds
timepart += f"{seconds}S"
if td.days == 0 and timepart:
return (str(sign).encode('utf-8') + b'P' +
str(timepart).encode('utf-8'))
return (str(sign).encode('utf-8') + b'P'
+ str(timepart).encode('utf-8'))
else:
return (str(sign).encode('utf-8') + b'P' +
str(abs(td.days)).encode('utf-8') +
b'D' + str(timepart).encode('utf-8'))
return (str(sign).encode('utf-8') + b'P'
+ str(abs(td.days)).encode('utf-8')
+ b'D' + str(timepart).encode('utf-8'))
@staticmethod
def from_ical(ical):
@ -495,19 +488,20 @@ class vDuration:
value = -value
return value
except Exception:
raise ValueError('Invalid iCalendar duration: %s' % ical)
raise ValueError(f'Invalid iCalendar duration: {ical}')
class vPeriod:
"""A precise period of time.
"""
def __init__(self, per):
start, end_or_duration = per
if not (isinstance(start, datetime) or isinstance(start, date)):
raise ValueError('Start value MUST be a datetime or date instance')
if not (isinstance(end_or_duration, datetime) or
isinstance(end_or_duration, date) or
isinstance(end_or_duration, timedelta)):
if not (isinstance(end_or_duration, datetime)
or isinstance(end_or_duration, date)
or isinstance(end_or_duration, timedelta)):
raise ValueError('end_or_duration MUST be a datetime, '
'date or timedelta instance')
by_duration = 0
@ -535,7 +529,8 @@ class vPeriod:
def __cmp__(self, other):
if not isinstance(other, vPeriod):
raise NotImplementedError('Cannot compare vPeriod with %r' % other)
raise NotImplementedError(
f'Cannot compare vPeriod with {other!r}')
return cmp((self.start, self.end), (other.start, other.end))
def overlaps(self, other):
@ -547,10 +542,10 @@ class vPeriod:
def to_ical(self):
if self.by_duration:
return (vDatetime(self.start).to_ical() + b'/' +
vDuration(self.duration).to_ical())
return (vDatetime(self.start).to_ical() + b'/' +
vDatetime(self.end).to_ical())
return (vDatetime(self.start).to_ical() + b'/'
+ vDuration(self.duration).to_ical())
return (vDatetime(self.start).to_ical() + b'/'
+ vDatetime(self.end).to_ical())
@staticmethod
def from_ical(ical):
@ -560,7 +555,7 @@ class vPeriod:
end_or_duration = vDDDTypes.from_ical(end_or_duration)
return (start, end_or_duration)
except Exception:
raise ValueError('Expected period format, got: %s' % ical)
raise ValueError(f'Expected period format, got: {ical}')
def __repr__(self):
if self.by_duration:
@ -582,13 +577,13 @@ class vWeekday(str):
self = super().__new__(cls, value)
match = WEEKDAY_RULE.match(self)
if match is None:
raise ValueError('Expected weekday abbrevation, got: %s' % self)
raise ValueError(f'Expected weekday abbrevation, got: {self}')
match = match.groupdict()
sign = match['signal']
weekday = match['weekday']
relative = match['relative']
if weekday not in vWeekday.week_days or sign not in '+-':
raise ValueError('Expected weekday abbrevation, got: %s' % self)
raise ValueError(f'Expected weekday abbrevation, got: {self}')
self.relative = relative and int(relative) or None
self.params = Parameters()
return self
@ -601,7 +596,7 @@ class vWeekday(str):
try:
return cls(ical.upper())
except Exception:
raise ValueError('Expected weekday abbrevation, got: %s' % ical)
raise ValueError(f'Expected weekday abbrevation, got: {ical}')
class vFrequency(str):
@ -622,7 +617,7 @@ class vFrequency(str):
value = to_unicode(value, encoding=encoding)
self = super().__new__(cls, value)
if self not in vFrequency.frequencies:
raise ValueError('Expected frequency, got: %s' % self)
raise ValueError(f'Expected frequency, got: {self}')
self.params = Parameters()
return self
@ -634,7 +629,7 @@ class vFrequency(str):
try:
return cls(ical.upper())
except Exception:
raise ValueError('Expected frequency, got: %s' % ical)
raise ValueError(f'Expected frequency, got: {ical}')
class vRecur(CaselessDict):
@ -708,7 +703,7 @@ class vRecur(CaselessDict):
recur[key] = cls.parse_type(key, vals)
return dict(recur)
except Exception:
raise ValueError('Error in recurrence rule: %s' % ical)
raise ValueError(f'Error in recurrence rule: {ical}')
class vText(str):
@ -723,7 +718,7 @@ class vText(str):
return self
def __repr__(self):
return "vText('%s')" % self.to_ical()
return f"vText('{self.to_ical()}')"
def to_ical(self):
return escape_char(self).encode(self.encoding)
@ -741,7 +736,7 @@ class vTime:
def __init__(self, *args):
if len(args) == 1:
if not isinstance(args[0], (time, datetime)):
raise ValueError('Expected a datetime.time, got: %s' % args[0])
raise ValueError(f'Expected a datetime.time, got: {args[0]}')
self.dt = args[0]
else:
self.dt = time(*args)
@ -757,7 +752,7 @@ class vTime:
timetuple = (int(ical[:2]), int(ical[2:4]), int(ical[4:6]))
return time(*timetuple)
except Exception:
raise ValueError('Expected time, got: %s' % ical)
raise ValueError(f'Expected time, got: {ical}')
class vUri(str):
@ -778,7 +773,7 @@ class vUri(str):
try:
return cls(ical)
except Exception:
raise ValueError('Expected , got: %s' % ical)
raise ValueError(f'Expected , got: {ical}')
class vGeo:
@ -806,7 +801,7 @@ class vGeo:
latitude, longitude = ical.split(';')
return (float(latitude), float(longitude))
except Exception:
raise ValueError("Expected 'float;float' , got: %s" % ical)
raise ValueError(f"Expected 'float;float' , got: {ical}")
class vUTCOffset:
@ -814,9 +809,9 @@ class vUTCOffset:
"""
ignore_exceptions = False # if True, and we cannot parse this
# component, we will silently ignore
# it, rather than let the exception
# propagate upwards
# component, we will silently ignore
# it, rather than let the exception
# propagate upwards
def __init__(self, td):
if not isinstance(td, timedelta):
@ -840,9 +835,9 @@ class vUTCOffset:
minutes = abs((seconds % 3600) // 60)
seconds = abs(seconds % 60)
if seconds:
duration = '%02i%02i%02i' % (hours, minutes, seconds)
duration = f'{hours:02}{minutes:02}{seconds:02}'
else:
duration = '%02i%02i' % (hours, minutes)
duration = f'{hours:02}{minutes:02}'
return sign % duration
@classmethod
@ -856,10 +851,10 @@ class vUTCOffset:
int(ical[5:7] or 0))
offset = timedelta(hours=hours, minutes=minutes, seconds=seconds)
except Exception:
raise ValueError('Expected utc offset, got: %s' % ical)
raise ValueError(f'Expected utc offset, got: {ical}')
if not cls.ignore_exceptions and offset >= timedelta(hours=24):
raise ValueError(
'Offset must be less than 24 hours, was %s' % ical)
f'Offset must be less than 24 hours, was {ical}')
if sign == '-':
return -offset
return offset