Pete
Pete

Reputation: 343

Why does RestrictedPython behave differently when used with Python 3.6?

I'm trying to use RestrictedPython(see documentation) with Python 3.6. The following code yields different results in Python 2.7 and in 3.6:

from RestrictedPython import compile_restricted
from RestrictedPython.Guards import safe_builtins
restricted_globals = dict(__builtins__ = safe_builtins)

src = '''
open('/etc/passwd')
'''

code = compile_restricted(src, '<string>', 'exec')
exec(code) in restricted_globals

In Python 2.7, the result is as expected:

Traceback (most recent call last):
  File "...Playground.py", line 10, in <module>
    exec(code) in restricted_globals
  File "<string>", line 2, in <module>
NameError: name 'open' is not defined

But in Python 3.6, the results is:

Traceback (most recent call last):
  File "...Playground.py", line 10, in <module>
    exec(code) in restricted_globals
  File "<string>", line 2, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/etc/passwd'

The open name/method is now obviously known, which should not be the case. Why does this code behave different when used in 3.6 than when used in 2.7?

Upvotes: 3

Views: 690

Answers (1)

Elisio Quintino
Elisio Quintino

Reputation: 475

The way you should write your code for version 3.6 is presented here:

https://github.com/zopefoundation/RestrictedPython

Under "Problematic Code Example".

Namely, the following code will work, that is, open will be not defined:

from RestrictedPython import compile_restricted
from RestrictedPython import safe_builtins

source_code = """
open('/etc/passwd')
"""
byte_code = compile_restricted(source_code, '<inline>', 'exec')
exec(byte_code, {'__builtins__': safe_builtins}, {})

As for the reason why this happens, I don't have one, but I wanted to present a way of making it work anyways.

Upvotes: 3

Related Questions