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
ENH PyProxy getattr/etc traps & added getitem/etc for PyMappings #1175
Conversation
ced03e7
to
59b2889
Compare
…ethods for list, dict, PyMapping objects
59b2889
to
df334ad
Compare
Hello @hoodmane,
this change is not much, but what if there's already existing JavaScript code using this notation in other projects using Pyodide? First, I think an entry in the CHANGELOG should not be missing here. Next, maybe, it may help to first declare the old notation as deprecated but still preserve the old behavior, and print a warning to the JS-console. Later on, it can be removed entirely, to make Pyodide-Objects finally more Pythonic in the JavaScript world, instead of this hard cut. What is your (and the others) opinion on this? |
Absolutely. (My plan on documentation is to make a separate PR that just updates the type conversions documentation to reflect many of the #900 changes.)
So far we haven't been bothering with deprecation warnings at all. I am open to the idea of doing deprecation warnings if we agree that it's a good idea, though I think we'd need to discuss how to design the deprecation system. We'll presumably want eventually as pyodide gets more stable so it's probably not wasted effort to set up a system. Perhaps I should open another "Deprecation?? Should we be doing it??" issue. @rth @dalcde Thoughts? For the |
Yeah, let's discuss it in a separate issue. |
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.
Thanks @hoodmane ! It's indeed important to be able to differentiate getattr from getitem in PyProxy.
If I have a Python class that does define the get
method (fairly common), how would I call it via a PyProxy with this PR?
|
||
// Wrap "globals" in a special Proxy that allows `pyodide.globals.x` access. | ||
// TODO: Should we have this? | ||
Module.globals = Module.wrapNamespace(Module.globals); |
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.
Ideally with a warning (maybe with console.warn
), saying we will remove it in 0.18.0.
An excellent question which I don't have a good answer for. Note that at least there is only a name collision if the class implements both |
Oh well at least in the dictionary case, it's not a big deal at all: the only difference between |
So how about this: suppose
If the object has both |
@rth Do you know of other standard objects that define both |
It makes sense, though the issue is when reading code that does
For instance, collections.Counter, queue.Queue. Otherwise pandas.DataFrame.get |
Well |
OK, sounds good. +1 for you proposal in #1175 (comment) |
@rth I think the changes required to implement the "python methods override javascript methods" suggestion are too complicated for this PR, I'm going to open it as a separate PR on top of this one. |
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.
Generally LGTM. Could we just add a test on a class with that subclasses dict, and with a custom get method, and make sure that it doesn't call the __getitem__
method?
class CustomDict(dict):
def get(self, key):
return 1
x = CustomDict(a = 2)
assert x.get(x) == 1 # from JS
Sounds good. By the way, note that Javascript Symbols are often used to add names to a proxy that are guaranteed not to clash with the proxied names. If you define a symbol One sad thing about the current behavior of these proxies is that they leak Python objects like crazy. Like if you say: let namespace = pyodide.globals.dict();
namespace.get("a");
namespace.destroy(); then you've actually leaked |
OK, sounds good. Thanks! |
In javascript
x.a
andx["a"]
do the same thing. For the equivalent of Pythongetitem
, javascript typically usesx.get("a")
. This PR fixes the error handling for the traps forx.a
(which usesgetattr
) and adds new functions likex.get("a")
(which usesgetitem
).This has the effect of changing the way we need to look stuff up onpyodide.globals
: instead ofpyodide.globals.a
, we now need to usepyodide.globals.get("a")
.Edit: I added an extra
Proxy
aroundglobals
so that you can still look up methods using ordinary indexing, to preserve backwards compatibility.