Skip to content
Laeeth Isharc edited this page Mar 19, 2015 · 2 revisions

Table of Contents

Class Wrapping

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.

See also

pyd.class_wrap

Member wrapping

|**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)

Operator Overloading

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.)

Notes on wrapped operators

  • 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. 

Iterator wrapping

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 .
Alternately, you can supply a Def with only and have it return a Range that iterates your object.

Examples

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.

Clone this wiki locally