If you read the language reference for augmented arithmetic assignment, you will note that it essentially says, "call __i<op>__, and if that doesn't work call as if you were doing a <op> b". Unfortunately it appears **= does not follow the rule of falling back on the binary arithmetic expression semantics. I have a GitHub gist with demonstration code that shows this happening in both 3.8 and master (https://gist.github.com/brettcannon/fec4152857e0ed551b4da515dc63e580
). This was reported in https://bugs.python.org/issue38302
, although initially it didn't cover __pow__, only __rpow__ being skipped.
I think there are two options to fixing this:
1. Add a note to the data model that **= is special and does not fall back (obviously the most backwards-compatible)
2. Fix **= (which makes sense from a language consistency perspective)
Personally, my vote is for #2 as I don't want to have to remember that **= is somehow special compared to all other augmented assignments. I also don't think the backwards-compatibility risk is at all large since the semantics of turning `a **= b` into `a = a ** b` shouldn't really be different.
P.S. Why are some of the PyNumber_InPlace*() functions handwritten while others are defined using a macro which mirrors the handwritten ones? Just something I noticed while investigating this.