On Tue, Dec 29, 2020 at 10:30 AM Guido van Rossum <gu...@python.org> wrote:
> Interesting -- thanks for taking up the challenge. I still suspect that if > we ran the corresponding benchmark at the C level, the first form would win, > I was thinking that might be the case -- but either way, there is little difference, and at least for ** unpacking, it's probably mostly used for small dicts anyway. > Does there need to be a single defined "protocol" for a mapping (other >> than the ABC)? -- that is, would **unpacking be able to use .items() and >> keys() be used in other contexts? >> >> And why does ** unpacking need to check at all (LBYL) couldn't it simply >> do something like: >> >> {k: d[k] for k in d} >> >> I don't understand why LBYL is considered such an anti-pattern. It helps > produce much clearer error messages in this case for users who are > exploring this feature, and distinguishing *early* between sequences and > mappings is important for that. > Fair enough, though in this case, it's producing a not quite clear error message, whereas simply trying to call keys() would reflect the actual error. I was thinking about this a bit more, and realized that this pattern is used (at least) in the dict constructor and dict.update() -- but in both of those cases, they can take either a mapping or an iterable of (key, value) pairs. So it is required to make a distinction, and looking for keys() is as good a way as any (maybe the best, certainly well established) (and if you pass a object with a keys() method, but no __getitem__ into dict(), you get: "TypeError: 'MinMap' object is not subscriptable" -- not anything it about it needing to be a Mapping) But for **, which only supports Mappings, maybe there is no need to check for keys() -- it is clearly defined that iter(a_mapping) iterates over the keys, so that part should work, and if the __getitem__ doesn't work appropriately, then that's not really different than passing a iterable that doesn't produce valid (key, value) pairs to dict(). But this is all theoretical -- it's established, and a bit better docs should clear up the confusion. One more note on the docstrings: dict.update() says: "... If E is present and has a .keys() method..." Which nicely defines what is actually required. Whereas dict() says: "...dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs..." Without saying anything about how it determines what whether it's a mapping. So maybe that could be made a bit more clear as well. I also just noticed something else in the docs -- in typing, there is a Protocol type -- maybe we could/should pre-define a mapping protocol type? Or maybe a MinimialMapping ABC, analogous to the Iterable ABC -- though no idea what to call it that would be clear :-) -CHB -- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@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/IXPZJSCT2C2Z4MFWQUZVZY4MGBGBJ457/ Code of Conduct: http://python.org/psf/codeofconduct/