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
toJSONandfromJSONmethods 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.classmethodorpy.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.objectto compare this object withReturns: py.bool
-
__ne__(other)¶ The default implementation calls
__eq__()and reverses its result.Parameters: other – py.objectto compare this object withReturns: py.bool
-
__lt__(other)¶ The default implementation simply returns
py.NotImplemented.Parameters: other – py.objectto compare this object withReturns: py.bool
-
__le__(other)¶ The default implementation simply returns
py.NotImplemented.Parameters: other – py.objectto compare this object withReturns: py.bool
-
__ge__(other)¶ The default implementation simply returns
py.NotImplemented.Parameters: other – py.objectto compare this object withReturns: py.bool
-
__gt__(other)¶ The default implementation simply returns
py.NotImplemented.Parameters: other – py.objectto 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.objectparameter and return a singlepy.objectparameter.Unary operator numeric methods are all supported:
For non-operator numeric methods, support is contingent on the corresponding builtins being implemented