RestrictedPython 8.1a1.dev0__py3-none-any.whl → 8.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- RestrictedPython/Guards.py +1 -0
- RestrictedPython/_compat.py +2 -1
- RestrictedPython/transformer.py +29 -72
- {restrictedpython-8.1a1.dev0.dist-info → restrictedpython-8.3.dist-info}/METADATA +42 -26
- restrictedpython-8.3.dist-info/RECORD +14 -0
- {restrictedpython-8.1a1.dev0.dist-info → restrictedpython-8.3.dist-info}/WHEEL +1 -1
- restrictedpython-8.1a1.dev0.dist-info/RECORD +0 -14
- {restrictedpython-8.1a1.dev0.dist-info → restrictedpython-8.3.dist-info/licenses}/LICENSE.txt +0 -0
- {restrictedpython-8.1a1.dev0.dist-info → restrictedpython-8.3.dist-info}/top_level.txt +0 -0
RestrictedPython/Guards.py
CHANGED
RestrictedPython/_compat.py
CHANGED
|
@@ -3,8 +3,9 @@ import sys
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
_version = sys.version_info
|
|
6
|
-
IS_PY310_OR_GREATER = _version.major == 3 and _version.minor >= 10
|
|
7
6
|
IS_PY311_OR_GREATER = _version.major == 3 and _version.minor >= 11
|
|
8
7
|
IS_PY312_OR_GREATER = _version.major == 3 and _version.minor >= 12
|
|
8
|
+
IS_PY313_OR_GREATER = _version.major == 3 and _version.minor >= 13
|
|
9
|
+
IS_PY314_OR_GREATER = _version.major == 3 and _version.minor >= 14
|
|
9
10
|
|
|
10
11
|
IS_CPYTHON = platform.python_implementation() == 'CPython'
|
RestrictedPython/transformer.py
CHANGED
|
@@ -73,6 +73,7 @@ INSPECT_ATTRIBUTES = frozenset([
|
|
|
73
73
|
"f_back",
|
|
74
74
|
"f_builtins",
|
|
75
75
|
"f_code",
|
|
76
|
+
"f_generator",
|
|
76
77
|
"f_globals",
|
|
77
78
|
# "f_lasti", # int
|
|
78
79
|
# "f_lineno", # int
|
|
@@ -99,6 +100,7 @@ INSPECT_ATTRIBUTES = frozenset([
|
|
|
99
100
|
# on generator objects:
|
|
100
101
|
"gi_frame",
|
|
101
102
|
# "gi_running", # bool
|
|
103
|
+
# "gi_suspended", # bool
|
|
102
104
|
"gi_code",
|
|
103
105
|
"gi_yieldfrom",
|
|
104
106
|
# on coroutine objects:
|
|
@@ -354,60 +356,11 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
354
356
|
return (tmp_target, cleanup)
|
|
355
357
|
|
|
356
358
|
def gen_none_node(self):
|
|
357
|
-
return ast.
|
|
359
|
+
return ast.Constant(None)
|
|
358
360
|
|
|
359
361
|
def gen_del_stmt(self, name_to_del):
|
|
360
362
|
return ast.Delete(targets=[ast.Name(name_to_del, ast.Del())])
|
|
361
363
|
|
|
362
|
-
def transform_slice(self, slice_):
|
|
363
|
-
"""Transform slices into function parameters.
|
|
364
|
-
|
|
365
|
-
ast.Slice nodes are only allowed within a ast.Subscript node.
|
|
366
|
-
To use a slice as an argument of ast.Call it has to be converted.
|
|
367
|
-
Conversion is done by calling the 'slice' function from builtins
|
|
368
|
-
"""
|
|
369
|
-
|
|
370
|
-
if isinstance(slice_, ast.expr):
|
|
371
|
-
# Python 3.9+
|
|
372
|
-
return slice_
|
|
373
|
-
|
|
374
|
-
elif isinstance(slice_, ast.Index):
|
|
375
|
-
return slice_.value
|
|
376
|
-
|
|
377
|
-
elif isinstance(slice_, ast.Slice):
|
|
378
|
-
# Create a python slice object.
|
|
379
|
-
args = []
|
|
380
|
-
|
|
381
|
-
if slice_.lower:
|
|
382
|
-
args.append(slice_.lower)
|
|
383
|
-
else:
|
|
384
|
-
args.append(self.gen_none_node())
|
|
385
|
-
|
|
386
|
-
if slice_.upper:
|
|
387
|
-
args.append(slice_.upper)
|
|
388
|
-
else:
|
|
389
|
-
args.append(self.gen_none_node())
|
|
390
|
-
|
|
391
|
-
if slice_.step:
|
|
392
|
-
args.append(slice_.step)
|
|
393
|
-
else:
|
|
394
|
-
args.append(self.gen_none_node())
|
|
395
|
-
|
|
396
|
-
return ast.Call(
|
|
397
|
-
func=ast.Name('slice', ast.Load()),
|
|
398
|
-
args=args,
|
|
399
|
-
keywords=[])
|
|
400
|
-
|
|
401
|
-
elif isinstance(slice_, ast.ExtSlice):
|
|
402
|
-
dims = ast.Tuple([], ast.Load())
|
|
403
|
-
for item in slice_.dims:
|
|
404
|
-
dims.elts.append(self.transform_slice(item))
|
|
405
|
-
return dims
|
|
406
|
-
|
|
407
|
-
else: # pragma: no cover
|
|
408
|
-
# Index, Slice and ExtSlice are only defined Slice types.
|
|
409
|
-
raise NotImplementedError(f"Unknown slice type: {slice_}")
|
|
410
|
-
|
|
411
364
|
def check_name(self, node, name, allow_magic_methods=False):
|
|
412
365
|
"""Check names if they are allowed.
|
|
413
366
|
|
|
@@ -434,6 +387,9 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
434
387
|
self.error(node, f'"{name}" is a reserved name.')
|
|
435
388
|
|
|
436
389
|
def check_function_argument_names(self, node):
|
|
390
|
+
for arg in node.args.posonlyargs:
|
|
391
|
+
self.check_name(node, arg.arg)
|
|
392
|
+
|
|
437
393
|
for arg in node.args.args:
|
|
438
394
|
self.check_name(node, arg.arg)
|
|
439
395
|
|
|
@@ -523,20 +479,12 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
523
479
|
# ast for Literals
|
|
524
480
|
|
|
525
481
|
def visit_Constant(self, node):
|
|
526
|
-
"""Allow constant literals
|
|
482
|
+
"""Allow constant literals.
|
|
527
483
|
|
|
528
484
|
Constant replaces Num, Str, Bytes, NameConstant and Ellipsis in
|
|
529
485
|
Python 3.8+.
|
|
530
486
|
:see: https://docs.python.org/dev/whatsnew/3.8.html#deprecated
|
|
531
487
|
"""
|
|
532
|
-
if node.value is Ellipsis:
|
|
533
|
-
# Deny using `...`.
|
|
534
|
-
# Special handling necessary as ``self.not_allowed(node)``
|
|
535
|
-
# would return the Error Message:
|
|
536
|
-
# 'Constant statements are not allowed.'
|
|
537
|
-
# which is only partial true.
|
|
538
|
-
self.error(node, 'Ellipsis statements are not allowed.')
|
|
539
|
-
return
|
|
540
488
|
return self.node_contents_visit(node)
|
|
541
489
|
|
|
542
490
|
def visit_Interactive(self, node):
|
|
@@ -563,6 +511,27 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
563
511
|
"""Allow f-strings without restrictions."""
|
|
564
512
|
return self.node_contents_visit(node)
|
|
565
513
|
|
|
514
|
+
def visit_TemplateStr(self, node):
|
|
515
|
+
"""Template strings are allowed by default.
|
|
516
|
+
|
|
517
|
+
As Template strings are a very basic template mechanism, that needs
|
|
518
|
+
additional rendering logic to be useful, they are not blocked by
|
|
519
|
+
default.
|
|
520
|
+
Those rendering logic would be affected by RestrictedPython as well.
|
|
521
|
+
"""
|
|
522
|
+
return self.node_contents_visit(node)
|
|
523
|
+
|
|
524
|
+
def visit_Interpolation(self, node):
|
|
525
|
+
"""Interpolations are allowed by default.
|
|
526
|
+
|
|
527
|
+
As Interpolations are part of Template Strings, they are needed
|
|
528
|
+
to be reached in the context of RestrictedPython as Template Strings
|
|
529
|
+
are allowed. As a user has to provide additional rendering logic
|
|
530
|
+
to make use of Template Strings, the security implications of
|
|
531
|
+
Interpolations are limited in the context of RestrictedPython.
|
|
532
|
+
"""
|
|
533
|
+
return self.node_contents_visit(node)
|
|
534
|
+
|
|
566
535
|
def visit_JoinedStr(self, node):
|
|
567
536
|
"""Allow joined string without restrictions."""
|
|
568
537
|
return self.node_contents_visit(node)
|
|
@@ -909,7 +878,7 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
909
878
|
if isinstance(node.ctx, ast.Load):
|
|
910
879
|
new_node = ast.Call(
|
|
911
880
|
func=ast.Name('_getitem_', ast.Load()),
|
|
912
|
-
args=[node.value,
|
|
881
|
+
args=[node.value, node.slice],
|
|
913
882
|
keywords=[])
|
|
914
883
|
|
|
915
884
|
copy_locations(new_node, node)
|
|
@@ -930,24 +899,12 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
930
899
|
raise NotImplementedError(
|
|
931
900
|
f"Unknown ctx type: {type(node.ctx)}")
|
|
932
901
|
|
|
933
|
-
def visit_Index(self, node):
|
|
934
|
-
"""
|
|
935
|
-
|
|
936
|
-
"""
|
|
937
|
-
return self.node_contents_visit(node)
|
|
938
|
-
|
|
939
902
|
def visit_Slice(self, node):
|
|
940
903
|
"""
|
|
941
904
|
|
|
942
905
|
"""
|
|
943
906
|
return self.node_contents_visit(node)
|
|
944
907
|
|
|
945
|
-
def visit_ExtSlice(self, node):
|
|
946
|
-
"""
|
|
947
|
-
|
|
948
|
-
"""
|
|
949
|
-
return self.node_contents_visit(node)
|
|
950
|
-
|
|
951
908
|
# Comprehensions
|
|
952
909
|
|
|
953
910
|
def visit_ListComp(self, node):
|
|
@@ -1,28 +1,27 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: RestrictedPython
|
|
3
|
-
Version: 8.
|
|
3
|
+
Version: 8.3
|
|
4
4
|
Summary: RestrictedPython is a defined subset of the Python language which allows to provide a program input into a trusted environment.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
License: ZPL-2.1
|
|
5
|
+
Author-email: Zope Foundation and contributors <zope-dev@zope.dev>
|
|
6
|
+
Maintainer-email: Plone Foundation and contributors <zope-dev@zope.dev>
|
|
7
|
+
License-Expression: ZPL-2.1
|
|
9
8
|
Project-URL: Documentation, https://restrictedpython.readthedocs.io/
|
|
9
|
+
Project-URL: Issues, https://github.com/zopefoundation/RestrictedPython/issues
|
|
10
10
|
Project-URL: Source, https://github.com/zopefoundation/RestrictedPython
|
|
11
|
-
Project-URL:
|
|
12
|
-
Keywords: restricted
|
|
11
|
+
Project-URL: Changelog, https://github.com/zopefoundation/RestrictedPython/blob/master/CHANGES.rst
|
|
12
|
+
Keywords: restricted,execution,security,untrusted,code
|
|
13
13
|
Classifier: Development Status :: 6 - Mature
|
|
14
|
-
Classifier: License :: OSI Approved :: Zope Public License
|
|
15
14
|
Classifier: Programming Language :: Python
|
|
16
15
|
Classifier: Operating System :: OS Independent
|
|
17
16
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
22
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
24
23
|
Classifier: Topic :: Security
|
|
25
|
-
Requires-Python:
|
|
24
|
+
Requires-Python: <3.16,>=3.10
|
|
26
25
|
Description-Content-Type: text/x-rst
|
|
27
26
|
License-File: LICENSE.txt
|
|
28
27
|
Provides-Extra: test
|
|
@@ -31,18 +30,7 @@ Requires-Dist: pytest-mock; extra == "test"
|
|
|
31
30
|
Provides-Extra: docs
|
|
32
31
|
Requires-Dist: Sphinx; extra == "docs"
|
|
33
32
|
Requires-Dist: furo; extra == "docs"
|
|
34
|
-
Dynamic:
|
|
35
|
-
Dynamic: author-email
|
|
36
|
-
Dynamic: classifier
|
|
37
|
-
Dynamic: description
|
|
38
|
-
Dynamic: description-content-type
|
|
39
|
-
Dynamic: home-page
|
|
40
|
-
Dynamic: keywords
|
|
41
|
-
Dynamic: license
|
|
42
|
-
Dynamic: project-url
|
|
43
|
-
Dynamic: provides-extra
|
|
44
|
-
Dynamic: requires-python
|
|
45
|
-
Dynamic: summary
|
|
33
|
+
Dynamic: license-file
|
|
46
34
|
|
|
47
35
|
.. image:: https://github.com/zopefoundation/RestrictedPython/actions/workflows/tests.yml/badge.svg
|
|
48
36
|
:target: https://github.com/zopefoundation/RestrictedPython/actions/workflows/tests.yml
|
|
@@ -135,11 +123,39 @@ the documentation `Contributing page
|
|
|
135
123
|
Changes
|
|
136
124
|
=======
|
|
137
125
|
|
|
138
|
-
8.
|
|
126
|
+
8.3 (2026-06-16)
|
|
127
|
+
----------------
|
|
128
|
+
|
|
129
|
+
- Switch to PyPI Trusted Publishing for the package release process
|
|
130
|
+
|
|
131
|
+
- Also validate positional-only argument names (parameters before ``/``) so
|
|
132
|
+
they cannot start with an underscore, closing a sandbox escape where a
|
|
133
|
+
positional-only parameter could shadow an injected protected name such as
|
|
134
|
+
``_getattr_``, ``_getitem_``, ``_write_`` or ``_print_``.
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
8.3a1.dev0 (2026-05-29)
|
|
139
138
|
-----------------------
|
|
140
139
|
|
|
141
|
-
- Allow to use the package with Python 3.
|
|
142
|
-
|
|
140
|
+
- Allow to use the package with Python 3.15 -- Caution: No security audit has been done so far.
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
8.2 (2026-05-29)
|
|
144
|
+
----------------
|
|
145
|
+
|
|
146
|
+
- Remove documentation that appears to promote unsupported direct guards usage.
|
|
147
|
+
|
|
148
|
+
- Move package metadata from setup.py to pyproject.toml.
|
|
149
|
+
|
|
150
|
+
- Drop support for Python 3.9.
|
|
151
|
+
|
|
152
|
+
- Allow the ``...`` (Ellipsis) statement.
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
8.1 (2025-10-19)
|
|
156
|
+
----------------
|
|
157
|
+
|
|
158
|
+
- Allow to use the package with Python 3.14 including t-string support.
|
|
143
159
|
|
|
144
160
|
|
|
145
161
|
8.0 (2025-01-23)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
RestrictedPython/Eval.py,sha256=pa79tc-JsT7xfzwg0ceMkxyioIEnFbNHc_PsKUhkkj8,3201
|
|
2
|
+
RestrictedPython/Guards.py,sha256=e8xUs0VbvEQxnUu7ylyJNq7xyhGhQ4QuiiAEJIl4mc4,8105
|
|
3
|
+
RestrictedPython/Limits.py,sha256=dORpuly21vSjy8gzNac9IYfIXMMWRVFvqUiKKIeZ3OM,1866
|
|
4
|
+
RestrictedPython/PrintCollector.py,sha256=bBCpnUPOuKz1wJDuSgh7wo2aoKfcTJeeT8OYnM-K9F8,1137
|
|
5
|
+
RestrictedPython/Utilities.py,sha256=u4HUdyjGawaeHyXSakyt4gRT17BZietXnF5WqicujjE,3033
|
|
6
|
+
RestrictedPython/__init__.py,sha256=qB_s6zDxuXPAGMoKYKBMc-xZ0gTnQ0ZvtY5FxdAG3aM,1862
|
|
7
|
+
RestrictedPython/_compat.py,sha256=eGzz9dyKpYrhyytUV1Ul860zu5GZq9Ew9EQ3CqjVl0Y,385
|
|
8
|
+
RestrictedPython/compile.py,sha256=IhcF733t-bkPcvfQ2_NyBeCbSIPtHYxR-GQNNHnaMHM,6727
|
|
9
|
+
RestrictedPython/transformer.py,sha256=-3ga3rf6jtO6C23tpFgtszXKlcwoOPyZqK65ev3_I3Y,40267
|
|
10
|
+
restrictedpython-8.3.dist-info/licenses/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
|
|
11
|
+
restrictedpython-8.3.dist-info/METADATA,sha256=Kjj7EG2D8HejxlGqC_khj_HzUWAOom35RxWFd0L7QUQ,14997
|
|
12
|
+
restrictedpython-8.3.dist-info/WHEEL,sha256=YLJXdYXQ2FQ0Uqn2J-6iEIC-3iOey8lH3xCtvFLkd8Q,91
|
|
13
|
+
restrictedpython-8.3.dist-info/top_level.txt,sha256=E1-3ARWcduVJnQAScms0FgqnBx_PovrzYsNMYuLGwa0,17
|
|
14
|
+
restrictedpython-8.3.dist-info/RECORD,,
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
RestrictedPython/Eval.py,sha256=pa79tc-JsT7xfzwg0ceMkxyioIEnFbNHc_PsKUhkkj8,3201
|
|
2
|
-
RestrictedPython/Guards.py,sha256=hGLMmqB7SPWwaxHl5elPED6MPCLCWg2nmCVM4_OYaV4,8089
|
|
3
|
-
RestrictedPython/Limits.py,sha256=dORpuly21vSjy8gzNac9IYfIXMMWRVFvqUiKKIeZ3OM,1866
|
|
4
|
-
RestrictedPython/PrintCollector.py,sha256=bBCpnUPOuKz1wJDuSgh7wo2aoKfcTJeeT8OYnM-K9F8,1137
|
|
5
|
-
RestrictedPython/Utilities.py,sha256=u4HUdyjGawaeHyXSakyt4gRT17BZietXnF5WqicujjE,3033
|
|
6
|
-
RestrictedPython/__init__.py,sha256=qB_s6zDxuXPAGMoKYKBMc-xZ0gTnQ0ZvtY5FxdAG3aM,1862
|
|
7
|
-
RestrictedPython/_compat.py,sha256=2Mew5xHBB0Lg3YfhbFyTdOSt4TQCWnEBGQ1SNFeR8a0,318
|
|
8
|
-
RestrictedPython/compile.py,sha256=IhcF733t-bkPcvfQ2_NyBeCbSIPtHYxR-GQNNHnaMHM,6727
|
|
9
|
-
RestrictedPython/transformer.py,sha256=UEs-dqbE6r0lGq7JLszVsIXnZTnO_ak2pw8Isyp9l6s,41419
|
|
10
|
-
restrictedpython-8.1a1.dev0.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
|
|
11
|
-
restrictedpython-8.1a1.dev0.dist-info/METADATA,sha256=DkKGZ8zJq_r9nj5RoJVJ7Sa7u1J2tH62Fjg_vnSMA9A,14433
|
|
12
|
-
restrictedpython-8.1a1.dev0.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
|
13
|
-
restrictedpython-8.1a1.dev0.dist-info/top_level.txt,sha256=E1-3ARWcduVJnQAScms0FgqnBx_PovrzYsNMYuLGwa0,17
|
|
14
|
-
restrictedpython-8.1a1.dev0.dist-info/RECORD,,
|
{restrictedpython-8.1a1.dev0.dist-info → restrictedpython-8.3.dist-info/licenses}/LICENSE.txt
RENAMED
|
File without changes
|
|
File without changes
|