Skip to content

Cause syntax error when assigning to 'var - #39

Open
wonkodv wants to merge 1 commit into
m-ou-se:masterfrom
wonkodv:master
Open

Cause syntax error when assigning to 'var#39
wonkodv wants to merge 1 commit into
m-ou-se:masterfrom
wonkodv:master

Conversation

@wonkodv

Copy link
Copy Markdown

You can cause a Syntaxerror for assignments to rust variables by expanding them to ((lambda:_RUST_var)())

Since the SyntaxError has a very confusing message, the likely cause is appended:

error: python: cannot assign to function call. LIKELY CAUSE: you cannot assign to RUST-Variables, see Context::get_global() instead
--> examples/readonly.rs:6:9
|
6 | 'x = 42;
| ^^^^^^^^
error: aborting due to previous error

The Error message could be improved by inspecting the code it is raised for, but I don't know how to do it reliably.

@de-vri-es

de-vri-es commented Apr 3, 2021

Copy link
Copy Markdown
Contributor

Hey, thanks for the PR. It's an interesting idea.

I think it would be nicer to make the Rust globals an object with read-only properties. One downside for that is that it gives a runtime error when trying to assign, rather than syntax errors. But it's python, so I think people will forgive that. The advantage is that the error message will make more sense, and there's no need to intercept and adjust error messages then.

@wonkodv

wonkodv commented Apr 3, 2021

Copy link
Copy Markdown
Author

My first Idea was to use a new type as locals argument to exec, it does not have to be a dict. Globals have to be a dict. This is how it could look in python:

classReadOnlyRustVariables:
def__init__(self, dict):
self.dict=dictdef__getitem__(self, key):
returnself.dict[key]
def__setitem__(self, key, val):
ifkey.startswith("__rust_var_"):
k=key[len("__rust_var_"):]
raiseTypeError(f"You can not modify the rust-variable '{k} use Context::get_global()")
self.dict[key] =vallocals_=ReadOnlyRustVariables({"__rust_var_x":42})
globals_=vars(__import__("builtins"))
exec("y = __rust_var_x * 2", globals_, locals_)
assertlocals_["y"] ==84, locals_exec("__rust_var_x = __rust_var_x * 2", globals_, locals_)
# TypeError: You can not modify the rust-variable 'x use Context::get_global()

I didn't try this one.

another Idea was to replace 'var with _RUST_IMMUT_VARS['var'] (and maybe #var with _RUST_MUT_VARS['var']).
The two objects could be created in Context::try_new() using inline_python::python! to initialize the python environment like so:

classRustVars: __slots__= ("_dict", "_mutable") def__init__(self, mutable:bool): self._dict=dict() self._mutable=mutabledef__setitem__(self, key, value): ifself._mutable: self._dict[key] =valueelse: raiseTypeError("You are trying to write to "+'\''+key+" which is read-only. Try #"+key) def__getitem__(self, key): returnself._dict[key] _RUST_MUT_VARS=RustVars(True) _RUST_IMMUT_VARS=RustVars(False) delRustVarsfrombuiltinsimport*

I tried implementing the second in rust and failed to run python code when initializing the context.
It's a mess: wonkodv@1a6a51f

When I thought of the lambda trick and found it easy to implement I liked the compile time errors better than runtime errors, even if the Error Message is not perfect.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@wonkodv@de-vri-es