Implementing a custom type¶
To implement a custom python-level type, one can use the
py.type()
builtin. At the JS-level, it is a function with the
same signature as the type
builtin [1]. It returns a
child type of its one base (or py.object
if no base is
provided).
The dict
parameter to py.type()
can contain any
attribute, javascript-level or python-level: the default
__getattribute__
implementation will ensure they are converted to
Python-level attributes if needed. Most methods are also wrapped and
converted to Python-level callable, although there are a number
of special cases:
- Most “magic methods” of the data model (“dunder” methods) remain javascript-level. See the listing of magic methods and their signatures. As a result, they do not respect the Python calling conventions
- The
toJSON
andfromJSON
methods are special-cased to remain javascript-level and don’t follow the Python calling conventions - Functions which have been wrapped explicitly (via
py.PY_def
,py.classmethod
orpy.staticmethod
) are associated to the class untouched. But due to their wrapper, they will use the Python calling conventions anyway
Python-level callable¶
Wrapped javascript function or the __call__()
method itself
follow the Python calling conventions. As a result, they can’t
(easily) be called directly from javascript code. Because
__new__()
and __init__()
follow from __call__()
,
they also follow the Python calling conventions.
py.PY_call()
should be used when interacting with them from
javascript is necessary.
Because __call__
follows the Python calling conventions,
instantiating a py.js
type from javascript requires using
py.PY_call()
.
Python calling conventions¶
The python-level arguments should be considered completely opaque,
they should be interacted with through py.PY_parseArgs()
(to
extract python-level arguments to javascript implementation code) and
py.PY_call()
(to call Python-level callable from
javascript code).
A callable following the Python calling conventions must
return a py.js
object, an error will be generated when failing to
do so.
Magic methods¶
py.js
doesn’t support calling magic (“dunder”) methods of the
datamodel from Python code, and these methods remain javascript-level
(they don’t follow the Python calling conventions).
Here is a list of the understood datamodel methods, refer to the relevant Python documentation for their roles.
Basic customization¶
-
__hash__
()¶ Returns: String
-
__eq__
(other)¶ The default implementation tests for identity
Parameters: other – py.object
to compare this object withReturns: py.bool
-
__ne__
(other)¶ The default implementation calls
__eq__()
and reverses its result.Parameters: other – py.object
to compare this object withReturns: py.bool
-
__lt__
(other)¶ The default implementation simply returns
py.NotImplemented
.Parameters: other – py.object
to compare this object withReturns: py.bool
-
__le__
(other)¶ The default implementation simply returns
py.NotImplemented
.Parameters: other – py.object
to compare this object withReturns: py.bool
-
__ge__
(other)¶ The default implementation simply returns
py.NotImplemented
.Parameters: other – py.object
to compare this object withReturns: py.bool
-
__gt__
(other)¶ The default implementation simply returns
py.NotImplemented
.Parameters: other – py.object
to compare this object withReturns: py.bool
-
__str__
()¶ Simply calls
__unicode__()
. This method should not be overridden,__unicode__()
should be overridden instead.Returns: py.str
-
__unicode__
()¶ Returns: py.unicode
Customizing attribute access¶
-
__getattribute__
(name)¶ Parameters: name (String) – name of the attribute, as a javascript string Returns: py.object
Implementing descriptors¶
Emulating Numeric Types¶
Non-in-place binary numeric methods (e.g.
__add__
,__mul__
, ...) should all be supported including reversed calls (in case the primary call is not available or returnspy.NotImplemented
). They take a singlepy.object
parameter and return a singlepy.object
parameter.Unary operator numeric methods are all supported:
For non-operator numeric methods, support is contingent on the corresponding builtins being implemented