This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: namedtuple comparison ignores types
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.7, Python 3.6, Python 3.3, Python 3.4, Python 3.5, Python 2.7
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: r.david.murray, vlad
Priority: normal Keywords:

Created on 2017-08-19 00:34 by vlad, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (3)
msg300562 - (view) Author: Vlad Shcherbina (vlad) * Date: 2017-08-19 00:34
Toy example:

>>> from collections import namedtuple
>>> Rectangle = namedtuple('Rectangle', 'width height')
>>> Ellipse = namedtuple('Ellipse', 'x_axis y_axis')
>>> Rectangle(width=1, height=2) == Ellipse(x_axis=1, y_axis=2)
True

I understand this happens because namedtuple inherits comparisons and hash from the regular tuple.
However, this seems like confusing and dangerous behavior.
It is especially annoying to debug when these tuples are used as dict keys (repr() shows one thing and dict item access shows another).

Why would anyone mix named tuples of different types?
Here is a use case: typing.NamedTuple together with typing.Union would be a neat way to express algebraic data types.

Haskell's
data Shape = Rectangle Int Int | Ellipse Int Int    deriving(Eq, Show)

would become
Shape = Union[Rectangle, Ellipse]

except that it does not work as expected because of the flawed comparisons.
msg300563 - (view) Author: Vlad Shcherbina (vlad) * Date: 2017-08-19 00:37
While we are at it, namedtuple inherits other operations that make no sense for fixed-length tuples:

>>> Rectangle(width=1, height=2) * 3
(1, 2, 1, 2, 1, 2)
>>> Rectangle(width=1, height=2) + Ellipse(x_axis=3, y_axis=4)
(1, 2, 3, 4)

But those are not so problematic because they are less likely to occur in practice.
msg300571 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-08-19 08:13
This is by design: namedtuples are tuples in which you can access the elements by name.  If you have a tuple with the same elements, but no name access, they should compare equal, because they are fundamentally tuples.  The names are just a convenience.

Even if this were not so, it is not something that could be changed, for backward compatibility reasons.  

If you want a different data types, make them :)
History
Date User Action Args
2022-04-11 14:58:50adminsetgithub: 75422
2017-08-19 08:13:57r.david.murraysetstatus: open -> closed

nosy: + r.david.murray
messages: + msg300571

resolution: rejected
stage: resolved
2017-08-19 00:37:23vladsetmessages: + msg300563
2017-08-19 00:34:46vladcreate