-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
webassembly/objpyproxy: Avoid throwing on symbols or iterator. #17604
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
Conversation
952ac8b
to
ebd9662
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #17604 +/- ##
=======================================
Coverage 98.56% 98.56%
=======================================
Files 169 169
Lines 21946 21946
=======================================
Hits 21632 21632
Misses 314 314 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
for quick check about current state VS state after this MR (published on my npm account with same version + this MR in) and for history sake, here a test that shows the issue: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MicroPython VS JS Symbols</title>
<script type="module">
import { loadMicroPython } from 'https://cdn.jsdelivr.net/npm/@micropython/micropython-webassembly-pyscript/micropython.mjs';
// change this with webreflection instead to see it working -- ^^^^^^^^^^^
import codedent from 'https://esm.run/codedent';
const mpy = await loadMicroPython();
// sync or async it doesn't matter
await mpy.runPythonAsync(codedent(document.querySelector('script[type=micropython]').textContent));
</script>
<script>
globalThis.hasSymbol = (symbol, ref) => symbol in ref;
globalThis.getSymbol = (symbol, ref) => ref[symbol];
// some 3rd party JS library might use symbols to brand-check
// so it's not about symbols traveling from MicroPython
// it's about MicroPython proxies traps not understanding symbols
globalThis.hasIterator = ref => Symbol.iterator in ref;
</script>
<script type="micropython">
import js
# change this to Symbol.toStringTag to see it throwing all over
symbol = js.Symbol.iterator
# this passes only with Symbol.iterator
print('get', js.getSymbol(symbol, []))
# these both fail miserably
print('has', js.hasSymbol(symbol, []))
print('direct', js.hasIterator([]))
</script>
</head>
</html> |
Thanks for the patch. Was this a regression that worked in a prior version? |
Yes, it's a regression. If you compare MicroPython bundled in the previous version of PyScript 2025.5.1 with current PyScript (2025.7.1) there's a difference in behaviour. |
I don't think so ... I've never seen
that's my miscommunication ... the regression is introduced in our latest PyScript because we use better primitives to handle worker/main use cases and those better primitives revealed this issue with MicroPython which has been broken to date but now it starts hurting when paired with more modern libraries and code. As mentioned in Discord, there's much more to do to have MicroPython fully handling symbols but for the time being, at least having it not throwing and return |
@WebReflection ah, my bad. I misconstrued the context. The MicroPython/JS proxy dance could be something to discuss in our next call (21st July)..? I think if we (PyScript - i.e. Andrea) can contribute back to upstream MicroPython we're telling and embodying a good FLOSS open source story. |
@dpgeorge last time this was touched is in here: #15293 I should've reviewed that (or provided hints around this topic) ... symbols are very special (and weird) beast in JS and particularly from workers these cannot ever travel but even on main we have issues in checking if special, libraries defined, symbols are present in objects to simply brand check these or guard against undesired access (private symbols in JS are also a thing, these are all This MR prevents those checks from failing but it also grant that the only one understood and implemented in the edid I did review that and forgot checking the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fix looks good to me, and the new test covers the new code and passes.
JavaScript code uses "Symbol in object" to brand check its own proxies, and such checks should also work on the Python side. Signed-off-by: Andrea Giammarchi <[email protected]>
Bravo and thank you..! Has this made it into a release..? |
Yes: https://www.npmjs.com/package/@micropython/micropython-webassembly-pyscript/v/1.26.0-preview-293 |
Awesome work. As always. 🎉 |
Not only our latest stack uses internally symbols to brand check its own proxies, there are various 3rd party libraries that might perform similar checks and you also have:
in your
get
trap but a check before such as:would fail with an error that states that a string was expected but a symbol was received.
This MR would like to fix the situation for at least known symbols you also handle internally.
Summary
Testing
Trade-offs and Alternatives