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

datetime.fromisoformat() accepts invalid ISO 8601 timestamps #115783

Open
Paebbels opened this issue Feb 21, 2024 · 6 comments
Open

datetime.fromisoformat() accepts invalid ISO 8601 timestamps #115783

Paebbels opened this issue Feb 21, 2024 · 6 comments
Labels
extension-modules C modules in the Modules dir stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@Paebbels
Copy link

Paebbels commented Feb 21, 2024

Bug report

Bug description:

Since Python 3.11, datetime.fromisoformat(...) accepts invalid timestamps. The same code was tested in many Python versions via GitHub Actions:

Wrong format: 2024-01-17T15:21:00-0800
Fixed format: 2024-01-17T15:21:00-08:00

Python code to check:

datetime.fromisoformat("2024-01-17T15:21:00-0800")

ISO 8601 defines 2 formats:

  • basic format (in short: without separators) and
  • extended format (with separators).

When checking the EBNF rules, all parts of the timestamp must be with or without separators. A mix of formats is not allowed.

I haven't checked for other basic and extended format mixes.
My CI checked many Python versions and platforms. Here a failed CI pipeline, shows a correct implementation. A successful pipeline denotes a buggy Python version.
image

Other resources:

CPython versions tested on:

3.8, 3.9, 3.10, 3.11, 3.12, 3.13

Operating systems tested on:

Linux, macOS, Windows

Linked PRs

@skoehler
Copy link

skoehler commented Feb 23, 2024

I'd like to extend the list of accepted invalid timestamps:

2024-01-17T15:21:00-0800
2024-01-17T152100-08:00
20240117T15:21:00-08:00

2024-01-17T152100-0800
20240117T15:21:00-0800
20240117T152100-08:00

All these should be rejected by fromisoformat().
I can report however, that removing just a single dash or a single colon from the date or time is properly rejected.

@TooPercentMilk
Copy link

I'm a beginner contributor and I'd like to work on this issue. How can I move forward?

@maxcyd
Copy link

maxcyd commented Apr 26, 2024

It is worth noting, the test_datetime defined within datetimetester.py test assumes inconsistent typing is acceptable. For example, '20250102T03:04:05,6' is considered an acceptable string to the datetime.isoformat() function.

@StanFromIreland
Copy link
Contributor

StanFromIreland commented Mar 18, 2025

We have been accepting several "wrong" formats for a while (inconstent expanding, though we check a few cases; missing separator; separator other than ["T"] etc.)... This will require deprecation if we even wish to implement it.

test_fromisoformat_datetime_examples cases that fail with a patch that restricts it to only proper ISO 8601 expandedstrings:

It's a long list... (Not including other "wrong" cases)

('2025-01-02T0304', self.theclass(2025, 1, 2, 3, 4)),

('2025-01-02T030405', self.theclass(2025, 1, 2, 3, 4, 5)),

('2025-01-02T03:05:06+0300',

('2025-01-02T03:05:06-0300',

('2025-01-02T03:04:05+0000',

('2020-01-01T03:05:07.123457-0500',

('2020-06-01T04:05:06.111111-0400',

('2021-10-31T01:30:00.000000+0100',

('2025-01-02T03:04:05,6+000000.00',

Seeing as we seem to have been accepting these for so long and we even consider them valid in our tests I think this should be considered a feature request rather than a bug. I guess the decision is up to @pganssle, do you think we should restrict the function? I am happy to implement it.

@picnixz picnixz added stdlib Python modules in the Lib dir extension-modules C modules in the Modules dir labels Mar 18, 2025
@pganssle
Copy link
Member

The current documented scope of fromisoformat is that it should parse the union of all valid ISO8601 strings and all possible outputs of datetime.isoformat, so I would consider anything outside of that as a bug, even if we included it in our test suite because we misunderstood the spec. If we were to change it, I wouldn't recommend doing it in a bugfix release, however.

The options we have going forward are to document further extensions we support (i.e. mixed and matched separators), issue a deprecation cycle for invalid formats or just go ahead and break this.

Despite the fact that we have been supporting this for a while, I would be surprised if it is in particularly widespread use unless there is something out there generating these formats by default. They don't seem like the kind of format that you would choose to generate, unless maybe you are storing your strings in a place that can't accept : but can accept - or vice versa?

In any case, deprecation is probably the safest option. The argument for being strict is that you are supposed to be able to use fromisoformat for some kind of validation, and I've known people who use it that way. If we start emitting a warning, people can set the warning handler to error if they want that, or they can manipulate their strings. Of course, the down side is that people find deprecation warnings extremely annoying and tons of people don't bother handling them and they get passed on to end users who don't know what they mean, so it's not free to do that.

@StanFromIreland
Copy link
Contributor

In any case, deprecation is probably the safest option.

I agree.

you are supposed to be able to use fromisoformat for some kind of validation

It should also do what is in the name ;-) isoformat, not anyrandomformat

If we start emitting a warning, people can set the warning handler to error if they want that, or they can manipulate their strings.

We should do this. I can assign myself to this, I also propose extending the docs to be more specific and up to date with 8601:2

people find deprecation warnings extremely annoying and tons of people don't bother handling them and they get passed on to end users

Is this really that common an occurrence? They are warnings and not errors, most people do not check warnings. They will bother when it is no longer deprecated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extension-modules C modules in the Modules dir stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
Development

No branches or pull requests

7 participants