Fix handling of datetime arguments to from_start_end#580
Fix handling of datetime arguments to from_start_end#580mwilck merged 3 commits intoprojecthamster:masterfrom
Conversation
|
Hmm, tests/stuff_tests works fine, but hamster crashes: |
|
Confirmed, forgot to restart the server 🤦♂️ . Time to get out, I'm no longer into it... |
matthijskooijman
left a comment
There was a problem hiding this comment.
Thanks for looking into this. I left some comments inline.
Also, I wonder if this is really a complete fix, since I suspect there might be two parts to this problem:
- When a datetime instance is passed, it was previously treated as a date instance, throwing away time data.
- When a date instance is passed, the returned range has an end datetime pointing at the first second of the next day.
Regarding the second, that suggests that the Range returned is intended to be used as a range from the start time up to excluding the end time, but it is actually interpreted to mean the entire day pointed to by that first second of the next day.
Looking even more closely, it seems that this is because from_start_end is called twice (once in client.get_facts and once in the server's GetFactsJSON). The second time it is called, problem 1 above causes the 1-second-into-the-next-day datetime to be converted into a date object for that next day, and the end result is a datetime 1-second-into-the-next-next-day, which is wrong.
So, I guess the fix is complete after all, since now it just passes datetime objects unchanged, so the server will not further modify it.
src/hamster/lib/datetime.py
Outdated
| range = Range(start, end) | ||
| elif isinstance(start, datetime): | ||
| # this one must come first, | ||
| # because isinstance(datetime(), date) is True |
There was a problem hiding this comment.
I was a bit confused by this comment, since it seems there is no isinstance(datetime(), date) below at all. Looking more closely, I see that pdt is actually the datetime import. Maybe this comment could be adapted too:
# because isinstance(datetime(), pdt.date) is True
That would have made things more clear for me.
There was a problem hiding this comment.
date inherits from pdt.date.
I'll add a clarification though.
|
So we have this and #577, and both are closed ... ? |
|
Maybe @ederag plans to submit a fixed PR later? If so, note that you can also do a (force) push to the branch for an existing PR to automatically update the PR (this is often better than starting a new PR, since any comment history will be kept). |
Indeed (with force-push). Closed to lower the publicity.
|
|
Got it (hopefully...). Just a few tests to do before pushing again. |
matthijskooijman
left a comment
There was a problem hiding this comment.
Looks good to me, haven't tested it yet.
One question: If you pass a pdt.date, that is now handled, but I think not a date instance. It's probably not strictly needed (legacy uses pdt.date I suppose), but it would be easy to support date as well (just do isinstance(start, date) instead of isinstance(start, pdt.date). Or would it be better not to support this? Or would the Range constructor already accept date objects properly maybe?
|
Indeed, to avoid mistakes, I would restrict to |
matthijskooijman
left a comment
There was a problem hiding this comment.
Looks good, also good to choke on invalid types to prevent mistakes later on.
Looks good to merge like this, I think.
Good point, I added a suggestion for that.
I think this is not a supported case. The old API was to pass Writing this, I wonder if it would not be better to fix this by not passing I previously said:
But that made no sense: The current |
Co-Authored-By: Matthijs Kooijman <matthijs@stdin.nl>
|
Range granularity is Otherwise, there would be ambiguities: Passing |
|
Free advice for new maintainers: This PR deals with a serious bug because it leads to incorrect invoices for anyone like me who relies on |
|
Indeed. And the code is fine now. |
|
Let's merge it, then. The 3.0.2 version bump should be discussed elsewhere. |
Here is how I'd fix #576.