PythonMonkey icon indicating copy to clipboard operation
PythonMonkey copied to clipboard

Add `.new` Method to JavaScript Clases

Open wiwichips opened this issue 2 years ago • 3 comments

Describe your feature request here.

Class.new

Feature Request: add a new static method to classes exposed to Python to instantiate JavaScript classes. Code example:

import pythonmonkey as pm
JsDateClass = pm.Date

myDate = JsDateClass.new(0) # in JS this would look like: myDate = new JsDateClass(0);

Relevant Context

Unlike JavaScript, Python doesn't use the new keyword (or anything like it) for instantiating classes. For example:

class SomeClass:
    pass
obj = SomeClass()

However, JavaScript "classes" may require the new keyword to properly setup the object. ES6 classes will throw an error if not instantiated with new.

So we needed to provide a way for Python to instantiate JavaScript classes and chose to add a new function to the PythonMonkey api which returns a function wrapper for the constructor function which can be used to instantiate the class as if it were called with new. See the relevant ticket here: https://github.com/Distributive-Network/PythonMonkey/issues/144

This topic was debated in the TC39 forums here: https://es.discourse.group/t/function-prototype-new/1772 ; however, the community does not appear to be very unified on this subject. @WebReflection suggested adding Class.new to the JS spec

Pyodide uses Class.new to solve this, refer to the Pyodide documentation here: https://pyodide.org/en/stable/usage/api/python-api/ffi.html#pyodide.ffi.JsProxy.new

  • PythonMonkey should have a similar API spec to Pyodide
  • These products will likely be used together for instance with PythonMonkey on the server and Pyodide in the browser

Code example

import pythonmonkey as pm

myDate = pm.Date.new(0)

wiwichips avatar Sep 15 '23 13:09 wiwichips

FWIWI MicroPython in WASM also supports this syntax and it's great to see alignment around this tiny, yet huge, detail.

Thank You!

WebReflection avatar Sep 15 '23 14:09 WebReflection

@WebReflection Do you have any insight as to the implementation details in other platforms? A couple of ways to do this pop in my mind right away:

  1. add non-enumerable Function.prototype.new in JS-land
  2. intercept property access to new on JSFunction * from Python

I'm sort of leaning toward #1 due to simplicity, but it would have observable side effects in JS.

wesgarland avatar Sep 19 '23 12:09 wesgarland

Hi @zanxueyan, sorry to hear you're having issues. Let's discuss this in the other thread: https://github.com/Distributive-Network/PythonMonkey/issues/170

wiwichips avatar Sep 28 '23 20:09 wiwichips