You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ENH: Support importing complex arrays from standard library #31204
Python 3.15 adds support for complex arrays. It would be nice for NumPy to support importing these via the buffer protocol. Currently:
>>> import array
>>> import numpy as np
>>> a = array.array('D', [1.0+2.0j, 3.0+4.0j])
>>> a
array('D', [(1+2j), (3+4j)])
>>> np.array(a)
Traceback (most recent call last):
File "/usr/local/lib/python3.15/site-packages/numpy/_core/_internal.py", line 629, in _dtype_from_pep3118
dtype, align = __dtype_from_pep3118(stream, is_subdtype=False)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.15/site-packages/numpy/_core/_internal.py", line 705, in __dtype_from_pep3118
raise ValueError(
f"Unknown PEP 3118 data type specifier {stream.s!r}"
)
ValueError: Unknown PEP 3118 data type specifier 'D'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<python-input-4>", line 1, in <module>
np.array(a)
~~~~~~~~^^^
ValueError: 'D' is not a valid PEP 3118 buffer format string
Yeah, in retrospect it seems it was unwise for Python to reject the "additions to the struct syntax" part of the PEP without providing a syntax for complex numbers....
The PEP states clearly the Zd syntax (at the time D didn't exist after all)? And it doesn't seem so terrible...
Did Python notice that it breaks with that precedence or did this just sneak in as following the struct module?
Not that I am sure it is a big issue, importing one can certainly add trivially. But exporting we can't change unless everyone else understands D (unless we force everyone to switch over for 3.15? Doesn't seem great either.).
Python would argue that a PEP is just a proposal, and the Z prefix was deliberately rejected. The PEP link you gave above is to a historical document, not to canonical documentation. (Hey, don't shoot the messenger! I'm not saying NumPy was wrong to adopt the Z prefix--it was the only thing that had been suggested, so why invent some other syntax?)
The struct module added support for the 'F' and 'D' formats in Python 3.14. Also, it supports 'e' since Python 3.6.
The array module adds support for 'F' and 'D' in Python 3.15. Also, Python 3.15 adds half-precision 'e'.
The ctypes module supports 'F', 'D', 'G'. I've seen discussion on adding 'e' and saw no objections--it's just a matter of time to get it done.
I would say it is canonical and NumPy is more of a canonical implementation for it than Python itself. I have no problem accepting to override the PEP, but the PRs don't actually discuss any of it, so right now it isn't clear to me "their" opinion is (i.e. I am not even sure anyone has an opinion on it yet).
I asked on the PR, but should probably escalate to an issue just to clarify things.
I asked on the PR, but should probably escalate to an issue just to clarify things.
I don't think that issue is an appropriate format right now. Better to discuss this first on d.p.o with a wider audience.
For me it seems, that this part of the PEP wasn't discussed during it's review. That's why it's not a specification at all, even for complex types alone.
You are correct; the Python standard library array does not support 'D':
>>> import array
>>> a = array.array('D', [1.0+2.0j, 3.0+4.0j])
Traceback (most recent call last):
File "<python-input-1>", line 1, in <module>
a = array.array('D', [1.0+2.0j, 3.0+4.0j])
ValueError: bad typecode (must be b, B, u, w, h, H, i, I, l, L, q, Q, e, f, d, Zf or Zd)
Activity
jorenham commentedon Apr 10, 2026
Related: #28360
hpkfft commentedon Apr 12, 2026
Note that for exporting from NumPy using the buffer protocol,
"Zd"is specified rather than"D".numpy/numpy/_core/src/multiarray/buffer.c
Lines 396 to 398 in 3cd33b1
seberg commentedon Apr 12, 2026
Hummm, yeah, I guess since Python added those to the
structmodule it makes sense to support them at import (even if that means two names).We cannot change the export, Python is the one that is deviating from the buffer protocol PEP, even if that part never made it to the docs: https://peps.python.org/pep-3118/#additions-to-the-struct-string-syntax
hpkfft commentedon Apr 12, 2026
Yeah, in retrospect it seems it was unwise for Python to reject the "additions to the struct syntax" part of the PEP without providing a syntax for complex numbers....
seberg commentedon Apr 12, 2026
The PEP states clearly the
Zdsyntax (at the timeDdidn't exist after all)? And it doesn't seem so terrible...Did Python notice that it breaks with that precedence or did this just sneak in as following the
structmodule?Not that I am sure it is a big issue, importing one can certainly add trivially. But exporting we can't change unless everyone else understands
D(unless we force everyone to switch over for 3.15? Doesn't seem great either.).hpkfft commentedon Apr 12, 2026
Python would argue that a PEP is just a proposal, and the
Zprefix was deliberately rejected. The PEP link you gave above is to a historical document, not to canonical documentation. (Hey, don't shoot the messenger! I'm not saying NumPy was wrong to adopt theZprefix--it was the only thing that had been suggested, so why invent some other syntax?)The struct module added support for the
'F'and'D'formats in Python 3.14. Also, it supports'e'since Python 3.6.The array module adds support for
'F'and'D'in Python 3.15. Also, Python 3.15 adds half-precision'e'.The ctypes module supports
'F','D','G'. I've seen discussion on adding'e'and saw no objections--it's just a matter of time to get it done.seberg commentedon Apr 12, 2026
I would say it is canonical and NumPy is more of a canonical implementation for it than Python itself. I have no problem accepting to override the PEP, but the PRs don't actually discuss any of it, so right now it isn't clear to me "their" opinion is (i.e. I am not even sure anyone has an opinion on it yet).
I asked on the PR, but should probably escalate to an issue just to clarify things.
jorenham commentedon Apr 12, 2026
I just ran into a related CPython bug: python/cpython#148464
hpkfft commentedon Apr 12, 2026
Regarding PEP 3118, see also: python/peps#4200
As you know, there's also a Python discussion about the buffer protocol and arbitrary types
skirpichev commentedon Apr 13, 2026
JFR, here this conversation: python/cpython#146237 (comment)
I don't think that issue is an appropriate format right now. Better to discuss this first on d.p.o with a wider audience.
For me it seems, that this part of the PEP wasn't discussed during it's review. That's why it's not a specification at all, even for complex types alone.
hpkfft commentedon May 8, 2026
In Python 3.15.0b1, NumPy can both import and export Python standard library arrays:
So, I will close this enhancement request. (Feel free to reopen if I'm missing something.)
seberg commentedon May 8, 2026
Since you got it running, does it also work for:
my impression from the PR was it doesn't.
But yeah... I guess it is settled to the point where we probably don't have to do anything.
hpkfft commentedon May 8, 2026
You are correct; the Python standard library
arraydoes not support'D':See also: #28360 (comment)
seberg commentedon May 8, 2026
Ah, OK, sorry. At some point it had looked like they support both side by side, and I thought that would go into the buffer protocol. Nvm, then.