Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #16123 -- Ensured strptime receive proper string type

strptime generates an UnicodeEncodeError when using a non-ascii
unicode string on Python 2.
  • Loading branch information...
commit 4b3f7110ae1e9ef7862c67a38431780080f0062c 1 parent 962f133
Claude Paroz authored January 26, 2013
3  django/forms/extras/widgets.py
@@ -9,6 +9,7 @@
9 9
 from django.forms.widgets import Widget, Select
10 10
 from django.utils import datetime_safe
11 11
 from django.utils.dates import MONTHS
  12
+from django.utils.encoding import force_str
12 13
 from django.utils.safestring import mark_safe
13 14
 from django.utils.formats import get_format
14 15
 from django.utils import six
@@ -69,7 +70,7 @@ def render(self, name, value, attrs=None):
69 70
                 if settings.USE_L10N:
70 71
                     try:
71 72
                         input_format = get_format('DATE_INPUT_FORMATS')[0]
72  
-                        v = datetime.datetime.strptime(value, input_format)
  73
+                        v = datetime.datetime.strptime(force_str(value), input_format)
73 74
                         year_val, month_val, day_val = v.year, v.month, v.day
74 75
                     except ValueError:
75 76
                         pass
8  django/forms/fields.py
@@ -23,7 +23,7 @@
23 23
     NullBooleanSelect, SelectMultiple, DateInput, DateTimeInput, TimeInput,
24 24
     SplitDateTimeWidget, SplitHiddenDateTimeWidget, FILE_INPUT_CONTRADICTION)
25 25
 from django.utils import formats
26  
-from django.utils.encoding import smart_text, force_text
  26
+from django.utils.encoding import smart_text, force_str, force_text
27 27
 from django.utils.ipv6 import clean_ipv6_address
28 28
 from django.utils import six
29 29
 from django.utils.translation import ugettext_lazy as _
@@ -395,7 +395,7 @@ def to_python(self, value):
395 395
         return super(DateField, self).to_python(value)
396 396
 
397 397
     def strptime(self, value, format):
398  
-        return datetime.datetime.strptime(value, format).date()
  398
+        return datetime.datetime.strptime(force_str(value), format).date()
399 399
 
400 400
 
401 401
 class TimeField(BaseTemporalField):
@@ -417,7 +417,7 @@ def to_python(self, value):
417 417
         return super(TimeField, self).to_python(value)
418 418
 
419 419
     def strptime(self, value, format):
420  
-        return datetime.datetime.strptime(value, format).time()
  420
+        return datetime.datetime.strptime(force_str(value), format).time()
421 421
 
422 422
 class DateTimeField(BaseTemporalField):
423 423
     widget = DateTimeInput
@@ -455,7 +455,7 @@ def to_python(self, value):
455 455
         return from_current_timezone(result)
456 456
 
457 457
     def strptime(self, value, format):
458  
-        return datetime.datetime.strptime(value, format)
  458
+        return datetime.datetime.strptime(force_str(value), format)
459 459
 
460 460
 class RegexField(CharField):
461 461
     def __init__(self, regex, max_length=None, min_length=None, error_message=None, *args, **kwargs):
4  django/views/generic/dates.py
@@ -5,7 +5,7 @@
5 5
 from django.db import models
6 6
 from django.core.exceptions import ImproperlyConfigured
7 7
 from django.http import Http404
8  
-from django.utils.encoding import force_text
  8
+from django.utils.encoding import force_str, force_text
9 9
 from django.utils.functional import cached_property
10 10
 from django.utils.translation import ugettext as _
11 11
 from django.utils import timezone
@@ -673,7 +673,7 @@ def _date_from_string(year, year_format, month='', month_format='', day='', day_
673 673
     format = delim.join((year_format, month_format, day_format))
674 674
     datestr = delim.join((year, month, day))
675 675
     try:
676  
-        return datetime.datetime.strptime(datestr, format).date()
  676
+        return datetime.datetime.strptime(force_str(datestr), format).date()
677 677
     except ValueError:
678 678
         raise Http404(_("Invalid date string '%(datestr)s' given format '%(format)s'") % {
679 679
             'datestr': datestr,
10  tests/regressiontests/forms/tests/fields.py
@@ -370,6 +370,16 @@ def test_datefield_changed(self):
370 370
         self.assertFalse(f._has_changed(d, '17/09/2007'))
371 371
         self.assertFalse(f._has_changed(d.strftime(format), '17/09/2007'))
372 372
 
  373
+    def test_datefield_strptime(self):
  374
+        """Test that field.strptime doesn't raise an UnicodeEncodeError (#16123)"""
  375
+        f = DateField()
  376
+        try:
  377
+            f.strptime('31 мая 2011', '%d-%b-%y')
  378
+        except Exception as e:
  379
+            # assertIsInstance or assertRaises cannot be used because UnicodeEncodeError
  380
+            # is a subclass of ValueError
  381
+            self.assertEqual(e.__class__, ValueError)
  382
+
373 383
     # TimeField ###################################################################
374 384
 
375 385
     def test_timefield_1(self):

0 notes on commit 4b3f711

Please sign in to comment.
Something went wrong with that request. Please try again.