Thanks for writing this PEP!
Aside: I’ll have a PR shortly to fix a few typos and rephrase a few things for clarity. I hope it helps!
Regarding defaults for multiple, dot-separated names in attrgetter(), it occurs to me – and I haven’t thought this fully through – that you could allow default to be a callable, which would have an API along the lines of:
def resolve(
success_path: str,
fail_path: str,
last_object: object,
) -> object:
The idea being, let’s say you do this:
>>> attrgettr('a.b.c.d', default=resolve)(obj)
and let’s say you have a.b.c but that object has no d attribute. resolve() would get called with:
resolve('a.b.c', 'd', a.b.c)
The question that comes to mind is whether you could use this to implement the ?. functionality in PEP 505 this way, i.e. None-aware attribute access? Forget about the syntax in PEP 505, but just the functional equivalent?
Maybe – and I really haven’t thought about this! – something similar for itemgetter() and ?[], i.e. the None-aware indexing operator.
Maybe it’s not possible, or the signature of resolve() needs to be changed, or doesn’t make sense, but I wanted to throw it out there as it doesn’t appear to be covered in the rejected ideas of PEP 769.
There’s one glitch: what if you wanted to return a callable as the default? I think there are possible workarounds, such as defining a protocol/interface that a default callable must adhere to, or always using a 1-tuple default such as (function,).