Issue #28253: Fixed calendar functions for extreme months: 0001-01 and 9999-12.

Methods itermonthdays() and itermonthdays2() are reimplemented so that they
don't call itermonthdates() which can cause datetime.date under/overflow.
This commit is contained in:
Alexander Belopolsky 2016-09-27 22:45:20 -04:00
parent 36beb5ec13
commit 8cab419624
3 changed files with 39 additions and 10 deletions

View File

@ -174,22 +174,23 @@ class Calendar(object):
Like itermonthdates(), but will yield (day number, weekday number)
tuples. For days outside the specified month the day number is 0.
"""
for date in self.itermonthdates(year, month):
if date.month != month:
yield (0, date.weekday())
else:
yield (date.day, date.weekday())
for i, d in enumerate(self.itermonthdays(year, month), self.firstweekday):
yield d, i % 7
def itermonthdays(self, year, month):
"""
Like itermonthdates(), but will yield day numbers. For days outside
the specified month the day number is 0.
"""
for date in self.itermonthdates(year, month):
if date.month != month:
yield 0
else:
yield date.day
day1, ndays = monthrange(year, month)
days_before = (day1 - self.firstweekday) % 7
for _ in range(days_before):
yield 0
for d in range(1, ndays + 1):
yield d
days_after = (self.firstweekday - day1 - ndays) % 7
for _ in range(days_after):
yield 0
def monthdatescalendar(self, year, month):
"""

View File

@ -291,6 +291,27 @@ class CalendarTestCase(unittest.TestCase):
# see #15421
list(calendar.Calendar().itermonthdates(datetime.MAXYEAR, 12))
def test_itermonthdays(self):
for firstweekday in range(7):
cal = calendar.Calendar(firstweekday)
# Test the extremes, see #28253 and #26650
for y, m in [(1, 1), (9999, 12)]:
days = list(cal.itermonthdays(y, m))
self.assertIn(len(days), (35, 42))
# Test a short month
cal = calendar.Calendar(firstweekday=3)
days = list(cal.itermonthdays(2001, 2))
self.assertEqual(days, list(range(1, 29)))
def test_itermonthdays2(self):
for firstweekday in range(7):
cal = calendar.Calendar(firstweekday)
# Test the extremes, see #28253 and #26650
for y, m in [(1, 1), (9999, 12)]:
days = list(cal.itermonthdays2(y, m))
self.assertEqual(days[0][1], firstweekday)
self.assertEqual(days[-1][1], (firstweekday - 1) % 7)
class MonthCalendarTestCase(unittest.TestCase):
def setUp(self):

View File

@ -42,6 +42,13 @@ Core and Builtins
Library
-------
- Issue #28253: Fixed calendar functions for extreme months: 0001-01
and 9999-12.
Methods itermonthdays() and itermonthdays2() are reimplemented so
that they don't call itermonthdates() which can cause datetime.date
under/overflow.
- Issue #27963: Fixed possible null pointer dereference in
ctypes.set_conversion_mode(). Patch by Xiang Zhang.