Python object methods get lost somewhere in the JS side #1336
-
Hey folks, The point of the PR is to separate event handling in two ways:
For 1 here is an example of a code that should work: <br><button py-click-code="print('should work: this is a good use of py-click-code')" id="6">non_callable_no_dec py-click-code</button>< For 2 here is an example that should work: <br><button py-click="no_event_dec" id="3">no_event_dec py-click</button><br> With the impl. of @when("click", id="3")
def no_event_dec():
print(f"should work: I've clicked no_event_dec, and it ran with no arguements") Currently, we're facing the following problem: every time we use the def when(event=None, id=None):
"""
Decorates a function and passes py-* events to the decorated function
The events might or not be an argument of the decorated function
"""
def decorator(func):
element = js.document.getElementById(id)
sig = inspect.signature(func)
# Function doesn't receive events
if not sig.parameters:
def wrapper(*args, **kwargs):
func()
proxy = create_proxy(wrapper)
element.addEventListener(event, cast(wrapper, proxy))
else:
proxy = create_proxy(func)
element.addEventListener(event, func)
return decorator We lost methods like <br><button py-click-code="missuse_no_event_no_dec" id="1">missuse_no_event_no_dec py-click-code</button><br> And the definition of def missuse_no_event_no_dec():
print(f"should error: I've clicked no_event_no_dec, and it ran with no arguements") As you can see the code above should fail, because this is a callable being used with the However if you decorate this code: @when("click", id="1")
def missuse_no_event_no_dec():
print(f"should error: I've clicked no_event_no_dec, and it ran with no arguements") It will succeed because in JS side this function will no longer be identified as callable. (and this shouldn't happen!) I'm not sure what's wrong in the Python side. I've tried to use Pyodide's If you run the examples in Marking @hoodmane here because I think he's the one that has better chances in knowing what's up? But please, if anyone feel inclined would love your help too. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Thanks for all your work on this @marimeireles - I'm digging through it now, just want to make sure I'm understanding the examples in <br><button py-click="no_event_dec" id="3">no_event_dec py-click</button><br>
<py-script>
@when("click", id="3")
def no_event_dec():
print(f"should work: I've clicked no_event_dec, and it ran with no arguements")
</py-script> This is redundant, right? There's no reason to use the Smaller thing: <!-- the reason why this prints is bc of the way we eval it to try to figure it out if it's callable or not
it always runs it with the eval() function
we need to find a new way of evaluating? -->
<br><button py-click="print('should error: this is a py-click misuse')" id="5">missuse_non_callable_no_dec py-click</button><br> This is something that came up at the offsite; my personal feeling is that it's fine for the expression to produce side effects (like printing) for now, as long as it also shows an error, and we can improve the name resolution later if we decide it's necessary. |
Beta Was this translation helpful? Give feedback.
-
Is it possible that the problem is that you forgot to return the function from the decorator? I think a reasonable decorator should look as follows: def when(event=None, id=None):
def decorator(func):
element = js.document.getElementById(id)
sig = inspect.signature(func)
# Function doesn't receive events
if not sig.parameters:
def wrapper(*args, **kwargs):
func()
proxy = create_proxy(wrapper)
element.addEventListener(event, cast(wrapper, proxy))
else:
proxy = create_proxy(func)
element.addEventListener(event, func)
return func # <============================================ added this line
return decorator |
Beta Was this translation helpful? Give feedback.
Is it possible that the problem is that you forgot to return the function from the decorator? I think a reasonable decorator should look as follows: