mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge pull request #5169 from Blues-star/main
Update `calendar.py` and `test_calendar.py` from CPython v3.12
This commit is contained in:
76
Lib/calendar.py
vendored
76
Lib/calendar.py
vendored
@@ -7,8 +7,10 @@ set the first day of the week (0=Monday, 6=Sunday)."""
|
||||
|
||||
import sys
|
||||
import datetime
|
||||
from enum import IntEnum, global_enum
|
||||
import locale as _locale
|
||||
from itertools import repeat
|
||||
import warnings
|
||||
|
||||
__all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday",
|
||||
"firstweekday", "isleap", "leapdays", "weekday", "monthrange",
|
||||
@@ -16,6 +18,9 @@ __all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday",
|
||||
"timegm", "month_name", "month_abbr", "day_name", "day_abbr",
|
||||
"Calendar", "TextCalendar", "HTMLCalendar", "LocaleTextCalendar",
|
||||
"LocaleHTMLCalendar", "weekheader",
|
||||
"Day", "Month", "JANUARY", "FEBRUARY", "MARCH",
|
||||
"APRIL", "MAY", "JUNE", "JULY",
|
||||
"AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
|
||||
"MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY",
|
||||
"SATURDAY", "SUNDAY"]
|
||||
|
||||
@@ -37,9 +42,46 @@ class IllegalWeekdayError(ValueError):
|
||||
return "bad weekday number %r; must be 0 (Monday) to 6 (Sunday)" % self.weekday
|
||||
|
||||
|
||||
# Constants for months referenced later
|
||||
January = 1
|
||||
February = 2
|
||||
def __getattr__(name):
|
||||
if name in ('January', 'February'):
|
||||
warnings.warn(f"The '{name}' attribute is deprecated, use '{name.upper()}' instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
if name == 'January':
|
||||
return 1
|
||||
else:
|
||||
return 2
|
||||
|
||||
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
||||
|
||||
|
||||
# Constants for months
|
||||
@global_enum
|
||||
class Month(IntEnum):
|
||||
JANUARY = 1
|
||||
FEBRUARY = 2
|
||||
MARCH = 3
|
||||
APRIL = 4
|
||||
MAY = 5
|
||||
JUNE = 6
|
||||
JULY = 7
|
||||
AUGUST = 8
|
||||
SEPTEMBER = 9
|
||||
OCTOBER = 10
|
||||
NOVEMBER = 11
|
||||
DECEMBER = 12
|
||||
|
||||
|
||||
# Constants for days
|
||||
@global_enum
|
||||
class Day(IntEnum):
|
||||
MONDAY = 0
|
||||
TUESDAY = 1
|
||||
WEDNESDAY = 2
|
||||
THURSDAY = 3
|
||||
FRIDAY = 4
|
||||
SATURDAY = 5
|
||||
SUNDAY = 6
|
||||
|
||||
|
||||
# Number of days per month (except for February in leap years)
|
||||
mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
||||
@@ -95,9 +137,6 @@ day_abbr = _localized_day('%a')
|
||||
month_name = _localized_month('%B')
|
||||
month_abbr = _localized_month('%b')
|
||||
|
||||
# Constants for weekdays
|
||||
(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7)
|
||||
|
||||
|
||||
def isleap(year):
|
||||
"""Return True for leap years, False for non-leap years."""
|
||||
@@ -116,7 +155,7 @@ def weekday(year, month, day):
|
||||
"""Return weekday (0-6 ~ Mon-Sun) for year, month (1-12), day (1-31)."""
|
||||
if not datetime.MINYEAR <= year <= datetime.MAXYEAR:
|
||||
year = 2000 + year % 400
|
||||
return datetime.date(year, month, day).weekday()
|
||||
return Day(datetime.date(year, month, day).weekday())
|
||||
|
||||
|
||||
def monthrange(year, month):
|
||||
@@ -125,12 +164,12 @@ def monthrange(year, month):
|
||||
if not 1 <= month <= 12:
|
||||
raise IllegalMonthError(month)
|
||||
day1 = weekday(year, month, 1)
|
||||
ndays = mdays[month] + (month == February and isleap(year))
|
||||
ndays = mdays[month] + (month == FEBRUARY and isleap(year))
|
||||
return day1, ndays
|
||||
|
||||
|
||||
def _monthlen(year, month):
|
||||
return mdays[month] + (month == February and isleap(year))
|
||||
return mdays[month] + (month == FEBRUARY and isleap(year))
|
||||
|
||||
|
||||
def _prevmonth(year, month):
|
||||
@@ -260,10 +299,7 @@ class Calendar(object):
|
||||
Each month contains between 4 and 6 weeks and each week contains 1-7
|
||||
days. Days are datetime.date objects.
|
||||
"""
|
||||
months = [
|
||||
self.monthdatescalendar(year, i)
|
||||
for i in range(January, January+12)
|
||||
]
|
||||
months = [self.monthdatescalendar(year, m) for m in Month]
|
||||
return [months[i:i+width] for i in range(0, len(months), width) ]
|
||||
|
||||
def yeardays2calendar(self, year, width=3):
|
||||
@@ -273,10 +309,7 @@ class Calendar(object):
|
||||
(day number, weekday number) tuples. Day numbers outside this month are
|
||||
zero.
|
||||
"""
|
||||
months = [
|
||||
self.monthdays2calendar(year, i)
|
||||
for i in range(January, January+12)
|
||||
]
|
||||
months = [self.monthdays2calendar(year, m) for m in Month]
|
||||
return [months[i:i+width] for i in range(0, len(months), width) ]
|
||||
|
||||
def yeardayscalendar(self, year, width=3):
|
||||
@@ -285,10 +318,7 @@ class Calendar(object):
|
||||
yeardatescalendar()). Entries in the week lists are day numbers.
|
||||
Day numbers outside this month are zero.
|
||||
"""
|
||||
months = [
|
||||
self.monthdayscalendar(year, i)
|
||||
for i in range(January, January+12)
|
||||
]
|
||||
months = [self.monthdayscalendar(year, m) for m in Month]
|
||||
return [months[i:i+width] for i in range(0, len(months), width) ]
|
||||
|
||||
|
||||
@@ -509,7 +539,7 @@ class HTMLCalendar(Calendar):
|
||||
a('\n')
|
||||
a('<tr><th colspan="%d" class="%s">%s</th></tr>' % (
|
||||
width, self.cssclass_year_head, theyear))
|
||||
for i in range(January, January+12, width):
|
||||
for i in range(JANUARY, JANUARY+12, width):
|
||||
# months in this row
|
||||
months = range(i, min(i+width, 13))
|
||||
a('<tr>')
|
||||
@@ -693,7 +723,7 @@ def main(args):
|
||||
parser.add_argument(
|
||||
"-L", "--locale",
|
||||
default=None,
|
||||
help="locale to be used from month and weekday names"
|
||||
help="locale to use for month and weekday names"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-e", "--encoding",
|
||||
|
||||
19
Lib/test/test_calendar.py
vendored
19
Lib/test/test_calendar.py
vendored
@@ -8,6 +8,7 @@ import locale
|
||||
import sys
|
||||
import datetime
|
||||
import os
|
||||
import warnings
|
||||
|
||||
# From https://en.wikipedia.org/wiki/Leap_year_starting_on_Saturday
|
||||
result_0_02_text = """\
|
||||
@@ -490,6 +491,14 @@ class OutputTestCase(unittest.TestCase):
|
||||
self.assertEqual(out.getvalue().strip(), "1 2 3")
|
||||
|
||||
class CalendarTestCase(unittest.TestCase):
|
||||
|
||||
def test_deprecation_warning(self):
|
||||
with self.assertWarnsRegex(
|
||||
DeprecationWarning,
|
||||
"The 'January' attribute is deprecated, use 'JANUARY' instead"
|
||||
):
|
||||
calendar.January
|
||||
|
||||
def test_isleap(self):
|
||||
# Make sure that the return is right for a few years, and
|
||||
# ensure that the return values are 1 or 0, not just true or
|
||||
@@ -568,11 +577,15 @@ class CalendarTestCase(unittest.TestCase):
|
||||
try:
|
||||
# formatweekday uses different day names based on the available width.
|
||||
cal = calendar.LocaleTextCalendar(locale='en_US')
|
||||
# For short widths, a centered, abbreviated name is used.
|
||||
self.assertEqual(cal.formatweekday(0, 5), " Mon ")
|
||||
# For really short widths, even the abbreviated name is truncated.
|
||||
# For really short widths, the abbreviated name is truncated.
|
||||
self.assertEqual(cal.formatweekday(0, 1), "M")
|
||||
self.assertEqual(cal.formatweekday(0, 2), "Mo")
|
||||
# For short widths, a centered, abbreviated name is used.
|
||||
self.assertEqual(cal.formatweekday(0, 3), "Mon")
|
||||
self.assertEqual(cal.formatweekday(0, 5), " Mon ")
|
||||
self.assertEqual(cal.formatweekday(0, 8), " Mon ")
|
||||
# For long widths, the full day name is used.
|
||||
self.assertEqual(cal.formatweekday(0, 9), " Monday ")
|
||||
self.assertEqual(cal.formatweekday(0, 10), " Monday ")
|
||||
except locale.Error:
|
||||
raise unittest.SkipTest('cannot set the en_US locale')
|
||||
|
||||
Reference in New Issue
Block a user