Opened 3 years ago

Closed 3 years ago

#17937 closed Bug (fixed)

timeuntil doesn't work with datetime.date objects

Reported by: dmitry.guyvoronsky@… Owned by: aaugustin
Component: Template system Version: 1.4-beta-1
Severity: Release blocker Keywords: timezone
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

It seems a bug exists in several django.utils.timezone methods, is_aware() and is_native(). This leads to error "AttributeError: 'datetime.date' object has no attribute 'tzinfo'" when timesince filter is applied to date object in Django template. Proof code

import time
from datetime import date
today = date.today()

from django.template import Context, Template
c = Context({"today": today})
t = Template("{{ today|timeuntil }}")

print t.render(c)

Error trace:

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    print t.render(c)
  File "/cygdrive/c/Users/dmitryg/.virtualenvs/feedback/lib/python2.6/site-packages/django/template/base.py", line 140, in render
    return self._render(context)
  File "/cygdrive/c/Users/dmitryg/.virtualenvs/feedback/lib/python2.6/site-packages/django/template/base.py", line 134, in _render
    return self.nodelist.render(context)
  File "/cygdrive/c/Users/dmitryg/.virtualenvs/feedback/lib/python2.6/site-packages/django/template/base.py", line 823, in render
    bit = self.render_node(node, context)
  File "/cygdrive/c/Users/dmitryg/.virtualenvs/feedback/lib/python2.6/site-packages/django/template/base.py", line 837, in render_node
    return node.render(context)
  File "/cygdrive/c/Users/dmitryg/.virtualenvs/feedback/lib/python2.6/site-packages/django/template/base.py", line 874, in render
    output = self.filter_expression.resolve(context)
  File "/cygdrive/c/Users/dmitryg/.virtualenvs/feedback/lib/python2.6/site-packages/django/template/base.py", line 599, in resolve
    new_obj = func(obj, *arg_vals)
  File "/cygdrive/c/Users/dmitryg/.virtualenvs/feedback/lib/python2.6/site-packages/django/template/defaultfilters.py", line 755, in timeuntil_filter
    return timeuntil(value, arg)
  File "/cygdrive/c/Users/dmitryg/.virtualenvs/feedback/lib/python2.6/site-packages/django/utils/timesince.py", line 61, in timeuntil
    now = datetime.datetime.now(utc if is_aware(d) else None)
  File "/cygdrive/c/Users/dmitryg/.virtualenvs/feedback/lib/python2.6/site-packages/django/utils/timezone.py", line 243, in is_aware
    return value.tzinfo is not None and value.tzinfo.utcoffset(value) is not None
AttributeError: 'datetime.date' object has no attribute 'tzinfo'

Attachments (2)

timezone.diff (1.3 KB) - added by dmitry.guyvoronsky@… 3 years ago.
Objects of date class should be always naive according to python docs
timeuntil2.diff (1.4 KB) - added by dreamiurg 3 years ago.

Download all attachments as: .zip

Change History (11)

comment:1 Changed 3 years ago by anonymous

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Summary changed from django.utils.timezone methods don't work with datetime.date objects to django.utils.timezone methods doesn't work with datetime.date objects

comment:2 Changed 3 years ago by aaugustin

  • Component changed from Uncategorized to Template system
  • Has patch unset
  • Severity changed from Normal to Release blocker
  • Triage Stage changed from Unreviewed to Accepted

Indeed, the docs clearly mean that timesince accepts either a date or a datetime.

Changed 3 years ago by dmitry.guyvoronsky@…

Objects of date class should be always naive according to python docs

comment:3 Changed 3 years ago by anonymous

  • Has patch set

comment:4 follow-ups: Changed 3 years ago by aaugustin

  • Needs tests set
  • Owner changed from nobody to aaugustin
  • Patch needs improvement set

Thanks for the patch. Unfortunately, I think it puts the check in the wrong layer -- is_aware and is_naive are only intended to receive datetime objects (or subclasses, or API-compatible classes).

The check should be in timesince instead.

The same bug probably exists in timeuntil and possibly in other filters.

Last edited 3 years ago by aaugustin (previous) (diff)

comment:5 in reply to: ↑ 4 Changed 3 years ago by dreamiurg

Replying to aaugustin:

Thanks for the patch. Unfortunately, I think it puts the check in the wrong layer -- is_aware and is_naive are only intended to receive datetime objects (or subclasses, or API-compatible classes).

The check should be in timesince instead.

The same bug probably exists in timeuntil and possibly in other filters.

'Yes, I was thinking about patching at timesince/timeuntil level, however, after considerations it seemed more logical to make changes at the bottom level instead.

Changed 3 years ago by dreamiurg

comment:6 in reply to: ↑ 4 Changed 3 years ago by dreamiurg

  • Owner changed from aaugustin to dreamiurg
  • Status changed from new to assigned

Replying to aaugustin:

Thanks for the patch. Unfortunately, I think it puts the check in the wrong layer -- is_aware and is_naive are only intended to receive datetime objects (or subclasses, or API-compatible classes).

The check should be in timesince instead.

The same bug probably exists in timeuntil and possibly in other filters.

Please see second version of the patch, this one fixes problem on timeuntil() level + adds unittests.

comment:7 Changed 3 years ago by dreamiurg

  • Needs tests unset
  • Patch needs improvement unset

comment:8 Changed 3 years ago by aaugustin

  • Owner changed from dreamiurg to aaugustin
  • Status changed from assigned to new
  • Summary changed from django.utils.timezone methods doesn't work with datetime.date objects to timeuntil doesn't work with datetime.date objects

In fact, this problem only affects timeuntil, not timesince — there are tests checking that timeuntil accepts date objects.

It's a little bit hard to explain the problem in English but the patch is self-explanatory. It just avoids duplicating the preprocessing of parguments that is done correctly in timesince and incorrectly in timeuntil.

comment:9 Changed 3 years ago by aaugustin

  • Resolution set to fixed
  • Status changed from new to closed

In [17774]:

Fixed #17937 -- Avoided an error in the timeuntil filter when it receives a date object. Thanks Dmitry Guyvoronsky for the report.

Note: See TracTickets for help on using tickets.
Back to Top