Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add support for subtracting date/datetime objects to create timedelta objects. #6

Merged
merged 2 commits into from

2 participants

@dnmiller

Normally, subtracting date/datetime from another date/datetime returns a timedelta. Doing so with FakeDate/FakeDatetime instead raises an AttributeError since their __sub__ methods try to force the resulting timedelta returned by the super's __sub__ to be a FakeDate/FakeDatetime. As a result, code that subtracts date/datetime objects from other date/datetime objects will fail if patched with freeze_time.

This change causes the __sub__ methods for FakeDate/FakeDatetime to return a timedelta if the super's __sub__ returned a timedelta.

@spulec
Owner

Hi Dan,

Thanks a lot for taking the time to report this.

I'm not exactly excited that we have to special case timedeltas like this. I think it might be a little cleaner if we flipped it and did something like

if isinstance(result, real_datetime):
    return date_to_fakedate(result)
else:
    return result

It seems to be more explicit about what our intentions really are.

Thoughts?

@dnmiller

I like the suggestion. I've updated the pull request.

@spulec spulec merged commit 0bebcf2 into spulec:master
@spulec
Owner

Thanks Dan!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 20, 2012
Commits on Dec 21, 2012
  1. @dnmiller
This page is out of date. Refresh to see the latest.
Showing with 12 additions and 2 deletions.
  1. +8 −2 freezegun/api.py
  2. +4 −0 tests/test_operations.py
View
10 freezegun/api.py
@@ -24,7 +24,10 @@ def __sub__(self, other):
result = super(FakeDate, self).__sub__(other)
if result is NotImplemented:
return result
- return date_to_fakedate(result)
+ if isinstance(result, real_date):
+ return date_to_fakedate(result)
+ else:
+ return result
@classmethod
def today(cls):
@@ -53,7 +56,10 @@ def __sub__(self, other):
result = super(FakeDatetime, self).__sub__(other)
if result is NotImplemented:
return result
- return datetime_to_fakedatetime(result)
+ if isinstance(result, real_datetime):
+ return datetime_to_fakedatetime(result)
+ else:
+ return result
@classmethod
def now(cls):
View
4 tests/test_operations.py
@@ -21,11 +21,15 @@ def test_subtraction():
now = datetime.datetime.now()
before = now - datetime.timedelta(days=1)
other_before = now - relativedelta(days=1)
+ how_long = now - before
assert isinstance(before, datetime.datetime)
assert isinstance(other_before, datetime.datetime)
+ assert isinstance(how_long, datetime.timedelta)
today = datetime.date.today()
yesterday = today - datetime.timedelta(days=1)
other_yesterday = today - relativedelta(days=1)
+ how_long = today - yesterday
assert isinstance(yesterday, datetime.date)
assert isinstance(other_yesterday, datetime.date)
+ assert isinstance(how_long, datetime.timedelta)
Something went wrong with that request. Please try again.