RestrictedPython icon indicating copy to clipboard operation
RestrictedPython copied to clipboard

Allow type hinting

Open mohankumaru opened this issue 2 years ago • 4 comments

Hi, Is there a way to include annotated assignment in the code being executed?

               sample_code = """
               a: int = 1
                """
                supported_builtins["_getattr_"] = safer_getattr
                supported_builtins["_getiter_"] = default_guarded_getiter
                supported_builtins["_iter_unpack_sequence_"] = guarded_iter_unpack_sequence
                supported_builtins["dict"] = dict
                supported_builtins["list"] = list
                byte_code = compile_restricted(
                            sample_code,
                            filename='<inline code>',
                            mode='exec'
                            )
                exec(byte_code, {'__builtins__':supported_builtins}, {'input_arg': {"a":1})

Where I am looking to add type hints to my inline code "sample_code". It will throw exception saying " AnnAssign statements are not allowed.". Is there a way to get around this?

mohankumaru avatar Jan 19 '22 10:01 mohankumaru

mohankumaru wrote at 2022-1-19 02:13 -0800:

Is there a way to include annotated assignment in the code being executed?

Currently, this is not possible.

... Where I am looking to add type hints to my inline code "sample_code". It will throw saying " AnnAssign statements are not allowed.". Is there a way to get around this?

Why is this important for you? Those annotations are hints only; you need external tools to make effective use of them.

RestrictedPython works by compiling the source first into an "AST" (= "Abstract Syntax Tree") in the normal way and then use an AST transformation to check constructs at runtime (that's where not explicitly supported features such as annotations are rejected) and transform (some) other constructs to make runtime checks possible.

You can either monkey patch the transformation class or derive your own transformation class to allow annotations. But I wonder if it is worth the effort.

d-maurer avatar Jan 19 '22 11:01 d-maurer

@d-maurer , Thank you for quick reply. We run mypy regularly on our codebase and there are some code which needs to be restricted. I wanted to know if its possible through restricted python, possibly I can strip the type checks before restricted python compilation.

mohankumaru avatar Jan 20 '22 06:01 mohankumaru

Currently not supporting does not mean: will never support. So I am reopening this issue and mark it as an enhancement request.

As type annotations do not influence the runtime behavior it should be no problem to support them during the parsing and remove them from the AST.

icemac avatar Jan 21 '22 07:01 icemac

Hi I stumbled upon this issue and wanted to add that this is trivial to implement because AnnAssign nodes only have a target field declared as Name | Attribute | Subscript and so doesn't need the logic found in visit_Assign().

User code could look like this

from RestrictedPython import RestrictingNodeTransformer

class MyNodeTransformer(RestrictingNodeTransformer):

    def visit_AnnAssign(self, node: AnnAssign) -> Any:
        return self.node_contents_visit(node)

Here's our implementation: https://github.com/onecommons/unfurl/blob/c238d00e916d7071191104dd3fab0a34aded2574/tosca-package/tosca/loader.py#L504

In Python 3.12, the following node types were added for the new type alias syntax, so you might want to add these too, they only impact type annotations so are safe at runtime:

    def visit_TypeAlias(self, node) -> Any:
        return self.node_contents_visit(node)

    def visit_TypeVar(self, node) -> Any:
        return self.node_contents_visit(node)

    def visit_TypeVarTuple(self, node) -> Any:
        return self.node_contents_visit(node)

    def visit_ParamSpec(self, node) -> Any:
        return self.node_contents_visit(node)

aszs avatar Feb 06 '24 12:02 aszs