Choice of complex buffer protocol format intentional break with PEP?

Why? I don’t think this is a part of the PEP 3118 specification. It looks that proposed changes were not discussed during PEP review. That part is not a specification, just because it’s too vague and unclear. See this for example. Complex-related critique:

“complex (whatever the next specifier is)”. Not really ‘whatever’. You can not have a ‘complex bool’ or ‘complex int’. What other types of complex are there besides complex double?

I think that recent (year ago) addition to the PEP clarify things:

This PEP is a historical document. The up-to-date, canonical documentation can now be found at Buffer Protocol, PyBufferProcs, PyMemoryView_FromObject.

Not all features proposed here were implemented. Specifically:

This PEP targets Python 3.0, which was released more than a decade ago. Any proposals to add missing functionality should be discussed as new features, not treated as finishing the implementation of this PEP.

So, it’s not a part of PEP, period.

BTW, the NumPy itself uses different type codes for ndarray() and for buffer protocol. Which convention we should adopt e.g. for the array module and why?

We could add support for multiple digits in type codes and implement 'Zd' as an alias for 'D' in the struct module and co, as interoperability with NumPy is important. Though:

maybe we should discuss more deep changes in the struct’s format mini-langiage, where 'Zd' code will be a tiny part of the whole picture. IMO, recent thread (AFAIK, referenced NumPy issue is one outcome of that thread) shows the need for some extensibility for the struct module (ability to register user types with custom pack/unpack helpers).