On Fri, Sep 25, 2020 at 4:36 PM Steven D'Aprano <steve@pearwood.info> wrote:
> I.e. consider:
> >>> d = dict()
> >>> d[()] = "foo"
> >>> d
> {(): 'foo'}

I agree with Ricky that the choice of empty tuple should be justified
better by the PEP, and alternatives (None, NotImplemented) discussed.
But I don't think this is a breaking change. Can you explain further
what you think will break?

I think empty tuple is the best choice, and the discussion on the NumPy list mostly seems to agree.  I agree that it's basically just a question of making the PEP more explicit in explaining the choice.

In a direct sense, no matter what `newthing[foo=1, bar=4:5]` does internally, it CANNOT be a breaking change, since that is a SyntaxError now.  However, it's also the case that if any sentinel is used for "keywords only", whether None or () or EmptyIndexSentinel, it "steps on" using that value as an actual index.

E.g. we would have:

    newthing[(), foo=1, bar=4:5] == newthing[foo=1, bar=4:5]

... well, we have that if subscript access is not mutation, that is.  Which it hopefully will not be, but anything is possible in code.

The dead increasingly dominate and strangle both the living and the
not-yet born.  Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.