Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32k
gh-109798: Normalize_datetime
anddatetime
error messages#127345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
764eb1b
2bf419f
4363e9e
9da0dfc
179423d
f691251
d8973cf
5eea62f
79543cc
d174497
498c4ba
216d0fe
c409fec
3f454f6
a2b8f7a
209c338
0777aa5
4d31d33
f05ebba
f840105
61c95a5
2ab77b3
b1e272a
7a35bd4
cfd18cb
2827514
cd3bdc1
9915dfe
1da5a3a
610f067
410e0ce
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -60,14 +60,14 @@ def _days_in_month(year, month): | ||
def _days_before_month(year, month): | ||
"year, month -> number of days in year preceding first day of month." | ||
assert 1 <= month <= 12,f"month must be in 1..12, not {month}" | ||
return _DAYS_BEFORE_MONTH[month] + (month > 2 and _is_leap(year)) | ||
def _ymd2ord(year, month, day): | ||
"year, month, day -> ordinal, considering 01-Jan-0001 as day 1." | ||
assert 1 <= month <= 12,f"month must be in 1..12, not {month}" | ||
dim = _days_in_month(year, month) | ||
assert 1 <= day <= dim,f"day must be in 1..{dim}, not {day}" | ||
return (_days_before_year(year) + | ||
_days_before_month(year, month) + | ||
day) | ||
@@ -512,7 +512,7 @@ def _parse_isoformat_time(tstr): | ||
def _isoweek_to_gregorian(year, week, day): | ||
# Year is bounded this way because 9999-12-31 is (9999, 52, 5) | ||
if not MINYEAR <= year <= MAXYEAR: | ||
raise ValueError(f"year must be in {MINYEAR}..{MAXYEAR}, not {year}") | ||
if not 0 < week < 53: | ||
out_of_range = True | ||
@@ -545,7 +545,7 @@ def _isoweek_to_gregorian(year, week, day): | ||
def _check_tzname(name): | ||
if name is not None and not isinstance(name, str): | ||
raise TypeError("tzinfo.tzname() must return None or string, " | ||
f"not{type(name).__name__!r}") | ||
# name is the offset-producing method, "utcoffset" or "dst". | ||
# offset is what it returned. | ||
@@ -558,24 +558,24 @@ def _check_utc_offset(name, offset): | ||
if offset is None: | ||
return | ||
if not isinstance(offset, timedelta): | ||
raise TypeError(f"tzinfo.{name}() must return None " | ||
f"or timedelta, not{type(offset).__name__!r}") | ||
if not -timedelta(1) < offset < timedelta(1): | ||
raise ValueError("offset must bea timedelta " | ||
"strictly between-timedelta(hours=24) and" | ||
f"timedelta(hours=24), not {offset!r}") | ||
def _check_date_fields(year, month, day): | ||
year = _index(year) | ||
month = _index(month) | ||
day = _index(day) | ||
if not MINYEAR <= year <= MAXYEAR: | ||
raise ValueError(f"year must be in{MINYEAR}..{MAXYEAR}, not {year}") | ||
if not 1 <= month <= 12: | ||
raise ValueError(f"month must be in 1..12, not {month}") | ||
dim = _days_in_month(year, month) | ||
if not 1 <= day <= dim: | ||
raise ValueError(f"day must be in 1..{dim}, not {day}") | ||
return year, month, day | ||
def _check_time_fields(hour, minute, second, microsecond, fold): | ||
@@ -584,20 +584,23 @@ def _check_time_fields(hour, minute, second, microsecond, fold): | ||
second = _index(second) | ||
microsecond = _index(microsecond) | ||
if not 0 <= hour <= 23: | ||
raise ValueError(f"hour must be in 0..23, not {hour}") | ||
if not 0 <= minute <= 59: | ||
raise ValueError(f"minute must be in 0..59, not {minute}") | ||
if not 0 <= second <= 59: | ||
raise ValueError(f"second must be in 0..59, not {second}") | ||
if not 0 <= microsecond <= 999999: | ||
raise ValueError(f"microsecond must be in 0..999999, not {microsecond}") | ||
if fold not in (0, 1): | ||
raise ValueError(f"fold must be either 0 or 1, not {fold}") | ||
return hour, minute, second, microsecond, fold | ||
def _check_tzinfo_arg(tz): | ||
if tz is not None and not isinstance(tz, tzinfo): | ||
raise TypeError( | ||
"tzinfo argument must be None or of a tzinfo subclass, " | ||
f"not {type(tz).__name__!r}" | ||
) | ||
def _divide_and_round(a, b): | ||
"""divide a by b and round result to the nearest integer | ||
@@ -2418,7 +2421,7 @@ def __new__(cls, offset, name=_Omitted): | ||
if not cls._minoffset <= offset <= cls._maxoffset: | ||
raise ValueError("offset must be a timedelta " | ||
"strictly between -timedelta(hours=24) and " | ||
f"timedelta(hours=24), not {offset!r}") | ||
donBarbos marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Probably not going to be a great user experience here because of how bad the >>>print(f"{timedelta(hours=-25)!r}")datetime.timedelta(days=-2,seconds=82800) Maybe it will be clearer if we do it this way: ifoffset<timedelta(0):offset_str=f"-{-offset)}"else:offset_str=str(offset) That will print stuff like Probably a more elaborate timedelta formatter would be better, since we basically always want this in ContributorAuthor
| ||
return cls._create(offset, name) | ||
def __init_subclass__(cls): | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Added additional information into error messages in :mod:`datetime`, and made the messages more consistent between the C and Python implementations. Patch by Semyon Moroz. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -637,17 +637,19 @@ check_date_args(int year, int month, int day) | ||
{ | ||
if (year < MINYEAR || year > MAXYEAR) { | ||
PyErr_Format(PyExc_ValueError, | ||
"year must be in %d..%d, not %d", MINYEAR, MAXYEAR, year); | ||
return -1; | ||
} | ||
if (month < 1 || month > 12) { | ||
PyErr_Format(PyExc_ValueError, | ||
"month must be in 1..12, not %d", month); | ||
return -1; | ||
} | ||
int dim = days_in_month(year, month); | ||
if (day < 1 || day > dim) { | ||
erlend-aasland marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
PyErr_Format(PyExc_ValueError, | ||
"day must be in 1..%d, not %d", dim, day); | ||
return -1; | ||
} | ||
return 0; | ||
@@ -660,28 +662,25 @@ static int | ||
check_time_args(int h, int m, int s, int us, int fold) | ||
{ | ||
if (h < 0 || h > 23) { | ||
PyErr_Format(PyExc_ValueError, "hour must be in 0..23, not %i", h); | ||
return -1; | ||
} | ||
if (m < 0 || m > 59) { | ||
PyErr_Format(PyExc_ValueError, "minute must be in 0..59, not %i", m); | ||
return -1; | ||
} | ||
if (s < 0 || s > 59) { | ||
PyErr_Format(PyExc_ValueError, "second must be in 0..59, not %i", s); | ||
return -1; | ||
} | ||
if (us < 0 || us > 999999) { | ||
PyErr_Format(PyExc_ValueError, | ||
"microsecond must be in 0..999999, not %i", us); | ||
return -1; | ||
} | ||
if (fold != 0 && fold != 1) { | ||
PyErr_Format(PyExc_ValueError, | ||
"fold must be either 0 or 1, not %i", fold); | ||
return -1; | ||
} | ||
return 0; | ||
@@ -1435,8 +1434,7 @@ new_timezone(PyObject *offset, PyObject *name) | ||
GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { | ||
PyErr_Format(PyExc_ValueError, "offset must be a timedelta" | ||
" strictly between -timedelta(hours=24) and" | ||
erlend-aasland marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
" timedelta(hours=24), not %R", offset); | ||
return NULL; | ||
} | ||
@@ -1505,10 +1503,10 @@ call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg) | ||
GET_TD_SECONDS(offset) == 0 && | ||
GET_TD_MICROSECONDS(offset) < 1) || | ||
GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { | ||
PyErr_Format(PyExc_ValueError, "offset must be a timedelta" | ||
" strictly between -timedelta(hours=24) and" | ||
" timedelta(hours=24), not %R", offset); | ||
Py_DECREF(offset); | ||
erlend-aasland marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
return NULL; | ||
} | ||
} | ||
@@ -2261,7 +2259,7 @@ get_float_as_integer_ratio(PyObject *floatobj) | ||
if (!PyTuple_Check(ratio)) { | ||
PyErr_Format(PyExc_TypeError, | ||
"unexpected return type from as_integer_ratio(): " | ||
"expected tuple,not '%.200s'", | ||
Py_TYPE(ratio)->tp_name); | ||
Py_DECREF(ratio); | ||
return NULL; | ||
@@ -3382,7 +3380,8 @@ date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw) | ||
int rv = iso_to_ymd(year, week, day, &year, &month, &day); | ||
if (rv == -4) { | ||
PyErr_Format(PyExc_ValueError, | ||
"year must be in %d..%d, not %d", MINYEAR, MAXYEAR, year); | ||
return NULL; | ||
} | ||
@@ -3392,7 +3391,7 @@ date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw) | ||
} | ||
if (rv == -3) { | ||
PyErr_Format(PyExc_ValueError, "Invalidweekday: %d (range is [1, 7])", | ||
donBarbos marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
day); | ||
return NULL; | ||
} | ||
@@ -4378,8 +4377,7 @@ timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt) | ||
return NULL; | ||
} | ||
if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) { | ||
PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo is not self"); | ||
return NULL; | ||
} | ||
@@ -5352,7 +5350,8 @@ utc_to_seconds(int year, int month, int day, | ||
/* ymd_to_ord() doesn't support year <= 0 */ | ||
if (year < MINYEAR || year > MAXYEAR) { | ||
PyErr_Format(PyExc_ValueError, | ||
"year must be in %d..%d, not %d", MINYEAR, MAXYEAR, year); | ||
return -1; | ||
} | ||
Uh oh!
There was an error while loading.Please reload this page.