[Python-Dev] How to update namedtuple asdict() to use dict instead of OrderedDict

Gregory P. Smith greg at krypto.org
Wed Jan 30 19:50:04 EST 2019

On Wed, Jan 30, 2019 at 2:32 PM Raymond Hettinger <
raymond.hettinger at gmail.com> wrote:

> Now that regular dicts are ordered and compact, it makes more sense for
> the _asdict() method to create a regular dict (as it did in its early days)
> rather than an OrderedDict.  The regular dict is much smaller, much faster,
> and has a much cleaner looking repr.  It would also help namedtuple() stay
> in sync with dataclasses which already take advantage of the ordering
> feature of regular dicts.
> The question is how to be go about making the change in a way gives the
> most benefit to users as soon as possible and that creates the least
> disruption.
> Option 1) Add a deprecation notice to 3.8, make no code change in 3.8, and
> then update the code in 3.9.  This has several issues: a) it doesn't
> provide an executable DeprecationWarning in 3.8, b) it isn't really a
> deprecation, and c) it defers the benefits of the change for another
> release.
> Option 2) Add a deprecation notice to 3.8, add a DeprecationWarning to the
> _asdict() method, and make the actual improvement in 3.9.  The main issue
> here is that it will create a lot of noise for normal uses of the _asdict()
> method which are otherwise unaffected by the change. The typical use cases
> for _asdict() are to create keyword arguments and to pass named tuple data
> into functions or methods that expect regular dictionaries.  Those use
> cases would benefit from seeing the change made sooner and would suffer in
> the interim from their code slowing down for warnings that aren't useful.
> Option 3). Add a deprecation notice to 3.8 and have the _asdict() method
> create a subclass of OrderedDict that issues warnings only for the methods
> and attributes that will change (move_to_end, popitem, __eq__, __dict__,
> __weakref__).  This is less noisy but it adds a lot of machinery just to
> make a notification of a minor change.  Also, it fails to warn that the
> data type will change.  And it may create more confusion than options 1 and
> 4 which are simpler.
> Option 4) Just make the change directly in 3.8,  s/OrderedDict/dict/, and
> be done will it.  This gives users the benefits right away and doesn't
> annoy them with warnings that they likely don't care about.   There is some
> precedent for this.  To make namedtuple class creation faster, the
> *verbose* option was dropped without any deprecation period.  It looks like
> no one missed that feature at all, but they did get the immediate benefit
> of faster import times.  In the case of using regular dicts in named
> tuples, people will get immediate and significant space savings as well as
> a speed benefit.
> My recommendation is Option 4 as being less disruptive and more beneficial
> than the other options.  In the unlikely event that anyone is currently
> depending on the reordering methods for the output of _asdict(), the
> remediation is trivially simple:   nt._asdict() ->
> OrderedDict(nt.as_dict()).

+1 on option 4.  I agree with everyone else.  Because the remediation that
keeps code compatible across all versions is that simple, just go with
option 4.  We document that in What's New and be done with it. :)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20190130/5bdde236/attachment.html>

More information about the Python-Dev mailing list