Skip to content

partial_prepare incorrectly handles Django QueryDict, causes values to become lists #1249

@slav0nic

Description

@slav0nic

When using partial pipeline steps in Django projects, the partial_prepare function in social_core/pipeline/utils.py incorrectly converts QueryDict (and similar mapping types?) to a plain dict, causing all values to become lists. This breaks expected behavior: instead of scalar values, downstream code and extra_data receive lists (e.g. {"id": ["123"]} instead of {"id": "123"}).

Cause:

  • The line value = dict(value) if is_dict_type(value) else value in partial_prepare loses the scalar/flat semantics. For QueryDict, dict(qd) always returns lists.
>>> from django.http.request import QueryDict
>>> d = QueryDict("a=1&b=2")
>>> dict(d)
{'a': ['1'], 'b': ['2']}
>>> d.dict()
{'a': '1', 'b': '2'}

Impact (observed in a Django app): After a partial pipeline resume, the backend (e.g. TelegramAuth) passes response straight to extra_data. Because response was turned into a plain dict with list values, the stored extra_data becomes:

Before partial (expected):

{
  "id": "123456789",
  "username": "demo_user",
  "first_name": "Alice",
  "hash": "<redacted_hash>"
}

After partial (actual):

{
  "id": ["123456789"],
  "username": ["demo_user"],
  "first_name": ["Alice"],
  "hash": ["<redacted_hash>"]
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions