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.
@@ -27,6 +27,7 @@ _safe_names = [
27
27
  'None',
28
28
  'False',
29
29
  'True',
30
+ 'Ellipsis',
30
31
  'abs',
31
32
  'bool',
32
33
  'bytes',
@@ -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'
@@ -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.NameConstant(value=None)
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 with restriction for Ellipsis.
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, self.transform_slice(node.slice)],
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.2
1
+ Metadata-Version: 2.4
2
2
  Name: RestrictedPython
3
- Version: 8.1a1.dev0
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
- Home-page: https://github.com/zopefoundation/RestrictedPython
6
- Author: Zope Foundation and Contributors
7
- Author-email: zope-dev@zope.dev
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: Tracker, https://github.com/zopefoundation/RestrictedPython/issues
12
- Keywords: restricted execution security untrusted code
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: >=3.9, <3.15
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: author
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.1a1.dev0 (2025-03-20)
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.14 -- Caution: No security
142
- audit has been done so far.
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,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.2)
2
+ Generator: setuptools (81.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -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,,