Initially, NumPy support suffered heavily from
- wrong documentation
- implementation of arbitrary APIs
- mismatch between C++/XML and the Python signatures.
Meanwhile, several actions have been performed:
- error messages are created in Python, using the signature module
- object protocols are more consequently using PySequence
- signatures support the <array\> attribute for primitive type pointers
- signatures understand generic types like List[t], Sequence[t] and Iterator[t]
Still, there are oversights and omissions. For instance:
This works fine with Python2.
With Python3, this gives a crash. Why?
- range(16) is a List object in Python2
- range(16) is a lazy Sequence object in Python3. This is almost like the xrange object in Python2.
Full discussion of Python 3's range compared with Python2's xrange function can be found in https://treyhunner.com/2018/02/python-3-s-range-better-than-python-2-s-xrange/.
There is a common misunderstanding concerning range, because it has lazy behavior, but is not an iterator! I reant that distiction myself after reading https://treyhunner.com/2018/02/python-range-is-not-an-iterator/..
The fix is very simple, btw.
All array-like interfaces that use typing.List or typing.Sequence[t] will be changed to support the most general typing.Iterable[t] API. What does that mean?
The iterator protocol is partially quite complicated and partially quite easy.
- Complicated: Create objects that support the iterator protocol.
- Easier: Interface to objects that support typing.Iterable.
We restrict ourselves to the easy part: If an object supports it, then we use the iterator protocol.
Example: We will be able to use iter(range(16)) for the data of a QMatrix4x4 object.
The distinction between iterables and sequences is not tied to some explizit type.
Python uses duck typing, instead: https://en.wikipedia.org/wiki/Duck_typing.
This is the previous analysis
PySide needs to be more user-friendly when interfacing to other packages.
The most prominent example is NumPy, but it applies to other packages like SciPy, Pandas and MatPlotLib as well.
After looking into this issue, it appears to be a two-fold problem:
a) Many types support only List instead of allowing any sequence,
b) The error messages are extremely misleading and wrong.
There are many locations where PySide accepts a list only, although a sequence would be ok as well. That would allow for many new container types from NumPy, for instance.
This example says it uses a set, but it does not work:
The same with the function fromVector does of course not allow an arbitrary sequence.
but gives a very unintuitive error message.
I propose to either
- allow arbitrary sequences here, or
- add a new method fromSequence.
That would then work with any extension that uses the sequence protocol.
When trying to find negative examples for a), I stumbled surprisingly into examples for b). PySide already supports interfacing to other packages by using abstract protocols.
See the following example:
Here is the example that gives the impression that NumPy is not supported:
This problem seems to apply to the matrices, only. The error messages are very wrong, because the general sequence protocol is supported, but it says list. When you look at the file
instead, you see that it says sequence instead. But this is also still not completely correct, since the signature module needs more work on correct types, too.
My impression is that before adding a new sequence support that serves many extensions, we should try to
- improve error messages (re-write them using the signature module)
- write a tool that checks every function signature for functionality.
When that is working well enough that we can trust error messages, then we should think of new functionality.
Maybe the topic of this task needs to be changed?
|For Gerrit Dashboard: PYSIDE-795|
|253625,27||Support Pointer Primitive Types by Arrays or Result Tuples||5.12||pyside/pyside-setup||Status: NEW||0||0|
|267337,2||Improve NumPy Support||5.12||pyside/pyside-setup||Status: NEW||0||0|
|267338,6||Improve NumPy Support||5.12||pyside/pyside-setup||Status: NEW||0||0|