Fabio Manganiello on Nostr: It looks like runtime context evaluation in YAML procedures/hooks in #Platypush is ...
It looks like runtime context evaluation in YAML procedures/hooks in #Platypush is broken as of #Python 3.13 - reference issue.
I’ve noticed it today after upgrading one of my nodes to Python 3.13, and its hooks suddenly stopped working.
As of Python 3.13, it’s no longer allowed to set local variables via locals(), or exec()/eval(), so the following code breaks on the latest version:
>>> def f():
... exec('foo="bar"')
... print(foo)
...
>>> f()
Traceback (most recent call last):
File "<python-input-3>", line 1, in <module>
f()
~^^
File "<python-input-2>", line 3, in f
print(foo)
^^^
NameError: name 'foo' is not defined
Whereas it works on previous versions:
>>> def f():
... exec('foo="bar"')
... print(foo)
...
>>> f()
bar
I know that manually setting local variables by assigning keys to locals() or via exec/eval isn’t pretty, it’s a quite nasty abuse of a side effect, and it makes the code harder to debug.
But there are legit cases too. For example, Platypush allows to define event hooks in YAML this way:
event.hook.LogLatLongUpdate:
if:
type: platypush.message.event.geo.LatLongUpdateEvent
then:
- action: procedure.store_location_data
args:
latitude: ${latitude}
longitude: ${longitude}
altitude: ${altitude}
Where latitude, longitude and altitude, in this case, are parsed from the incoming event, assigned at runtime to local variables, and then the execution flow can just expand them on the fly.
Apparently this flow is no longer allowed.
I’ll investigate for workarounds (globals() doesn’t seem to be impacted, but I definitely don’t want to mess up with global variables), because at the current stage all those occurrences need to be replaced with e.g. ${context["event"].latitude} - still ok-ish, but definitely less readable.
I’m also a bit disappointed that such a breaking change wasn’t properly announced - sure, people shouldn’t mess up with the local variables of the interpreter at runtime, but there are legit cases that were worth discussing, and alternatives could have been provided, rather than seeing some code break from a day to another and getting a “sorry, you were never supposed to do this” as an answer.
I’ve noticed it today after upgrading one of my nodes to Python 3.13, and its hooks suddenly stopped working.
As of Python 3.13, it’s no longer allowed to set local variables via locals(), or exec()/eval(), so the following code breaks on the latest version:
>>> def f():
... exec('foo="bar"')
... print(foo)
...
>>> f()
Traceback (most recent call last):
File "<python-input-3>", line 1, in <module>
f()
~^^
File "<python-input-2>", line 3, in f
print(foo)
^^^
NameError: name 'foo' is not defined
Whereas it works on previous versions:
>>> def f():
... exec('foo="bar"')
... print(foo)
...
>>> f()
bar
I know that manually setting local variables by assigning keys to locals() or via exec/eval isn’t pretty, it’s a quite nasty abuse of a side effect, and it makes the code harder to debug.
But there are legit cases too. For example, Platypush allows to define event hooks in YAML this way:
event.hook.LogLatLongUpdate:
if:
type: platypush.message.event.geo.LatLongUpdateEvent
then:
- action: procedure.store_location_data
args:
latitude: ${latitude}
longitude: ${longitude}
altitude: ${altitude}
Where latitude, longitude and altitude, in this case, are parsed from the incoming event, assigned at runtime to local variables, and then the execution flow can just expand them on the fly.
Apparently this flow is no longer allowed.
I’ll investigate for workarounds (globals() doesn’t seem to be impacted, but I definitely don’t want to mess up with global variables), because at the current stage all those occurrences need to be replaced with e.g. ${context["event"].latitude} - still ok-ish, but definitely less readable.
I’m also a bit disappointed that such a breaking change wasn’t properly announced - sure, people shouldn’t mess up with the local variables of the interpreter at runtime, but there are legit cases that were worth discussing, and alternatives could have been provided, rather than seeing some code break from a day to another and getting a “sorry, you were never supposed to do this” as an answer.