-
Notifications
You must be signed in to change notification settings - Fork 49
Type Annotations for RestrictedPython #317
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
base: master
Are you sure you want to change the base?
Changes from 38 commits
7876a87
1cd6198
e2599ab
4915d8e
3299a8b
4d56e39
935a960
e67da67
2a3d728
3373795
f86d895
b4ceb35
43941ee
f0e2a06
26a218c
a4e189e
fd0328a
aceca07
3533c0f
e750331
44f9842
5b8285c
ac53335
6ecdf5a
0e1408c
1ce3ce1
652776e
0a292d3
444760e
0e92a0b
be5ad38
37a4bec
55985ad
99fd0be
fd28e28
501299a
b56ad85
2dd1fb5
ea394dc
b1d1303
23ec481
838d222
2913cb6
22ced90
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,35 @@ | ||
| from __future__ import annotations | ||
|
|
||
| import ast | ||
| import warnings | ||
| from collections import namedtuple | ||
| from ast import Expression | ||
| from ast import Interactive | ||
| from ast import Module | ||
| from ast import NodeTransformer | ||
| from collections.abc import Mapping | ||
| from collections.abc import Sequence | ||
| from os import PathLike | ||
| from types import CodeType | ||
| from typing import Any | ||
| from typing import Literal | ||
| from typing import NamedTuple | ||
| from typing import TypeAlias | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not like these from imports, below in the code it is unclear where a name comes from, please stick to normal imports.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @icemac Is it allowed to use |
||
|
|
||
| from RestrictedPython._compat import IS_CPYTHON | ||
| from RestrictedPython.transformer import RestrictingNodeTransformer | ||
|
|
||
|
|
||
| CompileResult = namedtuple( | ||
| 'CompileResult', 'code, errors, warnings, used_names') | ||
| # Temporary workaround for missing _typeshed | ||
| ReadableBuffer: TypeAlias = bytes | bytearray | ||
|
|
||
|
|
||
| class CompileResult(NamedTuple): | ||
| code: CodeType | None | ||
| errors: Sequence[str] | ||
| warnings: Sequence[str] | ||
| used_names: Mapping[str, bool] | ||
|
|
||
|
|
||
| syntax_error_template = ( | ||
| 'Line {lineno}: {type}: {msg} at statement: {statement!r}') | ||
|
|
||
|
|
@@ -18,12 +40,13 @@ | |
|
|
||
|
|
||
| def _compile_restricted_mode( | ||
| source, | ||
| filename='<string>', | ||
| mode="exec", | ||
| flags=0, | ||
| dont_inherit=False, | ||
| policy=RestrictingNodeTransformer): | ||
| source: str | ReadableBuffer | Module | Expression | Interactive, | ||
| filename: str | ReadableBuffer | PathLike[Any] = '<string>', | ||
| mode: Literal["exec", "eval", "single"] = "exec", | ||
|
|
||
| flags: int = 0, | ||
| dont_inherit: bool = False, | ||
| policy: type[NodeTransformer] | None = RestrictingNodeTransformer, | ||
| ) -> CompileResult: | ||
|
|
||
| if not IS_CPYTHON: | ||
| warnings.warn_explicit( | ||
|
|
@@ -39,13 +62,13 @@ def _compile_restricted_mode( | |
| dont_inherit=dont_inherit) | ||
| elif issubclass(policy, RestrictingNodeTransformer): | ||
| c_ast = None | ||
| allowed_source_types = [str, ast.Module] | ||
| allowed_source_types = [str, Module] | ||
| if not issubclass(type(source), tuple(allowed_source_types)): | ||
| raise TypeError('Not allowed source type: ' | ||
| '"{0.__class__.__name__}".'.format(source)) | ||
| c_ast = None | ||
|
zedzhen marked this conversation as resolved.
Outdated
|
||
| # workaround for pypy issue https://bitbucket.org/pypy/pypy/issues/2552 | ||
| if isinstance(source, ast.Module): | ||
| if isinstance(source, Module): | ||
| c_ast = source | ||
| else: | ||
| try: | ||
|
|
@@ -78,11 +101,12 @@ def _compile_restricted_mode( | |
|
|
||
|
|
||
| def compile_restricted_exec( | ||
| source, | ||
| filename='<string>', | ||
| flags=0, | ||
| dont_inherit=False, | ||
| policy=RestrictingNodeTransformer): | ||
| source: str | ReadableBuffer | Module | Expression | Interactive, | ||
| filename: str | ReadableBuffer | PathLike[Any] = '<string>', | ||
| flags: int = 0, | ||
| dont_inherit: bool = False, | ||
| policy: type[NodeTransformer] | None = RestrictingNodeTransformer, | ||
| ) -> CompileResult: | ||
| """Compile restricted for the mode `exec`.""" | ||
| return _compile_restricted_mode( | ||
| source, | ||
|
|
@@ -94,11 +118,12 @@ def compile_restricted_exec( | |
|
|
||
|
|
||
| def compile_restricted_eval( | ||
| source, | ||
| filename='<string>', | ||
| flags=0, | ||
| dont_inherit=False, | ||
| policy=RestrictingNodeTransformer): | ||
| source: str | ReadableBuffer | Module | Expression | Interactive, | ||
| filename: str | ReadableBuffer | PathLike[Any] = '<string>', | ||
| flags: int = 0, | ||
| dont_inherit: bool = False, | ||
| policy: type[NodeTransformer] | None = RestrictingNodeTransformer, | ||
| ) -> CompileResult: | ||
| """Compile restricted for the mode `eval`.""" | ||
| return _compile_restricted_mode( | ||
| source, | ||
|
|
@@ -110,11 +135,12 @@ def compile_restricted_eval( | |
|
|
||
|
|
||
| def compile_restricted_single( | ||
| source, | ||
| filename='<string>', | ||
| flags=0, | ||
| dont_inherit=False, | ||
| policy=RestrictingNodeTransformer): | ||
| source: str | ReadableBuffer | Module | Expression | Interactive, | ||
| filename: str | ReadableBuffer | PathLike[Any] = '<string>', | ||
| flags: int = 0, | ||
| dont_inherit: bool = False, | ||
| policy: type[NodeTransformer] | None = RestrictingNodeTransformer, | ||
| ) -> CompileResult: | ||
| """Compile restricted for the mode `single`.""" | ||
| return _compile_restricted_mode( | ||
| source, | ||
|
|
@@ -128,12 +154,13 @@ def compile_restricted_single( | |
| def compile_restricted_function( | ||
| p, # parameters | ||
| body, | ||
| name, | ||
| filename='<string>', | ||
| name: str, | ||
| filename: str | ReadableBuffer | PathLike[Any] = '<string>', | ||
| globalize=None, # List of globals (e.g. ['here', 'context', ...]) | ||
| flags=0, | ||
| dont_inherit=False, | ||
| policy=RestrictingNodeTransformer): | ||
| flags: int = 0, | ||
| dont_inherit: bool = False, | ||
| policy: type[NodeTransformer] | None = RestrictingNodeTransformer, | ||
| ) -> CompileResult: | ||
| """Compile a restricted code object for a function. | ||
|
|
||
| Documentation see: | ||
|
|
@@ -149,7 +176,7 @@ def compile_restricted_function( | |
| msg=v.msg, | ||
| statement=v.text.strip() if v.text else None) | ||
| return CompileResult( | ||
| code=None, errors=(error,), warnings=(), used_names=()) | ||
| code=None, errors=(error,), warnings=(), used_names={}) | ||
|
|
||
| # The compiled code is actually executed inside a function | ||
| # (that is called when the code is called) so reading and assigning to a | ||
|
|
@@ -181,12 +208,13 @@ def compile_restricted_function( | |
|
|
||
|
|
||
| def compile_restricted( | ||
| source, | ||
| filename='<unknown>', | ||
| mode='exec', | ||
| flags=0, | ||
| dont_inherit=False, | ||
| policy=RestrictingNodeTransformer): | ||
| source: str | ReadableBuffer | Module | Expression | Interactive, | ||
| filename: str | ReadableBuffer | PathLike[Any] = '<unknown>', | ||
| mode: str = 'exec', | ||
|
|
||
| flags: int = 0, | ||
| dont_inherit: bool = False, | ||
| policy: type[NodeTransformer] | None = RestrictingNodeTransformer, | ||
| ) -> CodeType: | ||
|
zedzhen marked this conversation as resolved.
Outdated
|
||
| """Replacement for the built-in compile() function. | ||
|
|
||
| policy ... `ast.NodeTransformer` class defining the restrictions. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.