Make ReturnDict support dict union operators on Python 3.9 and later by spookylukey · Pull Request #8302 · encode/django-rest-framework (original) (raw)

@kevin-brown It's impossible to keep things get that kind of consistency, since you can't change the behaviour of built-in types. If you have a Python 3.8 project, then having the | operator work only for some dictionary-like types is just confusion.

Regarding the PR in general, the current DRF behaviour is a very clear bug on Python 3.9. The ReturnDict types inherits from OrderedDict, but then breaks some of its behaviour. In other cases where this has happened, ReturnDict has been fixed to rectify this:

With the patch as it is, there is no resulting inconsistency:

  1. On Python 3.8, dictionaries (included slightly customised dictionary-subclasses like the ones DRF uses in some places), do not have | operator support.
  2. On Python 3.9, they do, and it always works.

Without the patch, 2 is not true.
With the patch but dropping the sys,version_info check, 1 is not true.

DRF nowhere advertises support for | on dictionaries - it could not, because it can't change built-in dict behaviour, and doesn't use ReturnDict everywhere. The fact that ReturnDict is anything other than a normal dict has in fact been deliberately hidden, so people should just be able to use it as a dict (I for one had no idea it wasn't a normal dict until I hit this). See #2421 (comment):

We're seeing folks ask about ResultDict and ResultList objects a fair bit on the mailing list, although they're most just an implementation detail that they don't need to know about.

We should probably modify the representation of them to simply be the standard native styles, such as {'a': 123} and [1,2,3]. Hiding this bit of detail will likely lead to less confusion.

So the only consistency to aim for here is consistency with Python dictionaries.