Skip to content

Conversation

@jbrockmendel
Copy link
Contributor

Will evidently need rebasing after review.

@pganssle
Copy link
Member

LGTM.

@pganssle pganssle added this to the 2.7.0 milestone Oct 27, 2017
return 1 <= value <= 31
elif not self.has_year:
# Be permissive, assume leapyear
return 1 <= value <= monthrange(2000, self.month)[1]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird choice of an exemplary leap year, since this is one of the weird leap years.

Is it meaningful to add a test that will hit this branch for leap and non-leap years?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. I'm happy to use 1996.

Is it meaningful to add a test that will hit this branch for leap and non-leap years?

My expectation is that this will turn out to be fragile in ways unrelated to leap vs non-leap. My preference would be to keep an eye out for from-the-wild cases that hit these branches rather than try to concoct them for the sake of coverage stats.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That said, I do have a couple of PRs coming up that are just adding tests, many of which will currently be xfails.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think 1996 vs 2000 matters. Just gave me a start because I was like, "Wait, that's not supposed to be a leap year because it's a century, actually, wait, the century is divisible by 4..." Doesn't matter to a computer and the comment is necessary to make it clear why you chose 2000 anyway.

Regarding the tests, I think it might be a good idea to come up with some tests that will hit those branches. I can do it if you didn't have anything in mind.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go for it. Anything you don't get covered I'll circle back to get next week.

@pganssle
Copy link
Member

Hm.. I'm noticing there's not a codecov hook anymore, but actually this seems to be introducing some uncovered lines see here. @jbrockmendel Do you think you can come up with some strings that will hit those other cases?

@jbrockmendel
Copy link
Contributor Author

I haven't brainstormed any particularly good examples for the other cases. Got any in mind?

@pganssle
Copy link
Member

pganssle commented Nov 2, 2017

I couldn't think of anything so I tried fuzzing the parser a bit with python-afl, and in fact found a bug in those lines!

>>> from dateutil.parser import parse
>>> parse('02:17NOV2017CE')
...
AttributeError: '_ymd' has no attribute 'month'

@jbrockmendel
Copy link
Contributor Author

Good catch. I'll have to take a look at that fuzzer.

Pushing a fix shortly.

Though the trailing "BCE" is a whole other can of worms.

@pganssle
Copy link
Member

pganssle commented Nov 2, 2017

It also works with a trailing CE, which would be a valid date in Python. I haven't found any examples yet where it would actually parse to a real date, though.

@jbrockmendel
Copy link
Contributor Author

Yah, I'm running the fuzzer now to get a feel for how it works.

I vote for closing out this bug fix and not cargo-culting coverage.

@pganssle
Copy link
Member

pganssle commented Nov 2, 2017

@jbrockmendel I wouldn't worry too much about the fuzzing, but I think that my insistence on coverage was not at all cargo culting, since in this case the code you've written is fundamentally broken. Anything that reaches the uncovered branches will fail with AttributeError. I'm not sure if there's an obvious fix to it, since _ymd no longer actually stores year, month or day, so either the approach to could_be_day needs to be fixed or _ymd needs to take a different approach as a container.

Worst case scenario, we can add tests that directly call _ymd (and maybe that's a good start when doing the development), but I'd be more comfortable with that if we could come up with some reasoning to explain why no valid datetime strings would ever reach those branches in the current implementation.

@jbrockmendel
Copy link
Contributor Author

since in this case the code you've written is fundamentally broken

Fair point. (Huh. The fix I pushed isn't showing up here... gotta see where that ended up)

[...] if we could come up with some reasoning to explain why no valid datetime strings would ever reach those branches in the current implementation.

I have no such reasoning, and I like the idea of using fuzzing to try to find them. All I'm getting at is that if we can't find such cases after [whatever the appropriate amount of effort is] we shouldn't let that stop us from fixing the bug we know about.

@pganssle
Copy link
Member

pganssle commented Nov 3, 2017

I like this approach with test_internals.py. Fuzzing with 5 parallel tasks for most of a day didn't find anything useful here, so we'll replace the relevant test_internals.py calls if we come up with anything that naturally hits these lines (I'm guessing that's more likely to happen due to refactoring than fuzzing or something).

@pganssle pganssle merged commit 8d93169 into dateutil:master Nov 3, 2017
@pganssle pganssle mentioned this pull request Mar 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants