Skip to content

Cache Param For get_json() Leading to Contradictory Behavior #1698

Closed
@AndTheDaysGoBy

Description

@AndTheDaysGoBy

The location of interest:

class JSONMixin(object):

Example:

from flask import Response
r = Response(response=’{“detail”:”Bad Gateway”}’, status=502, content_type=’application/json’)

# Initial
assert r.data === b’{“detail”:”Bad Gateway”}’
assert r.get_data() === b’{“detail”:”Bad Gateway”}’
assert r.json == {‘detail’: ‘Bad Gateway’}
assert r.get_json() == {‘detail’: ‘Bad Gateway’}

# Set
r.set_data(‘{“a”:”b”}’)

# Data field updated
assert r.data == b‘{“a”:”b”}’
assert r.get_data() == b'{“a”:”b”}’

# JSON field non-cached is correct
assert r.get_json(cache=False) == {‘a’: ‘b’}

# Cache not refreshed (Fails)
assert r.get_json() == {'a': 'b'}

In the above example, due to the set_data, the data changes. Using get_json(cache=False) works because it'll re-parses the data. However, since cache = False, this value will not be placed into the cache for the future. If I hadn't used get_json(cache=False), it would've just returned the cached value (which is wrong).
Therefore, it seems that performing set_data, makes it so that every subsequent call would require get_json(cache=False). My how would be something like get_json(reparse=True) and then all subsequently calls can just be from the cache.

Now, what the cache parameter represents becomes important, does it mean "cache the current value" or "return the currently cached value". The issue I see is that it's playing both roles (See:

if cache and self._cached_json[silent] is not Ellipsis:
and )
Consequently, should the data change, if you used cache = True, you'll just return the currently cached value, but if you use cache = False, you wont set the cache to the new value because of line:

Therefore, I recommend separating out the use cache and set cache functionalities (i.e. two different kwargs), or, have cache=True solely be used for obtaining the value from the cache, not for setting it. I.e. it is performing get_json(cache=False) that perform the set (I.e. remove if cache check here:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions