#19221: Cache keys can't be integers
-------------------------------------+------------------------------------
     Reporter:  mhsparks             |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Core (Cache system)  |                  Version:  master
     Severity:  Release blocker      |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+------------------------------------

Comment (by aaugustin):

 Since this is a release blocker for 1.5, we have to do something quickly;
 but I'm not ready to commit to supporting integers as cache keys in Django
 right now.

 I'm not specifically against using integers as cache keys. I'm against
 different Python values mapping to the same cache key, and that's what
 happens currently with integers (as well as any non-string type):

 {{{
 >>> a, b = 42, "42"
 >>> a == b
 False
 >>> cache.get(a)
 >>> cache.set(b, "foobar")
 >>> cache.get(a)
 "foobar"
 }}}

 ----

 As a compromise, in the short term, I suggest this small change:
 {{{
 --- a/django/core/cache/backends/base.py
 +++ b/django/core/cache/backends/base.py
 @@ -26,7 +26,7 @@ def default_key_func(key, key_prefix, version):
      the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
      function with custom key making behavior.
      """
 -    return ':'.join([key_prefix, str(version), key])
 +    return '%s:%s:%s' % (key_prefix, version, key)


  def get_key_func(key_func):
 }}}

 No tests, because tests create a promise of backwards-compatibility.

 And then move the ticket to DDN.

 ----

 This will make the cache work with any type of key that's convertible to a
 unicode string (`unicode_literals` is turned on in this module).

 It isn't 100% backwards compatible: Django used to call `smart_bytes`, and
 with this change it will implicitly call `six.text_type`. But I'm strongly
 against using the `smart_*` or `force_*` here. These functions do much
 more work than necessary. They are only suitable for use on not-so-well-
 specified input, or in extreme cases (like the 500 view) where we want
 *something* representing *any* object (even an instance of
 `UnicodeDecodeError`).

-- 
Ticket URL: <https://code.djangoproject.com/ticket/19221#comment:7>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to