-
Notifications
You must be signed in to change notification settings - Fork 30
ClassWrap
Exposing D classes to Python is easy! The heart of Pyd's class wrapping features is the wrap_class function template.
Calls to wrap_class must occur after calling module_init.
|**Python member type**| ** D member type** | **Pyd Param** | static function | static function | StaticDef!(Foo.fun) | instance function | instance function | Def!(Foo.fun) | property | instance function or instance property | Property!(Foo.fun) | instance field | instance field | Member!(fieldname)
The following operators may be wrapped: |**Operator** | **D function** | **Pyd Param** | + - * / % ~^^ << >> & ^ ~| ~ | opBinary!(op) | OpBinary!(op) | + - * / % ~^^ << >> & ^ ~| ~ in | opBinaryRight!(op) | OpBinaryRight!(op) | += -= *= /= %= ~^^= <<= >>= &= ^= ~|= ~~= | opOpAssign!(op) | OpAssign!(op) | + - ~ | opUnary!(op) | OpUnary!(op) | < <= > >= | opCmp | OpCompare!() | a[i] | opIndex | OpIndex!() | a[i] = b | opIndexAssign | OpIndexAssign!() | a[i] (python ) | opSlice | OpSlice!() | a[i] = b | opSliceAssign | OpSliceAssign!() | a(args) | opCall | OpCall!(Args) | a.length (python ) | length | Len!()
The usual rules for function wrapping apply: Only an opFunc whose return type and arguments are convertable may be wrapped. (The current implementation is pretty dumb: If the specified opFunc has an unconvertable return type or argument, the operator overload will still be wrapped, but won't work.)
- Only one overload is permitted per operator; however OpBinary and OpBinaryRight may "share" an operator.
- **opSlice, opSliceAssign**:
Pyd only supports these overloads if both of their two indexes are implicitly convertable to type Py_ssize_t. This is a limitation of the Python/C API. Note that this means the zero-argument form of opSlice (for allowing the "empty slice," e.g. foo[]) cannot be wrapped. (I may work around this in the future.) In the presence of multiple overloads, Pyd is capable of selecting the appropriate one.
- **~~, ~~=**:
Python does not have a dedicated array concatenation operator. The plus sign (+) is reused for this purpose. Therefore, odd behavior may result with classes that define both opAdd/opAddAssign and one or both of these operators. (Consider yourself warned.) However, the Python/C API considers addition and concatenation distinct operations, and so both of these sets of operator overloads are supported.
- **in**:
Python expects the in operator to return a boolean value (it is a containment test). D convention is for in to search for the value in the container, and to return a pointer to the found item, or null if the item is not found. That said, D does not enforce any particular signature on the in overload, while the Python/C API does. Pyd will check the boolean result of a call to the in overload, and return that value to Python.
A wrapped class can be made iterable in python by supplying Defs with the python names:
- which should return this.
- which should return the next item, or null for termination. Signature must be .
Suppose we have the following simple class:
We would expose this class to Python by putting this code in PydMain after the call to module_init:
Now we can use this type from within Python like any other type.