Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34k
GH-70647: Deprecate strptime day of month parsing without a year present to avoid leap-year bugs#117107
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 our terms of service and privacy 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.
GH-70647: Deprecate strptime day of month parsing without a year present to avoid leap-year bugs #117107
Changes from all commits
4b929e4b0eacf95851b0ba068dac333ba57b12e7e5d4c994e92e30b8f1bd314File 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 |
|---|---|---|
| @@ -10,6 +10,7 @@ | ||
| strptime -- Calculates the time struct represented by the passed-in string | ||
| """ | ||
| import os | ||
| import time | ||
| import locale | ||
| import calendar | ||
| @@ -250,12 +251,30 @@ def pattern(self, format): | ||
| format = regex_chars.sub(r"\\\1", format) | ||
| whitespace_replacement = re_compile(r'\s+') | ||
| format = whitespace_replacement.sub(r'\\s+', format) | ||
| year_in_format = False | ||
| day_of_month_in_format = False | ||
| while '%' in format: | ||
| directive_index = format.index('%')+1 | ||
| format_char = format[directive_index] | ||
| processed_format = "%s%s%s" % (processed_format, | ||
| format[:directive_index-1], | ||
| self[format[directive_index]]) | ||
| self[format_char]) | ||
| format = format[directive_index+1:] | ||
| match format_char: | ||
| case 'Y' | 'y' | 'G': | ||
| year_in_format = True | ||
| case 'd': | ||
| day_of_month_in_format = True | ||
| if day_of_month_in_format and not year_in_format: | ||
MemberAuthor
| ||
| import warnings | ||
| warnings.warn("""\ | ||
| Parsing dates involving a day of month without a year specified is ambiguious | ||
| and fails to parse leap day. The default behavior will change in Python 3.15 | ||
| to either always raise an exception or to use a different default year (TBD). | ||
| To avoid trouble, add a specific year to the input & format. | ||
| See https://github.com/python/cpython/issues/70647.""", | ||
| DeprecationWarning, | ||
| skip_file_prefixes=(os.path.dirname(__file__),)) | ||
| return "%s%s" % (processed_format, format) | ||
| def compile(self, format): | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| Start the deprecation period for the current behavior of | ||
| :func:`datetime.datetime.strptime` and :func:`time.strptime` which always | ||
| fails to parse a date string with a :exc:`ValueError` involving a day of | ||
| month such as ``strptime("02-29", "%m-%d")`` when a year is **not** | ||
| specified and the date happen to be February 29th. This should help avoid | ||
| users finding new bugs every four years due to a natural mistaken assumption | ||
| about the API when parsing partial date values. |
Uh oh!
There was an error while loading. Please reload this page.