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/

Reply via email to