Skip to content

Proper construction of scope for exec/eval. #590

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

Merged
merged 5 commits into from
Mar 4, 2019
Merged

Proper construction of scope for exec/eval. #590

merged 5 commits into from
Mar 4, 2019

Conversation

cthulahoops
Copy link
Collaborator

One case I couldn't handle is that the following is valid in CPython.

>>>>> exec("print(x)", None, {'x': 2})
Traceback (most recent call last):
  File <stdin>, line 0, in <module>
TypeError: argument of type <class 'dict'> is required for parameter 2 (globals) (got: <class 'NoneType'>)

arg_check! needs to allow None and treat it as if the optional argument wasn't passed. I don't know what other builtins have this behaviour.

@codecov-io
Copy link

codecov-io commented Mar 3, 2019

Codecov Report

Merging #590 into master will increase coverage by 2.14%.
The diff coverage is 46.66%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #590      +/-   ##
==========================================
+ Coverage   41.61%   43.75%   +2.14%     
==========================================
  Files          74       74              
  Lines       16762    17228     +466     
  Branches     4406     4671     +265     
==========================================
+ Hits         6975     7538     +563     
+ Misses       7781     7594     -187     
- Partials     2006     2096      +90
Impacted Files Coverage Δ
vm/src/builtins.rs 35.21% <38.23%> (-8.63%) ⬇️
vm/src/vm.rs 52.72% <71.42%> (+1.02%) ⬆️
vm/src/frame.rs 47.16% <75%> (+0.05%) ⬆️
vm/src/function.rs 66.66% <0%> (-4.77%) ⬇️
vm/src/pyobject.rs 71.31% <0%> (+11.63%) ⬆️
vm/src/obj/objfloat.rs 58.26% <0%> (+12.44%) ⬆️
vm/src/obj/objbytearray.rs 61% <0%> (+15.18%) ⬆️
... and 4 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5d28f9b...c4953ee. Read the comment docs.

@adrian17
Copy link
Contributor

adrian17 commented Mar 3, 2019

Looks like CPython doesn't do "automatic" dict type checking there, and just allows any type, then checks for None, then manually typechecks for dict.
https://github.com/python/cpython/blob/master/Python/bltinmodule.c#L1000

@cthulahoops
Copy link
Collaborator Author

In that case I've added a macro to do the extra checking.

This leads me to run into the limitations of our definitions of scope. We consider local scope to be the nearest scope to us so top level statements execute with local and global scope being the same thing. In python though this means there is no local scope, creating one doesn't replace the current local==global scope.

This should work, but doesn't:

x=2
exec("print(2)", None, {})

We'll need to sort this out to implement the globals keyword, but I think what we have is okay for now.

@cthulahoops
Copy link
Collaborator Author

Uh... the above is wrong. It looks like creating a new local scope never replaces the existing local scope. (Ie. that code still works even in a function.)

This is all wrong. :(

@cthulahoops
Copy link
Collaborator Author

I was right the first time! :)

@cthulahoops
Copy link
Collaborator Author

Interesting example:

def g():
    seven = "seven"
    def f():
        d = {}
        exec("y = seven", None, d)
        assert d['y'] == seven
    f()
g()

locals: Option<&PyObjectRef>,
) -> ScopeRef {
let current_scope = vm.current_scope();
let parent = match globals {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check here if globals is passed at all, None or an actual dictionary.

Sign up for free to 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.

4 participants