Exposing D classes to python

The heart of PyD’s class wrapping features is the class_wrap function template.

Member wrapping

Python member type D member type PyD Param
instance function instance function Def!(Foo.fun)
static function static function StaticDef!(Foo.fun)
property instance function or property Property!(Foo.fun)
instance field instance field Member!(fieldname)
constructor constructor Init!(Args...)
Notes
  • Def and StaticDef behave very much like def
  • Init doesn’t take named parameters
  • Member takes a string, not an alias

Def template arguments

Docstring

See Docstring

PyName

See PyName

StaticDef template arguments

Docstring

See Docstring

PyName

See PyName

Property template arguments

Docstring

See Docstring

PyName

See PyName

Mode

Specify whether property is read-only, write-only, or read-write.

Possible values: "r", "w", "rw", ""

When "", determine mode based on availability of getter and setter forms.

Default: ""

Member template arguments

Mode

See Mode

Operator Overloading

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 .. j] (python a[i:j]) opSlice OpSlice!()
a[i .. j] = b (python a[i:j] = b) opSliceAssign OpSliceAssign!()
a(args) opCall OpCall!(Args)
a.length (python len(a)) length Len!()
Notes on wrapped operators
  • only one overload is permitted per operator; however OpBinary and OpBinaryRight may “share” an operator.
  • PyD only supports opSlice, opSliceAssign if both of their two indices are implicitly convertable to Py_ssize_t. This is a limitation of the Python/C API. Note this means the zero-argument form of opSlice (foo[]) cannot be wrapped.
  • ~, ~=: Python does not have a dedicated array concatenation operator. + is reused for this purpose. Therefore, odd behavior may result with classes that overload both + and ~. The Python/C API does consider addition and concantenation to be distinct operations, though.
  • in: Semantics vary slightly. In python, in is a containment test and retursn a bool. In D, by convention in is a lookup, returning a pointer or null. PyD will check the boolean result of a call to the overload and return that value to Python.

Iterator wrapping

A wrapped class can be make iterable in python by supplying defs with the python names:

  • __iter__, which should return this.
  • next, which should return the next item, or null to signal termination. Signature must be PyObject* next().

Alternatively, you can supply a single __iter__ that returns a Range.