PythonMonkey
PythonMonkey copied to clipboard
object prototype chaining does not work correctly on proxied python objects
Describe your feature request here.
Proxied python objects currently do not have a proper prototype chain, and we are instead mimicking prototype chain behaviour by special-casing [[GetOwnPropertyDescriptor]] when the prop name is equal to a default prop name on the intended prototype.
For example, in:
import pythonmonkey as pm
l = [1, 2, 3]
pm.eval("(l) => l.pop()")(l)
l.pop
is accomplished by us intercepting prop lookup on l
, seeing that the prop name is "pop"
, and passing back our own implementation of pop
that is special-cased for python lists. This has some interesting consequences:
pm.eval("(l) => Object.getPrototypeOf(l) === Array.prototype")(l) # True
pm.eval("(l) => l.pop === Array.prototype.pop")(l) # False, should be True
pm.eval("(l) => l.pop === l.pop")(l) # False!!, should DEFINITELY be True
I propose that we define our own classes/prototypes for our proxied objects, and have those classes/prototypes inherit from the respective mimicked types, like so:
listObject = []
dictObject = []
bytesObject = b""
iterObject = iter(())
class Class:
pass
classObject = Class()
pm.eval("""
(listObject, dictObject, bytesObject, iterObject, classObject) => {
assert(Object.getPrototypeOf(listObject) === PyListProxy.prototype);
assert(Object.getPrototypeOf(dictObject) === PyDictProxy.prototype);
assert(Object.getPrototypeOf(bytesObject) === PyBytesProxy.prototype);
assert(Object.getPrototypeOf(iterObject) === PyIterProxy.prototype);
assert(Object.getPrototypeOf(classObject) === PyObjectProxy.prototype); // would be interesting if we could get python class
inheritance to be represented in the prototype chain with proxied Classes, though I don't think that's currently in scope, particularly since Python has true multiple inheritance
assert(Object.getPrototypeOf(PyListProxy.prototype) === Array.prototype);
assert(Object.getPrototypeOf(PyDictProxy.prototype) === Object.prototype);
assert(Object.getPrototypeOf(PyBytesProxy.prototype) === Uint8Array.prototype);
assert(Object.getPrototypeOf(PyIterProxy.prototype) === Object.prototype);
assert(Object.getPrototypeOf(PyObjectProxy.prototype) === Object.prototype);
}
""")(listObject, dictObject, bytesObject, iterObject, classObject)
Code example
No response