@Michael: As the previous author I fully support this proposal! ;) Thank you for the revival. For reference, since you linked one of the answer of the original thread, this is my original proposal: https://mail.python.org/pipermail/python-ideas/2016-April/039836.html Both suggested implementations are very interesting. If I'm not wrong they have exactly the same behavior (except for __dict__). Performance-wise with a quick test I get the following results: t = (1, 2) print("sizeof", sys.getsizeof(t)) # 56 print("sizeof type", sys.getsizeof(type(t))) # 408 print(timeit.timeit("(1, 2)")) # ~0.01 nt = namedtuple("nt", ["x", "y"]) print("sizeof", sys.getsizeof(nt(1, 2))) # 56 print("sizeof type", sys.getsizeof(type(nt(1, 2)))) # 896 print(timeit.timeit("nt(1, 2)", setup="from __main__ import nt")) # ~0.2 pt = atuple(x=1, y=2) print("sizeof", sys.getsizeof(pt)) # 56 print("sizeof type", sys.getsizeof(type(pt))) # 896 print(timeit.timeit("atuple(x=12, y=16)", setup="from __main__ import atuple")) # ~0.8 point = TupleWithNames(x=1, y=2) print("sizeof", sys.getsizeof(point)) # 64 print("sizeof type", sys.getsizeof(type(point))) # 1064 print(timeit.timeit("TupleWithNames(x=12, y=16)", setup="from __main__ import TupleWithNames")) # ~0.8 The timing performance of both solutions is roughly the same given the measurament variation, but way slower than tuple an namedtuple. TupleWithNames is a bit more memory hungry than atuple and namedtuple, but there is only one type so if I understand correctly it would be a win for multiple instances. Maybe there is room for optimisation in both cases ?