-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Object methods use incorrect this
#172
Comments
@zanxueyan ran into a byproduct of this bug described in this message here: #170 (comment) It can be described by this minimal repro: import pythonmonkey as pm
pm.eval("""
class Human {
constructor(name)
{
this.name = name;
}
setName(name)
{
this.name = name;
}
getName()
{
return this.name;
}
}
""")
Human = pm.eval('Human')
person = pm.new(Human)('Will')
# setting it using setName
person.setName('Joe')
print(person.getName()) # prints "Joe"
print(person.name) # prints "Will" but should print "Joe"!!!
print(person['name']) # prints "Will" but should print "Joe"!!!
# now try setting it directly
person.name = "Liang"
print(person.getName()) # prints "Joe"
print(person.name) # prints "Liang"!!!
print(person['name']) # prints "Liang"!!! since |
I don't think this issue should be closed just yet, as while the specific above minimal repro is no longer an issue, there are still cases where the "wrong" In JS, a function always has However in python, there are both functions and methods as distinct types. Python functions are equivalent to, and have similar behaviour as, JS Functions except that they do not have an equivalent to import types
class MyClass:
def pyMeth(self, arg1, arg2):
print(arg1)
print(arg2)
return self
pyObj = MyClass()
result = pyObj.pyMeth("Hello", "World) # result is pyObj
pyDict1 = {"pyMeth": pyObj.pyMeth}
pyDict2 = {"pyMeth": MyClass.pyMeth}
pyDict3 = {}
pyDict3["pyMeth"] = types.MethodType(MyClass.pyMeth, pyDict3)
print(pyObj.pyMeth) # <bound method MyClass.pyMethod of <pyObj>>
print(pyDict1["pyMeth"]) # <bound method MyClass.pyMethod of <pyObj>> (NOT bound to pyDict1)
print(pyDict2["pyMeth"]) # <function MyClass.pyMeth> (NOT bound to anything)
print(pyDict3["pyMeth"]) # <bound method MyClass.pyMethod of <pyDict3>> (bound to pyDict3)
result = pyDict1["pyMeth"]("Hello", "World") # result is pyObj, NOT pyDict1
# result = pyDict2["pyMeth"]("Hello", "World") # results in "missing 1 required positional argument: 'self'" TypeError
result = pyDict3["pyMeth"]("Hello", "World") # result is pyDict3 Importantly there is no such thing as an unbound method in python, a method is bound to an object immediately when it is created, and the only way to get a function bound to another object is to manually create a new method object. Below is an example of the consequences of this for pythonmonkey: import pythonmonkey as pm
pm.eval("""
class Human {
constructor(name)
{
this.name = name;
}
setName(name)
{
this.name = name;
}
getName()
{
return this.name;
}
}
""")
Human = pm.eval('Human')
person = pm.new(Human)('Will')
# setting it using setName
person.setName('Joe')
print(person.getName()) # prints "Joe"
print(person.name) # prints "Joe"
print(person['name']) # prints "Joe"
# now try setting it directly
person.name = "Liang"
print(person.getName()) # prints "Liang"
print(person.name) # prints "Liang"
print(person['name']) # prints "Liang"
pyPerson = { "name": "John", "getName": person.getName, "setName": person.setName}
# setting it using setName
pyPerson["setName"]("Jeremy")
print(pyPerson["getName"]()) # prints "Jeremy"
print(pyPerson["name"]) # prints "John"
# now try setting it directly
pyPerson["name"] = "Claude"
print(pyPerson["getName"]()) # prints "Jeremy"
print(pyPerson["name"]) # prints "Claude" My branch #227 introduces a new type called |
@caleb-distributive let's make sure the default code resolves the issue listed initially above and the one listed in #58 |
Issue type
Bug
How did you install PythonMonkey?
Installed from pip
OS platform and distribution
Ubuntu 22.04
Python version (
python --version
)Python 3.10.12
PythonMonkey version (
pip show pythonmonkey
)0.2.1
Bug Description
When calling the method of a class,
this
in the scope of the function is globalThis and not the function'sthis
example.js
main.py
--- When I run
python3 main.py
I get the following output:getArea
returnsnan
becauseglobalThis.w === undefined
andundefined * undefined = NaN
,getThis
returns globalThis becausethis
is not set to the objectthis
.Standalone code to reproduce the issue
Relevant log output or backtrace
Additional info if applicable
No response
What branch of PythonMonkey were you developing on? (If applicable)
No response
The text was updated successfully, but these errors were encountered: