### Zen of Python Overview Source: https://restrictedpython.readthedocs.io/en/latest/contributing/index Presents the core principles of the Zen of Python, a set of guiding philosophies for writing Python code. These principles emphasize readability, explicitness, and simplicity. ```python >>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! ``` -------------------------------- ### Executing Compiled Code with Restricted Globals Source: https://restrictedpython.readthedocs.io/en/latest/_sources/usage/basic_usage.rst Demonstrates executing compiled RestrictedPython code by providing explicit `globals` and `locals` dictionaries to `exec`. This is crucial for controlling access to built-in functions and modules. ```python byte_code = exec(byte_code, { ... }, { ... }) ``` -------------------------------- ### RestrictedPython Built-in Function Restriction Example Source: https://restrictedpython.readthedocs.io/en/latest/usage/policy Shows how to restrict access to built-in functions like `open` by providing a modified `__builtins__` dictionary to `compile_restricted` and `exec`. ```python >>> from RestrictedPython.Guards import safe_builtins >>> restricted_globals = dict(__builtins__=safe_builtins) >>> src = ''' ... open('/etc/passwd') ... ''' >>> code = compile_restricted(src, '', 'exec') >>> exec(code, restricted_globals) Traceback (most recent call last): ... NameError: name 'open' is not defined ``` -------------------------------- ### RestrictedPython Execution Modes (exec, eval, single) Source: https://restrictedpython.readthedocs.io/en/latest/_sources/usage/basic_usage.rst Demonstrates the usage of `compile_restricted` across different execution modes: 'exec' for statements, 'eval' for expressions, and 'single' for single-statement execution. ```python from RestrictedPython import compile_restricted source_code = """ def do_something(): pass """ byte_code = compile_restricted( source_code, filename='', mode='exec' ) exec(byte_code) do_something() ``` ```python from RestrictedPython import compile_restricted byte_code = compile_restricted( "2 + 2", filename='', mode='eval' ) eval(byte_code) ``` ```python from RestrictedPython import compile_restricted byte_code = compile_restricted( "2 + 2", filename='', mode='single' ) exec(byte_code) ``` -------------------------------- ### Restricted Python Code Transformation Example Source: https://restrictedpython.readthedocs.io/en/latest/_sources/usage/policy.rst Illustrates how a Python function is transformed after restricted compilation in RestrictedPython. It shows the introduction of restricted accessors like _print_, _write_, _getattr_, and _getitem_ to enforce security policies. ```python def f(x): x.foo = x.foo + x[0] print x return printed # After restricted compilation: def f(x): # Make local variables from globals. _print = _print_() _write = _write_ _getattr = _getattr_ _getitem = _getitem_ # Translation of f(x) above _write(x).foo = _getattr(x, 'foo') + _getitem(x, 0) print >>_print, x return _print() ``` -------------------------------- ### RestrictedPython Print Statement Example Source: https://restrictedpython.readthedocs.io/en/latest/usage/policy Demonstrates how to use `RestrictedPython.PrintCollector.PrintCollector` to capture output from `print` statements within restricted code, preventing direct output to stdout. ```python >>> from RestrictedPython.PrintCollector import PrintCollector >>> _print_ = PrintCollector >>> _getattr_ = getattr >>> src = ''' ... print("Hello World!") ... ''' >>> code = compile_restricted(src, '', 'exec') >>> exec(code) ``` ```python >>> src = ''' ... print("Hello World!") ... result = printed ... ''' >>> code = compile_restricted(src, '', 'exec') >>> exec(code) >>> result 'Hello World!\n' ``` -------------------------------- ### Restricted Python Code Translation Example Source: https://restrictedpython.readthedocs.io/en/latest/usage/policy Illustrates how a standard Python function is translated into its restricted execution equivalent using RestrictedPython's hooks for print, write, getattr, and getitem operations. ```python def f(x): x.foo = x.foo + x[0] print x return printed ``` ```python def f(x): # Make local variables from globals. _print = _print_() _write = _write_ _getattr = _getattr_ _getitem = _getitem_ # Translation of f(x) above _write(x).foo = _getattr(x, 'foo') + _getitem(x, 0) print >>_print, x return _print() ``` -------------------------------- ### Zen of Python Excerpt (Python Console) Source: https://restrictedpython.readthedocs.io/en/latest/_sources/contributing/index.rst An excerpt from the Zen of Python, displayed in a Python console session, emphasizing principles like 'Explicit is better than implicit' and 'Readability counts'. This is presented as a guiding principle for development. ```pycon >>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! ``` -------------------------------- ### Custom Policy Creation with RestrictingNodeTransformer in Python Source: https://restrictedpython.readthedocs.io/en/latest/_sources/usage/framework_usage.rst Demonstrates how to create a custom policy for RestrictedPython by subclassing RestrictingNodeTransformer. This allows for modification of how Python language elements are handled. The policy instance is initialized with empty lists for errors, warnings, and used names. ```python from RestrictedPython import compile_restricted from RestrictedPython import RestrictingNodeTransformer class OwnRestrictingNodeTransformer(RestrictingNodeTransformer): pass policy_instance = OwnRestrictingNodeTransformer( errors=[], warnings=[], used_names=[] ) ``` -------------------------------- ### Unrestricted Execution with Null-Policy (None) in Python Source: https://restrictedpython.readthedocs.io/en/latest/_sources/usage/framework_usage.rst Illustrates how to execute code in an unrestricted mode using RestrictedPython by passing None as the policy to compile_restricted. This is useful for specific scenarios like porting Zope Packages to Python 3. ```python from RestrictedPython import compile_restricted source_code = """ def do_something(): pass """ byte_code = compile_restricted( source_code, filename='', mode='exec', policy=None # Null-Policy -> unrestricted ) exec(byte_code, globals(), None) ``` -------------------------------- ### Using a Custom Policy with compile_restricted in Python Source: https://restrictedpython.readthedocs.io/en/latest/_sources/usage/framework_usage.rst Shows how to use a custom policy class with the compile_restricted function. The 'policy' parameter accepts the policy class itself, which is then used during the compilation of the source code. ```python source_code = """ def do_something(): pass """ policy = OwnRestrictingNodeTransformer byte_code = compile_restricted( source_code, filename='', mode='exec', policy=policy # policy class ) exec(byte_code, globals(), None) ``` -------------------------------- ### Restricted Built-ins and Helper Modules Source: https://restrictedpython.readthedocs.io/en/latest/usage/api Information about the available restricted built-in objects and helper modules provided by RestrictedPython. ```APIDOC ## Restricted Builtins ### Description Provides access to a set of safe global and built-in objects for restricted execution environments. ### Available Builtins * `safe_globals` * `safe_builtins` * `limited_builtins` * `utility_builtins` ## Helper Modules ### Description Includes utility modules to assist with restricted code execution. ### Available Modules * `PrintCollector` ``` -------------------------------- ### Basic Python Code Execution Source: https://restrictedpython.readthedocs.io/en/latest/usage/basic_usage Demonstrates the standard Python workflow for executing source code by compiling it into bytecode and then executing it. This serves as a baseline for understanding RestrictedPython's approach. ```Python source_code = """ def do_something(): pass """ byte_code = compile(source_code, filename='', mode='exec') exec(byte_code) do_something() ``` -------------------------------- ### Disallowing AST Nodes in RestrictedPython (Python) Source: https://restrictedpython.readthedocs.io/en/latest/_sources/contributing/index.rst Demonstrates two options for handling new AST nodes in RestrictedPython. Option 1 denies all AST nodes without an explicit visit method by default, reducing maintenance. Option 2 requires explicit disabling of nodes, aiming for explicitness. ```python def visit_(self, node): """`` expression currently not allowed.""" self.not_allowed(node) ``` -------------------------------- ### Executing Compiled RestrictedPython Function Source: https://restrictedpython.readthedocs.io/en/latest/usage/api Demonstrates how to execute compiled code generated by `compile_restricted_function`. It shows how to create a function object from compiled bytecode and how to manage global scope for specific calls. ```python from RestrictedPython import compile_restricted_function compiled = compile_restricted_function('', 'pass', 'function_name') safe_locals = {} safe_globals = {} exec(compiled.code, safe_globals, safe_locals) compiled_function = safe_locals['function_name'] result = compiled_function(*[], **{}) ``` ```python my_call_specific_global_bindings = dict(foo='bar') safe_globals = safe_globals.copy() safe_globals.update(my_call_specific_global_bindings) import types new_function = types.FunctionType( compiled_function.__code__, safe_globals, '', compiled_function.__defaults__ or ()) result = new_function(*[], **{}) ``` -------------------------------- ### Python AST Differences: 3.9 vs 3.10 Source: https://restrictedpython.readthedocs.io/en/latest/contributing/changes_from39to310 This snippet shows the Abstract Syntax Tree (AST) definition differences between Python 3.9 and Python 3.10. It highlights new nodes like `Match` and `MatchCase`, and changes in attributes like `FormattedValue` and `alias`. ```ASDL -- Python 3.9 AST -- ASDL's 4 builtin types are: -- identifier, int, string, constant module Python version "3.9" { mod = Module(stmt* body, type_ignore* type_ignores) | Interactive(stmt* body) | Expression(expr body) | FunctionType(expr name, expr* argtypes, expr returns) stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, identifier? type_comment) | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, identifier? type_comment) | ClassDef(identifier name, expr* bases, expr* keywords, stmt* body, expr* decorator_list) | Return(expr? value) | Delete(expr* targets) | Assign(expr* targets, expr value, string? type_comment) | AugAssign(expr target, operator op, expr value) | AnnAssign(expr target, expr annotation, expr? value, int simple) | For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment) | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment) | While(expr test, stmt* body, stmt* orelse) | If(expr test, stmt* body, stmt* orelse) | With(withitem* items, stmt* body, string? type_comment) | AsyncWith(withitem* items, stmt* body, string? type_comment) | Raise(expr? exc, expr? cause) | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) | Assert(expr test, expr? msg) | Import(alias* names) | ImportFrom(identifier? module, alias* names, int? level) | Global(identifier* names) | Nonlocal(identifier* names) | Expr(expr body) | Pass() | Break() | Continue() expr = BoolOp(boolop op, expr* values) | BinOp(expr left, operator op, expr right) | UnaryOp(unaryop op, expr operand) | Lambda(arguments args, expr body) | IfExp(expr test, expr body, expr orelse) | Dict(expr* keys, expr* values) | Set(expr* elt) | ListComp(expr elt, comprehension* generators) | SetComp(expr elt, comprehension* generators) | DictComp(expr key, expr value, comprehension* generators) | GeneratorExp(expr elt, comprehension* generators) | Await(expr value) | Yield(expr? value) | YieldFrom(expr value) | Compare(expr left, cmpop* ops, expr* comparators) | Call(expr func, expr* args, keyword* keywords) | FormattedValue(expr value, int? conversion, expr? format_spec) | JoinedStr(expr* values) | Constant(constant value, string? kind) | Attribute(expr value, identifier attr, expr_context ctx) | Subscript(expr value, expr slice, expr_context ctx) | Starred(expr value, expr_context ctx) | Name(identifier id, expr_context ctx) | List(expr* elt, expr_context ctx) | Tuple(expr* elt, expr_context ctx) arguments = arguments(posonlyargs=arg*, args=arg*, vararg=arg | None, kwonlyargs=arg*, kwarg=arg | None, defaults=expr*, kw_defaults=expr*) arg = arg(identifier arg, expr? annotation, expr? type_comment) keyword = keyword(identifier arg, expr value) comprehension = comprehension(expr target, expr iter, expr* ifs, int is_async) excepthandler = excepthandler(expr? type, identifier? name, stmt* body) alias = (identifier name, identifier? asname) withitem = (expr context_expr, expr? optional_vars) type_ignore = TypeIgnore(int lineno, string tag) } -- Python 3.10 AST -- ASDL's 4 builtin types are: -- identifier, int, string, constant module Python version "3.10" { mod = Module(stmt* body, type_ignore* type_ignores) | Interactive(stmt* body) | Expression(expr body) | FunctionType(expr name, expr* argtypes, expr returns) stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, identifier? type_comment) | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, identifier? type_comment) | ClassDef(identifier name, expr* bases, expr* keywords, stmt* body, expr* decorator_list) | Return(expr? value) | Delete(expr* targets) | Assign(expr* targets, expr value, string? type_comment) | AugAssign(expr target, operator op, expr value) | AnnAssign(expr target, expr annotation, expr? value, int simple) | For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment) | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment) | While(expr test, stmt* body, stmt* orelse) | If(expr test, stmt* body, stmt* orelse) | With(withitem* items, stmt* body, string? type_comment) | AsyncWith(withitem* items, stmt* body, string? type_comment) | Match(expr subject, match_case* cases) | Raise(expr? exc, expr? cause) | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) | Assert(expr test, expr? msg) | Import(alias* names) | ImportFrom(identifier? module, alias* names, int? level) | Global(identifier* names) | Nonlocal(identifier* names) | Expr(expr body) | Pass() | Break() | Continue() expr = BoolOp(boolop op, expr* values) | BinOp(expr left, operator op, expr right) | UnaryOp(unaryop op, expr operand) | Lambda(arguments args, expr body) | IfExp(expr test, expr body, expr orelse) | Dict(expr* keys, expr* values) | Set(expr* elt) | ListComp(expr elt, comprehension* generators) | SetComp(expr elt, comprehension* generators) | DictComp(expr key, expr value, comprehension* generators) | GeneratorExp(expr elt, comprehension* generators) | Await(expr value) | Yield(expr? value) | YieldFrom(expr value) | Compare(expr left, cmpop* ops, expr* comparators) | Call(expr func, expr* args, keyword* keywords) | FormattedValue(expr value, int conversion, expr? format_spec) | JoinedStr(expr* values) | Constant(constant value, string? kind) | Attribute(expr value, identifier attr, expr_context ctx) | Subscript(expr value, expr slice, expr_context ctx) | Starred(expr value, expr_context ctx) | Name(identifier id, expr_context ctx) | List(expr* elt, expr_context ctx) | Tuple(expr* elt, expr_context ctx) arguments = arguments(posonlyargs=arg*, args=arg*, vararg=arg | None, kwonlyargs=arg*, kwarg=arg | None, defaults=expr*, kw_defaults=expr*) arg = arg(identifier arg, expr? annotation, expr? type_comment) keyword = keyword(identifier arg, expr value) comprehension = comprehension(expr target, expr iter, expr* ifs, int is_async) excepthandler = excepthandler(expr? type, identifier? name, stmt* body) alias = (identifier name, identifier? asname) attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset) withitem = (expr context_expr, expr? optional_vars) match_case = (pattern pattern, expr? guard, stmt* body) pattern = MatchValue(expr value) | MatchSingleton(constant value) | MatchSequence(pattern* patterns) | MatchMapping(expr* keys, pattern* patterns, identifier? rest) | MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns) | MatchStar(identifier? name) -- The optional "rest" MatchMapping parameter handles capturing extra mapping keys | MatchAs(pattern? pattern, identifier? name) | MatchOr(pattern* patterns) attributes (int lineno, int col_offset, int end_lineno, int end_col_offset) type_ignore = TypeIgnore(int lineno, string tag) } ``` -------------------------------- ### Add visit method for AST Node in RestrictedPython Source: https://restrictedpython.readthedocs.io/en/latest/_sources/contributing/index.rst This code demonstrates how to add a new visit method for an Abstract Syntax Tree (AST) node in RestrictedPython. This method is called when the transformer encounters the specified AST node. If a visit method is not explicitly defined for an AST node, it is denied by default. The method should perform any necessary modifications and then call `node_contents_visit` to process the node's children. ```python def visit_(self, node): """Allow `` expressions.""" ... # modifications return self.node_contents_visit(node) ``` -------------------------------- ### AST Differences: Python 3.10 vs 3.11 Source: https://restrictedpython.readthedocs.io/en/latest/contributing/changes_from310to311 This snippet shows the differences in the Abstract Syntax Tree (AST) definition between Python 3.10 and Python 3.11. It highlights the addition of the `TryStar` node in Python 3.11, which is relevant for tools that parse and analyze Python code. ```diff --- /home/docs/checkouts/readthedocs.org/user_builds/restrictedpython/checkouts/latest/docs/contributing/ast/python3_10.ast +++ /home/docs/checkouts/readthedocs.org/user_builds/restrictedpython/checkouts/latest/docs/contributing/ast/python3_11.ast @@ -1,8 +1,8 @@ --- Python 3.10 AST +-- Python 3.11 AST -- ASDL's 4 builtin types are: -- identifier, int, string, constant -module Python version "3.10" +module Python version "3.11" { mod = Module(stmt* body, type_ignore* type_ignores) | Interactive(stmt* body) @@ -47,6 +47,7 @@ | Raise(expr? exc, expr? cause) | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) + | TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) | Assert(expr test, expr? msg) | Import(alias* names) ``` -------------------------------- ### Restricting AST Nodes with NodeTransformer in Python Source: https://restrictedpython.readthedocs.io/en/latest/contributing/index Demonstrates how to implement a `NodeTransformer` to restrict specific AST nodes, preventing their usage by default. This approach aligns with the 'explicit is better than implicit' philosophy. ```python def visit_(self, node): """`` expression currently not allowed.""" self.not_allowed(node) ``` -------------------------------- ### AST Differences: Python 3.11 vs. Python 3.12 Source: https://restrictedpython.readthedocs.io/en/latest/contributing/changes_from311to312 This snippet shows the differences in the Abstract Syntax Tree (AST) definition between Python 3.11 and 3.12. It highlights new constructs like type parameter declarations and the TypeAlias node introduced in Python 3.12. The comparison is presented in a diff format. ```diff --- /home/docs/checkouts/readthedocs.org/user_builds/restrictedpython/checkouts/latest/docs/contributing/ast/python3_11.ast +++ /home/docs/checkouts/readthedocs.org/user_builds/restrictedpython/checkouts/latest/docs/contributing/ast/python3_12.ast @@ -1,8 +1,8 @@ --- Python 3.11 AST +-- Python 3.12 AST -- ASDL's 4 builtin types are: -- identifier, int, string, constant -module Python version "3.11" +module Python version "3.12" { mod = Module(stmt* body, type_ignore* type_ignores) | Interactive(stmt* body) @@ -14,23 +14,27 @@ stmt* body, expr* decorator_list, expr? returns, - string? type_comment) + string? type_comment, + type_param* type_params) | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, - string? type_comment) + string? type_comment, + type_param* type_params) | ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, - expr* decorator_list) + expr* decorator_list, + type_param* type_params) | Return(expr? value) | Delete(expr* targets) | Assign(expr* targets, expr value, string? type_comment) + | TypeAlias(expr name, type_param* type_params, expr value) | AugAssign(expr target, operator op, expr value) -- 'simple' indicates that we annotate simple name without parens | AnnAssign(expr target, expr annotation, expr? value, int simple) @@ -182,4 +186,9 @@ attributes (int lineno, int col_offset, int end_lineno, int end_col_offset) type_ignore = TypeIgnore(int lineno, string tag) + + type_param = TypeVar(identifier name, expr? bound) + | ParamSpec(identifier name) + | TypeVarTuple(identifier name) + attributes (int lineno, int col_offset, int end_lineno, int end_col_offset) } ``` -------------------------------- ### RestrictedPython Execution with Safe Builtins Source: https://restrictedpython.readthedocs.io/en/latest/usage/basic_usage Demonstrates executing compiled RestrictedPython code using `safe_builtins` for the `__builtins__` dictionary. This limits the available built-in functions and methods, enhancing security. ```Python from RestrictedPython import compile_restricted from RestrictedPython import safe_builtins from RestrictedPython import limited_builtins from RestrictedPython import utility_builtins source_code = """ def do_something(): pass """ try: byte_code = compile_restricted( source_code, filename='', mode='exec' ) exec(byte_code, {'__builtins__': safe_builtins}, None) except SyntaxError as e: pass ``` -------------------------------- ### Restrict 'open' Built-in Function Execution Source: https://restrictedpython.readthedocs.io/en/latest/_sources/usage/policy.rst Demonstrates how to restrict the execution of the 'open' built-in function within a restricted Python environment using safe_builtins. If 'open' is not explicitly allowed, attempting to use it results in a NameError. ```python from RestrictedPython.Guards import safe_builtins restricted_globals = dict(__builtins__=safe_builtins) src = ''' open('/etc/passwd') ''' code = compile_restricted(src, '', 'exec') exec(code, restricted_globals) # Expected: NameError: name 'open' is not defined ``` -------------------------------- ### Python: Implement Full Write Guard for Restricted Execution Source: https://restrictedpython.readthedocs.io/en/latest/usage/policy Demonstrates how to use `full_write_guard` to prevent modifications to object attributes while allowing changes to lists and dictionaries in restricted Python code. It utilizes `compile_restricted` for safe code execution. ```python from RestrictedPython.Guards import full_write_guard from RestrictedPython import compile_restricted _write_ = full_write_guard _getattr_ = getattr class BikeShed(object): colour = 'green' shed = BikeShed() # Example demonstrating attribute access (allowed) src_access = ''' print(shed.colour) result = printed ''' code_access = compile_restricted(src_access, '', 'exec') exec(code_access) # Example demonstrating attribute modification (denied) src_modify_attr = ''' shed.colour = 'red' ''' code_modify_attr = compile_restricted(src_modify_attr, '', 'exec') try: exec(code_modify_attr) except TypeError as e: print(f"Caught expected error: {e}") # Example demonstrating list and dictionary modification (allowed) fibonacci = [1, 1, 2, 3, 4] transl = dict(one=1, two=2, tres=3) src_modify_list_dict = ''' # correct mistake in list fibonacci[-1] = 5 # one item doesn't belong del transl['tres'] ''' code_modify_list_dict = compile_restricted(src_modify_list_dict, '', 'exec') exec(code_modify_list_dict) print(f"Modified fibonacci: {fibonacci}") print(f"Modified transl keys: {sorted(transl.keys())}") ``` -------------------------------- ### RestrictedPython Compilation Methods Source: https://restrictedpython.readthedocs.io/en/latest/usage/api This section details the various methods available in RestrictedPython for compiling source code into interpretable byte code under a restricted environment. ```APIDOC ## RestrictedPython.compile_restricted ### Description Compiles source code into interpretable byte code with various modes and options. ### Method `compile_restricted(_source_, _filename_, _mode_, _flags_, _dont_inherit_, _policy_) ### Parameters #### Path Parameters * **source** (str or unicode text or `ast.AST`) - Required - The source code to compile. * **filename** (str or unicode text) - Optional - Defaults to `''`. * **mode** (str or unicode text) - Optional - Use `'exec'`, `'eval'`, `'single'` or `'function'`. Defaults to `'exec'`. * **flags** (int) - Optional - Defaults to `0`. * **dont_inherit** (int) - Optional - Defaults to `False`. * **policy** (RestrictingNodeTransformer class) - Optional - Defaults to `RestrictingNodeTransformer`. ### Returns Python `code` object --- ## RestrictedPython.compile_restricted_exec ### Description Compiles source code into interpretable byte code with `mode='exec'`. Use this mode if the source contains a sequence of statements. ### Method `compile_restricted_exec(_source_, _filename_, _flags_, _dont_inherit_, _policy_) ### Parameters #### Path Parameters * **source** (str or unicode text) - Required - The source code to compile. * **filename** (str or unicode text) - Optional - Defaults to `''`. * **flags** (int) - Optional - Defaults to `0`. * **dont_inherit** (int) - Optional - Defaults to `False`. * **policy** (RestrictingNodeTransformer class) - Optional - Defaults to `RestrictingNodeTransformer`. ### Returns CompileResult (a namedtuple with code, errors, warnings, used_names) --- ## RestrictedPython.compile_restricted_eval ### Description Compiles source code into interpretable byte code with `mode='eval'`. Use this mode if the source contains a single expression. ### Method `compile_restricted_eval(_source_, _filename_, _flags_, _dont_inherit_, _policy_) ### Parameters #### Path Parameters * **source** (str or unicode text) - Required - The source code to compile. * **filename** (str or unicode text) - Optional - Defaults to `''`. * **flags** (int) - Optional - Defaults to `0`. * **dont_inherit** (int) - Optional - Defaults to `False`. * **policy** (RestrictingNodeTransformer class) - Optional - Defaults to `RestrictingNodeTransformer`. ### Returns CompileResult (a namedtuple with code, errors, warnings, used_names) --- ## RestrictedPython.compile_restricted_single ### Description Compiles source code into interpretable byte code with `mode='single'`. Use this mode if the source contains a single interactive statement. ### Method `compile_restricted_single(_source_, _filename_, _flags_, _dont_inherit_, _policy_) ### Parameters #### Path Parameters * **source** (str or unicode text) - Required - The source code to compile. * **filename** (str or unicode text) - Optional - Defaults to `''`. * **flags** (int) - Optional - Defaults to `0`. * **dont_inherit** (int) - Optional - Defaults to `False`. * **policy** (RestrictingNodeTransformer class) - Optional - Defaults to `RestrictingNodeTransformer`. ### Returns CompileResult (a namedtuple with code, errors, warnings, used_names) --- ## RestrictedPython.compile_restricted_function ### Description Compiles source code into interpretable byte code with `mode='function'`. Use this mode for full functions. ### Method `compile_restricted_function(_p_, _body_, _name_, _filename_, _globalize_) ### Parameters #### Path Parameters * **p** (str or unicode text) - Required - A string representing the function parameters. * **body** (str or unicode text) - Required - The function body. * **name** (str or unicode text) - Required - The function name. * **filename** (str or unicode text) - Optional - Defaults to `''`. * **globalize** (None or list) - Optional - List of globals. Defaults to `None`. ### Returns byte code ### Example ```python from RestrictedPython import compile_restricted_function compiled = compile_restricted_function('', 'pass', 'function_name') safe_locals = {} safe_globals = {} exec(compiled.code, safe_globals, safe_locals) compiled_function = safe_locals['function_name'] result = compiled_function(*[], **{}) ``` ``` -------------------------------- ### Allow AST Node Expressions in RestrictedPython Source: https://restrictedpython.readthedocs.io/en/latest/contributing/index This Python code snippet demonstrates how to define a visitor method in `transformer.py` to allow a specific AST Node expression in RestrictedPython. It includes a docstring explaining its purpose and a call to `self.node_contents_visit(node)` to process the node's contents. All AST nodes without an explicit visitor method are denied by default. ```python def visit_(self, node): """Allow `` expressions.""" ... # modifications return self.node_contents_visit(node) ``` -------------------------------- ### Print Statement Handling with PrintCollector Source: https://restrictedpython.readthedocs.io/en/latest/_sources/usage/policy.rst Demonstrates how to enable and use the print statement within restricted Python code by supplying a `_print_` factory, typically `RestrictedPython.PrintCollector.PrintCollector`. The output is collected rather than printed to stdout. ```python from RestrictedPython.PrintCollector import PrintCollector _print_ = PrintCollector _getattr_ = getattr src = ''' print("Hello World!") ''' code = compile_restricted(src, '', 'exec') exec(code) # To retrieve collected output: src = ''' print("Hello World!") result = printed ''' code = compile_restricted(src, '', 'exec') exec(code) # result will contain 'Hello World!\n' ``` -------------------------------- ### Python's Built-in Compile Method Source: https://restrictedpython.readthedocs.io/en/latest/idea This snippet shows the signature of Python's built-in `compile()` function. It's used to compile source code into bytecode, which can then be executed. The relevant parameters are `source` (the code to compile) and `mode` (specifying how the code should be compiled, e.g., 'exec', 'eval', 'single'). ```python compile(source, filename, mode [, flags [, dont_inherit]]) ``` -------------------------------- ### RestrictedPython Compile with Alias Source: https://restrictedpython.readthedocs.io/en/latest/usage/basic_usage Illustrates how to use an alias for the `compile_restricted` function, simplifying its usage in the code. This is a stylistic choice for convenience. ```Python from RestrictedPython import compile_restricted as compile ``` -------------------------------- ### Allow List and Dictionary Modification with Write Guard Source: https://restrictedpython.readthedocs.io/en/latest/_sources/usage/policy.rst Demonstrates that `full_write_guard` permits modifications to mutable types like lists and dictionaries. This allows restricted code to correct list elements or delete dictionary items, showcasing fine-grained control. ```python from RestrictedPython.Guards import full_write_guard _write_ = full_write_guard _getattr_ = getattr fibonacci = [1, 1, 2, 3, 4] transl = dict(one=1, two=2, tres=3) src = ''' # correct mistake in list fibonacci[-1] = 5 # one item doesn't belong del transl['tres'] ''' code = compile_restricted(src, '', 'exec') exec(code) # Expected: fibonacci == [1, 1, 2, 3, 5] # Expected: sorted(transl.keys()) == ['one', 'two'] ``` -------------------------------- ### RestrictedPython's Compile Method Source: https://restrictedpython.readthedocs.io/en/latest/idea This snippet presents the signature for `RestrictedPython.compile_restricted()`, a safe alternative to Python's built-in `compile()`. It accepts similar parameters (`source`, `filename`, `mode`) but enforces restrictions to ensure safe execution. The `source` can be a string or an `ast.AST` instance. Both `compile` and `compile_restricted` return compiled bytecode or raise exceptions for invalid code. ```python RestrictedPython.compile_restricted(source, filename, mode [, flags [, dont_inherit]]) ``` -------------------------------- ### Compile Function with RestrictedPython Source: https://restrictedpython.readthedocs.io/en/latest/usage/api Compiles source code into interpretable byte code for full functions. It takes parameters, body, and name as required arguments, with optional filename, globalize list, flags, dont_inherit, and policy. ```python RestrictedPython.compile_restricted_function(_p_ , _body_ , _name_ , _filename_ , _globalize =None_) ``` -------------------------------- ### Python Compile Function Comparison Source: https://restrictedpython.readthedocs.io/en/latest/_sources/idea.rst Compares the standard Python `compile()` function with RestrictedPython's `compile_restricted()`. Both compile source code to bytecode, but `compile_restricted()` is designed for safe execution within a restricted environment. Both can raise exceptions for invalid source code. ```python compile(source, filename, mode [, flags [, dont_inherit]]) ``` ```python RestrictedPython.compile_restricted(source, filename, mode [, flags [, dont_inherit]]) ```