The proposal doesn't work well with type hints: atuple(a=1, b=2) and atuple(a="a", b="b") generates the same type.

Also, the automatic creation of a new type on-demand can lead to uncontrollable memory growth.

On Thu, Mar 24, 2022 at 6:15 PM <michael@michaelgreen.dev> wrote:
Back in early 2016 there was an idea submitted[1] by Joseph Martinot-Lagarde in regard to anonymous namedtuples. The crux of the submission was the idea of instantiating a namedtuple using only Python's generic tuple syntax plus keyword arguments. At the time, the major rebuttal against this idea however was that, since kwargs are an unordered collection, it would be non-trivial to figure out a proper convention for mapping an unordered collection onto an ordered one.

Times have changed however, and with python3.6/3.7 we now have the guarantee that dictionaries are insertion ordered. This means that by extension keyword arguments are also ordered, and thus the major point of contest against anonymous namedtuples is now moot. And as such I would like to once again suggest anonymous namedtuples as a potential PEP.

Proposal
=======
The proposal ultimately is the same as before:
```
my_point = (x=12, y=16)
# (x=12, y=16)
my_point[0]
# 12
```

where kwargs can be passed to a tuple's instantiation [either via tuple() or just ()], and these tuples would have all the same properties of a namedtuple.

A basic, pure-python implementation is actually quite trivial now given that kwargs are ordered. Observe:
```
def atuple(**kwargs):
    signature = " ".join(kwargs)
    _type = atuple.__dict__.get(signature)
    if not _type:
        _type = namedtuple(atuple.__name__, signature)
        atuple.__dict__[signature] = _type
    return _type(**kwargs)
```
This has none of the problems suggested in the previous rebuttal.

anonymous tuples of incorrect ordering raise the assertion error, as expected:

```
>>> assert atuple(x=12, y=16) == atuple(y=16, x=12)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
```

...and by extension it preserves the users's specified ordering as given by **kwargs.
```
>>> pt = atuple(r=3, theta=0.5, phi=0.25)
>>> pt
atuple(r=3, theta=0.5, phi=0.25)
```

Given that this implementation caches the type by the keyword signature, anonymous tuples of the same signature are recognized as the same type. However, given differing values, they are not equal.
```
>>> type(atuple(x=1,y=2)) == type(atuple(x=1,y=2))
True
>>> atuple(x=1,y=2) == atuple(x=1,y=3)
False
```

This allows us to provide positional arguments to the construct, just like regular namedtuples, and passing a mismatch throws an error as expected.
```
>>> pt = atuple(x=12, y=16)
>>> pt
atuple(x=12, y=16)
>>> type(pt)(1,2)
atuple(x=1, y=2)
>>> type(pt)(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: atuple.__new__() takes 3 positional arguments but 4 were given
```

As we can see, the introduction of insertion-ordered dictionaries solves all of the issues previously raised with regard to anonymous namedtuples.

References:
[1] https://mail.python.org/pipermail/python-ideas/2016-April/039857.html
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/EUJTGE2VIHHMNJN574L5BEAS7ROSTYZL/
Code of Conduct: http://python.org/psf/codeofconduct/


--
Thanks,
Andrew Svetlov