Consider the object returned by os.stat. It allows getting terms by index:
>>> import os
>>> os.stat("/dev/null")
os.stat_result(st_mode=8630, st_ino=336, st_dev=-2065165533, st_nlink=1,
st_uid=0, st_gid=0, st_size=0, st_atime=1730960121, st_mtime=1730981460,
st_ctime=1730981460)
>>> os.stat("/dev/null")[0]
8630
>>> os.stat("/dev/null")[-1]
1730981720
But that list of 10 values became locked because people do: (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = o.stat(filename)
Which means new fields are not accessible by indexing, only attribute lookup: >>> os.stat("/dev/null").st_blksize
65536
Assuming there wasn't the historical baggage which made os.stat the way it is, why would namedtuple still be the more Pythonic solution, and simpler than a frozen dataclass?(Historically, os.stat originally returned a tuple, then migrated to os.stat_result and named attributes, both for readability and to allow new fields, but keeping indexing for backwards compatibility support.)
The number of characters and lines to access the members of namedtuple is significantly less than dataclass.
dataclass would have similar issues if st_dev was now defined as a string whereas namedtuple would not.
Whilst there maybe edge cases in using simpler constructs, in scripting languages we accept the edge cases as it pays off in 99.99% of cases to simply ignore them. If something goes wrong, you catch the exception "Ask for forgiveness not for permission" if you want to look up the concept.
Namedtuple is not strictly simpler. It implements additional features which would not be in an frozen dataclass, which makes "simpler" a personal bias.
I've been using Python continuously since 1998 and well remember the "look before you leap" vs. "ask for forgiveness not for permission" debate from the bygone comp.lang.python forum. And I learned the concept of "easier to ask for forgiveness" from the 60 Minutes interview with Grace Hopper back in the 1980s.
That have nothing to do with this issue, which is one of taking on an API burden without due consideration simply because it's less typing.
>>> Point = dataclasses.make_dataclass("Point", ["x", "y", "z"])
>>> Point(1, 2, 3)
Point(x=1, y=2, z=3)