Skip to content
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

bpo-43295: Fix error handling of datetime.strptime format string '%z' #24627

Merged
merged 6 commits into from Mar 3, 2021

Conversation

@noormichael
Copy link
Contributor

@noormichael noormichael commented Feb 23, 2021

Previously, datetime.strptime would match 'z' with the format string '%z' (for UTC offsets), throwing an IndexError by erroneously trying to parse 'z' as a timestamp. As a special case, '%z' matches the string 'Z' which is equivalent to the offset '+00:00', however this behavior is not defined for lowercase 'z'.

This change ensures a ValueError is thrown when encountering the original example, as follows:

>>> from datetime import datetime
>>> datetime.strptime('z', '%z')
ValueError: time data 'z' does not match format '%z'

https://bugs.python.org/issue43295

Automerge-Triggered-By: GH:pganssle

@the-knights-who-say-ni
Copy link

@the-knights-who-say-ni the-knights-who-say-ni commented Feb 23, 2021

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept this contribution by verifying everyone involved has signed the PSF contributor agreement (CLA).

CLA Missing

Our records indicate the following people have not signed the CLA:

@noormichael

For legal reasons we need all the people listed to sign the CLA before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue.

If you have recently signed the CLA, please wait at least one business day
before our records are updated.

You can check yourself to see if the CLA has been received.

Thanks again for the contribution, we look forward to reviewing it!

Copy link
Member

@pganssle pganssle left a comment

Thanks for the quick fix on this! Just a few minor changes.

def test_timezone_offset_cannot_parse_z(self):
# Check ValueError is raised when matching "z" (ordinary letter)
# with "%z" (timezone offset)
self.assertRaises(ValueError, _strptime._strptime_time, "z", "%z")
Copy link
Member

@pganssle pganssle Feb 26, 2021

Two things here:

  1. I much prefer the context manager version of assertRaises, since it's much clearer what calls are being tested.
  2. It would be preferable to test this using only the public interface. I realize that there are other uses of _strptime._strptime_time in this file, but going forward I'd like to keep the tests focused on the public interface, so can you try and exercise this using time.strptime and/or datetime.strptime?

@@ -0,0 +1,10 @@
Previously, datetime.strptime would match 'z' with the format string '%z'
Copy link
Member

@pganssle pganssle Feb 26, 2021

This is a very good summary of the issue, but it is long for a news stub. They're usually 1 or two lines like this: https://docs.python.org/3/whatsnew/changelog.html

How about:

Previously, :meth:`datetime.datetime.strptime` would fail with `IndexError` when the string `'z'`
was found for the `%z` format specifier. This has been fixed to properly raise `ValueError` instead.

(You'll want to check to make sure that the :meth: directive works correctly, I may have made a mistake with that.
A BPO link is automatically generated, and users who want more information can click on it for an MWE and such.

@bedevere-bot
Copy link

@bedevere-bot bedevere-bot commented Feb 26, 2021

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@noormichael
Copy link
Contributor Author

@noormichael noormichael commented Mar 3, 2021

Is there a way to re-run the tests? test_ssl failed on Ubuntu which has passed on previous runs. In any case, I've made the requested changes. Could you please review this again?

Copy link
Member

@pganssle pganssle left a comment

@noormichael No need to worry about that. I believe this is something to do with github upgrading the default Ubuntu container from 18.04 to 20.04 and some patch in Ubuntu that breaks OpenSSL. See this bug for more details.

I believe no further action on your part is necessary, this looks good and we can probably wait until that bug is resolved to merge so that backports will go more easily. Thanks for your contribution to CPython!

@miss-islington
Copy link
Contributor

@miss-islington miss-islington commented Mar 3, 2021

@noormichael: Status check is done, and it's a success .

@miss-islington miss-islington merged commit 04f6fbb into python:master Mar 3, 2021
11 checks passed
@miss-islington
Copy link
Contributor

@miss-islington miss-islington commented Mar 3, 2021

Thanks @noormichael for the PR 🌮🎉.. I'm working now to backport this PR to: 3.8, 3.9.
🐍🍒🤖

@bedevere-bot
Copy link

@bedevere-bot bedevere-bot commented Mar 3, 2021

GH-24728 is a backport of this pull request to the 3.9 branch.

miss-islington added a commit to miss-islington/cpython that referenced this issue Mar 3, 2021
…pythonGH-24627)

Previously, `datetime.strptime` would match `'z'` with the format string `'%z'` (for UTC offsets), throwing an `IndexError` by erroneously trying to parse `'z'` as a timestamp. As a special case, `'%z'` matches the string `'Z'` which is equivalent to the offset `'+00:00'`, however this behavior is not defined for lowercase `'z'`.

This change ensures a `ValueError` is thrown when encountering the original example, as follows:

```
>>> from datetime import datetime
>>> datetime.strptime('z', '%z')
ValueError: time data 'z' does not match format '%z'
```

Automerge-Triggered-By: GH:pganssle
(cherry picked from commit 04f6fbb)

Co-authored-by: Noor Michael <nsmichael31@gmail.com>
@bedevere-bot
Copy link

@bedevere-bot bedevere-bot commented Mar 3, 2021

GH-24729 is a backport of this pull request to the 3.8 branch.

miss-islington added a commit to miss-islington/cpython that referenced this issue Mar 3, 2021
…pythonGH-24627)

Previously, `datetime.strptime` would match `'z'` with the format string `'%z'` (for UTC offsets), throwing an `IndexError` by erroneously trying to parse `'z'` as a timestamp. As a special case, `'%z'` matches the string `'Z'` which is equivalent to the offset `'+00:00'`, however this behavior is not defined for lowercase `'z'`.

This change ensures a `ValueError` is thrown when encountering the original example, as follows:

```
>>> from datetime import datetime
>>> datetime.strptime('z', '%z')
ValueError: time data 'z' does not match format '%z'
```

Automerge-Triggered-By: GH:pganssle
(cherry picked from commit 04f6fbb)

Co-authored-by: Noor Michael <nsmichael31@gmail.com>
@Immorningstar
Copy link

@Immorningstar Immorningstar commented Mar 3, 2021

gvanrossum added a commit to gvanrossum/cpython that referenced this issue Mar 10, 2021
…pythonGH-24627)

Previously, `datetime.strptime` would match `'z'` with the format string `'%z'` (for UTC offsets), throwing an `IndexError` by erroneously trying to parse `'z'` as a timestamp. As a special case, `'%z'` matches the string `'Z'` which is equivalent to the offset `'+00:00'`, however this behavior is not defined for lowercase `'z'`.

This change ensures a `ValueError` is thrown when encountering the original example, as follows:

```
>>> from datetime import datetime
>>> datetime.strptime('z', '%z')
ValueError: time data 'z' does not match format '%z'
```

Automerge-Triggered-By: GH:pganssle
@miss-islington
Copy link
Contributor

@miss-islington miss-islington commented Apr 28, 2021

Thanks @noormichael for the PR 🌮🎉.. I'm working now to backport this PR to: 3.9.
🐍🍒🤖

@bedevere-bot
Copy link

@bedevere-bot bedevere-bot commented Apr 28, 2021

GH-25695 is a backport of this pull request to the 3.9 branch.

miss-islington added a commit to miss-islington/cpython that referenced this issue Apr 28, 2021
…pythonGH-24627)

Previously, `datetime.strptime` would match `'z'` with the format string `'%z'` (for UTC offsets), throwing an `IndexError` by erroneously trying to parse `'z'` as a timestamp. As a special case, `'%z'` matches the string `'Z'` which is equivalent to the offset `'+00:00'`, however this behavior is not defined for lowercase `'z'`.

This change ensures a `ValueError` is thrown when encountering the original example, as follows:

```
>>> from datetime import datetime
>>> datetime.strptime('z', '%z')
ValueError: time data 'z' does not match format '%z'
```

Automerge-Triggered-By: GH:pganssle
(cherry picked from commit 04f6fbb)

Co-authored-by: Noor Michael <nsmichael31@gmail.com>
kreathon added a commit to kreathon/cpython that referenced this issue May 2, 2021
…pythonGH-24627)

Previously, `datetime.strptime` would match `'z'` with the format string `'%z'` (for UTC offsets), throwing an `IndexError` by erroneously trying to parse `'z'` as a timestamp. As a special case, `'%z'` matches the string `'Z'` which is equivalent to the offset `'+00:00'`, however this behavior is not defined for lowercase `'z'`.

This change ensures a `ValueError` is thrown when encountering the original example, as follows:

```
>>> from datetime import datetime
>>> datetime.strptime('z', '%z')
ValueError: time data 'z' does not match format '%z'
```

Automerge-Triggered-By: GH:pganssle
pganssle pushed a commit that referenced this issue May 20, 2021
…GH-24627) (#25695)

Previously, `datetime.strptime` would match `'z'` with the format string `'%z'` (for UTC offsets), throwing an `IndexError` by erroneously trying to parse `'z'` as a timestamp. As a special case, `'%z'` matches the string `'Z'` which is equivalent to the offset `'+00:00'`, however this behavior is not defined for lowercase `'z'`.

This change ensures a `ValueError` is thrown when encountering the original example, as follows:

```
>>> from datetime import datetime
>>> datetime.strptime('z', '%z')
ValueError: time data 'z' does not match format '%z'
```

Automerge-Triggered-By: GH:pganssle
(cherry picked from commit 04f6fbb)

Co-authored-by: Noor Michael <nsmichael31@gmail.com>

Co-authored-by: Noor Michael <nsmichael31@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
9 participants