RestrictedPython 8.1a1.dev0__py3-none-any.whl → 8.3a1.dev0__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 +26 -72
- {restrictedpython-8.1a1.dev0.dist-info → restrictedpython-8.3a1.dev0.dist-info}/METADATA +31 -26
- restrictedpython-8.3a1.dev0.dist-info/RECORD +14 -0
- {restrictedpython-8.1a1.dev0.dist-info → restrictedpython-8.3a1.dev0.dist-info}/WHEEL +1 -1
- restrictedpython-8.1a1.dev0.dist-info/RECORD +0 -14
- {restrictedpython-8.1a1.dev0.dist-info → restrictedpython-8.3a1.dev0.dist-info/licenses}/LICENSE.txt +0 -0
- {restrictedpython-8.1a1.dev0.dist-info → restrictedpython-8.3a1.dev0.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
|
|
|
@@ -523,20 +476,12 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
523
476
|
# ast for Literals
|
|
524
477
|
|
|
525
478
|
def visit_Constant(self, node):
|
|
526
|
-
"""Allow constant literals
|
|
479
|
+
"""Allow constant literals.
|
|
527
480
|
|
|
528
481
|
Constant replaces Num, Str, Bytes, NameConstant and Ellipsis in
|
|
529
482
|
Python 3.8+.
|
|
530
483
|
:see: https://docs.python.org/dev/whatsnew/3.8.html#deprecated
|
|
531
484
|
"""
|
|
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
485
|
return self.node_contents_visit(node)
|
|
541
486
|
|
|
542
487
|
def visit_Interactive(self, node):
|
|
@@ -563,6 +508,27 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
563
508
|
"""Allow f-strings without restrictions."""
|
|
564
509
|
return self.node_contents_visit(node)
|
|
565
510
|
|
|
511
|
+
def visit_TemplateStr(self, node):
|
|
512
|
+
"""Template strings are allowed by default.
|
|
513
|
+
|
|
514
|
+
As Template strings are a very basic template mechanism, that needs
|
|
515
|
+
additional rendering logic to be useful, they are not blocked by
|
|
516
|
+
default.
|
|
517
|
+
Those rendering logic would be affected by RestrictedPython as well.
|
|
518
|
+
"""
|
|
519
|
+
return self.node_contents_visit(node)
|
|
520
|
+
|
|
521
|
+
def visit_Interpolation(self, node):
|
|
522
|
+
"""Interpolations are allowed by default.
|
|
523
|
+
|
|
524
|
+
As Interpolations are part of Template Strings, they are needed
|
|
525
|
+
to be reached in the context of RestrictedPython as Template Strings
|
|
526
|
+
are allowed. As a user has to provide additional rendering logic
|
|
527
|
+
to make use of Template Strings, the security implications of
|
|
528
|
+
Interpolations are limited in the context of RestrictedPython.
|
|
529
|
+
"""
|
|
530
|
+
return self.node_contents_visit(node)
|
|
531
|
+
|
|
566
532
|
def visit_JoinedStr(self, node):
|
|
567
533
|
"""Allow joined string without restrictions."""
|
|
568
534
|
return self.node_contents_visit(node)
|
|
@@ -909,7 +875,7 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
909
875
|
if isinstance(node.ctx, ast.Load):
|
|
910
876
|
new_node = ast.Call(
|
|
911
877
|
func=ast.Name('_getitem_', ast.Load()),
|
|
912
|
-
args=[node.value,
|
|
878
|
+
args=[node.value, node.slice],
|
|
913
879
|
keywords=[])
|
|
914
880
|
|
|
915
881
|
copy_locations(new_node, node)
|
|
@@ -930,24 +896,12 @@ class RestrictingNodeTransformer(ast.NodeTransformer):
|
|
|
930
896
|
raise NotImplementedError(
|
|
931
897
|
f"Unknown ctx type: {type(node.ctx)}")
|
|
932
898
|
|
|
933
|
-
def visit_Index(self, node):
|
|
934
|
-
"""
|
|
935
|
-
|
|
936
|
-
"""
|
|
937
|
-
return self.node_contents_visit(node)
|
|
938
|
-
|
|
939
899
|
def visit_Slice(self, node):
|
|
940
900
|
"""
|
|
941
901
|
|
|
942
902
|
"""
|
|
943
903
|
return self.node_contents_visit(node)
|
|
944
904
|
|
|
945
|
-
def visit_ExtSlice(self, node):
|
|
946
|
-
"""
|
|
947
|
-
|
|
948
|
-
"""
|
|
949
|
-
return self.node_contents_visit(node)
|
|
950
|
-
|
|
951
905
|
# Comprehensions
|
|
952
906
|
|
|
953
907
|
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.3a1.dev0
|
|
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,28 @@ the documentation `Contributing page
|
|
|
135
123
|
Changes
|
|
136
124
|
=======
|
|
137
125
|
|
|
138
|
-
8.
|
|
126
|
+
8.3a1.dev0 (2026-05-29)
|
|
139
127
|
-----------------------
|
|
140
128
|
|
|
141
|
-
- Allow to use the package with Python 3.
|
|
142
|
-
|
|
129
|
+
- Allow to use the package with Python 3.15 -- Caution: No security audit has been done so far.
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
8.2 (2026-05-29)
|
|
133
|
+
----------------
|
|
134
|
+
|
|
135
|
+
- Remove documentation that appears to promote unsupported direct guards usage.
|
|
136
|
+
|
|
137
|
+
- Move package metadata from setup.py to pyproject.toml.
|
|
138
|
+
|
|
139
|
+
- Drop support for Python 3.9.
|
|
140
|
+
|
|
141
|
+
- Allow the ``...`` (Ellipsis) statement.
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
8.1 (2025-10-19)
|
|
145
|
+
----------------
|
|
146
|
+
|
|
147
|
+
- Allow to use the package with Python 3.14 including t-string support.
|
|
143
148
|
|
|
144
149
|
|
|
145
150
|
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=Oggxl6_xDYy2R5hctTr3VosDrjlJhji4bfKpakEb77k,40181
|
|
10
|
+
restrictedpython-8.3a1.dev0.dist-info/licenses/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
|
|
11
|
+
restrictedpython-8.3a1.dev0.dist-info/METADATA,sha256=KNWa7DLZYb9HVciRTXYiGmiK-VF4U9wPMy4ih9viZgc,14613
|
|
12
|
+
restrictedpython-8.3a1.dev0.dist-info/WHEEL,sha256=YLJXdYXQ2FQ0Uqn2J-6iEIC-3iOey8lH3xCtvFLkd8Q,91
|
|
13
|
+
restrictedpython-8.3a1.dev0.dist-info/top_level.txt,sha256=E1-3ARWcduVJnQAScms0FgqnBx_PovrzYsNMYuLGwa0,17
|
|
14
|
+
restrictedpython-8.3a1.dev0.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.3a1.dev0.dist-info/licenses}/LICENSE.txt
RENAMED
|
File without changes
|
{restrictedpython-8.1a1.dev0.dist-info → restrictedpython-8.3a1.dev0.dist-info}/top_level.txt
RENAMED
|
File without changes
|