Products.PythonScripts 5.0__py3-none-any.whl → 5.1__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.
- Products/PythonScripts/PythonScript.py +24 -7
- Products/PythonScripts/tests/testPythonScript.py +48 -2
- Products/PythonScripts/www/pyScriptEdit.dtml +1 -1
- {Products.PythonScripts-5.0.dist-info → Products.PythonScripts-5.1.dist-info}/METADATA +19 -5
- {Products.PythonScripts-5.0.dist-info → Products.PythonScripts-5.1.dist-info}/RECORD +11 -11
- {Products.PythonScripts-5.0.dist-info → Products.PythonScripts-5.1.dist-info}/WHEEL +1 -1
- /Products.PythonScripts-5.0-py3.11-nspkg.pth → /Products.PythonScripts-5.1-py3.11-nspkg.pth +0 -0
- {Products.PythonScripts-5.0.dist-info → Products.PythonScripts-5.1.dist-info}/LICENSE.txt +0 -0
- {Products.PythonScripts-5.0.dist-info → Products.PythonScripts-5.1.dist-info}/entry_points.txt +0 -0
- {Products.PythonScripts-5.0.dist-info → Products.PythonScripts-5.1.dist-info}/namespace_packages.txt +0 -0
- {Products.PythonScripts-5.0.dist-info → Products.PythonScripts-5.1.dist-info}/top_level.txt +0 -0
|
@@ -16,7 +16,9 @@ This product provides support for Script objects containing restricted
|
|
|
16
16
|
Python code.
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
+
import importlib.abc
|
|
19
20
|
import importlib.util
|
|
21
|
+
import linecache
|
|
20
22
|
import marshal
|
|
21
23
|
import os
|
|
22
24
|
import re
|
|
@@ -56,7 +58,7 @@ LOG = getLogger('PythonScripts')
|
|
|
56
58
|
Python_magic = importlib.util.MAGIC_NUMBER
|
|
57
59
|
|
|
58
60
|
# This should only be incremented to force recompilation.
|
|
59
|
-
Script_magic =
|
|
61
|
+
Script_magic = 5
|
|
60
62
|
_log_complaint = (
|
|
61
63
|
'Some of your Scripts have stale code cached. Since Zope cannot'
|
|
62
64
|
' use this code, startup will be slightly slower until these Scripts'
|
|
@@ -97,6 +99,17 @@ def manage_addPythonScript(self, id, title='', file=None, REQUEST=None,
|
|
|
97
99
|
return ''
|
|
98
100
|
|
|
99
101
|
|
|
102
|
+
class PythonScriptLoader(importlib.abc.Loader):
|
|
103
|
+
"""PEP302 loader to display source code in tracebacks
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
def __init__(self, source):
|
|
107
|
+
self._source = source
|
|
108
|
+
|
|
109
|
+
def get_source(self, name):
|
|
110
|
+
return self._source
|
|
111
|
+
|
|
112
|
+
|
|
100
113
|
class PythonScript(Script, Historical, Cacheable):
|
|
101
114
|
"""Web-callable scripts written in a safe subset of Python.
|
|
102
115
|
|
|
@@ -179,12 +192,12 @@ class PythonScript(Script, Historical, Cacheable):
|
|
|
179
192
|
if self.wl_isLocked():
|
|
180
193
|
raise ResourceLockedError('The script is locked via WebDAV.')
|
|
181
194
|
|
|
195
|
+
if not file:
|
|
196
|
+
return self.ZPythonScriptHTML_editForm(
|
|
197
|
+
self, REQUEST,
|
|
198
|
+
manage_tabs_message='No file specified',
|
|
199
|
+
manage_tabs_type='warning')
|
|
182
200
|
if not isinstance(file, str):
|
|
183
|
-
if not file:
|
|
184
|
-
return self.ZPythonScriptHTML_editForm(
|
|
185
|
-
self, REQUEST,
|
|
186
|
-
manage_tabs_message='No file specified',
|
|
187
|
-
manage_tabs_type='warning')
|
|
188
201
|
file = file.read()
|
|
189
202
|
|
|
190
203
|
self.write(file)
|
|
@@ -234,7 +247,7 @@ class PythonScript(Script, Historical, Cacheable):
|
|
|
234
247
|
self._params,
|
|
235
248
|
body=self._body or 'pass',
|
|
236
249
|
name=self.id,
|
|
237
|
-
filename=self.
|
|
250
|
+
filename=getattr(self, '_filepath', None) or self.get_filepath(),
|
|
238
251
|
globalize=bind_names)
|
|
239
252
|
|
|
240
253
|
code = compile_result.code
|
|
@@ -261,6 +274,7 @@ class PythonScript(Script, Historical, Cacheable):
|
|
|
261
274
|
fc.co_argcount)
|
|
262
275
|
self.Python_magic = Python_magic
|
|
263
276
|
self.Script_magic = Script_magic
|
|
277
|
+
linecache.clearcache()
|
|
264
278
|
self._v_change = 0
|
|
265
279
|
|
|
266
280
|
def _newfun(self, code):
|
|
@@ -331,6 +345,8 @@ class PythonScript(Script, Historical, Cacheable):
|
|
|
331
345
|
PythonScriptTracebackSupplement, self, -1)
|
|
332
346
|
safe_globals['__file__'] = getattr(
|
|
333
347
|
self, '_filepath', None) or self.get_filepath()
|
|
348
|
+
safe_globals['__loader__'] = PythonScriptLoader(self._body)
|
|
349
|
+
|
|
334
350
|
function = types.FunctionType(
|
|
335
351
|
function_code, safe_globals, None, function_argument_definitions)
|
|
336
352
|
|
|
@@ -556,6 +572,7 @@ InitializeClass(PythonScript)
|
|
|
556
572
|
|
|
557
573
|
class PythonScriptTracebackSupplement:
|
|
558
574
|
"""Implementation of ITracebackSupplement"""
|
|
575
|
+
|
|
559
576
|
def __init__(self, script, line=0):
|
|
560
577
|
self.object = script
|
|
561
578
|
# If line is set to -1, it means to use tb_lineno.
|
|
@@ -15,6 +15,7 @@ import contextlib
|
|
|
15
15
|
import io
|
|
16
16
|
import os
|
|
17
17
|
import sys
|
|
18
|
+
import traceback
|
|
18
19
|
import unittest
|
|
19
20
|
import warnings
|
|
20
21
|
from urllib.error import HTTPError
|
|
@@ -241,7 +242,8 @@ class TestPythonScriptNoAq(PythonScriptTestBase):
|
|
|
241
242
|
self.assertEqual(ps.read(), ps.manage_DAVget())
|
|
242
243
|
|
|
243
244
|
def test_PUT_native_string(self):
|
|
244
|
-
|
|
245
|
+
container = DummyFolder('container')
|
|
246
|
+
ps = makerequest(self._filePS('complete').__of__(container))
|
|
245
247
|
self.assertEqual(ps.title, 'This is a title')
|
|
246
248
|
self.assertEqual(ps.body(), 'print(foo+bar+baz)\nreturn printed\n')
|
|
247
249
|
self.assertEqual(ps.params(), 'foo, bar, baz=1')
|
|
@@ -265,7 +267,8 @@ return \xe4\xe9\xee\xf6\xfc
|
|
|
265
267
|
self.assertEqual(ps.params(), 'oops')
|
|
266
268
|
|
|
267
269
|
def test_PUT_bytes(self):
|
|
268
|
-
|
|
270
|
+
container = DummyFolder('container')
|
|
271
|
+
ps = makerequest(self._filePS('complete').__of__(container))
|
|
269
272
|
self.assertEqual(ps.title, 'This is a title')
|
|
270
273
|
self.assertEqual(ps.body(), 'print(foo+bar+baz)\nreturn printed\n')
|
|
271
274
|
self.assertEqual(ps.params(), 'foo, bar, baz=1')
|
|
@@ -588,3 +591,46 @@ class PythonScriptBrowserTests(FunctionalTestCase):
|
|
|
588
591
|
|
|
589
592
|
# Cleanup
|
|
590
593
|
noSecurityManager()
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
class TestTraceback(FunctionalTestCase, PythonScriptTestBase):
|
|
597
|
+
|
|
598
|
+
def _format_exception(self):
|
|
599
|
+
return "".join(traceback.format_exception(*sys.exc_info()))
|
|
600
|
+
|
|
601
|
+
def test_source_code_in_traceback(self):
|
|
602
|
+
ps = self._newPS("1 / 0")
|
|
603
|
+
try:
|
|
604
|
+
ps()
|
|
605
|
+
except ZeroDivisionError:
|
|
606
|
+
formatted_exception = self._format_exception()
|
|
607
|
+
self.assertIn("1 / 0", formatted_exception)
|
|
608
|
+
|
|
609
|
+
ps.write("2 / 0")
|
|
610
|
+
try:
|
|
611
|
+
ps()
|
|
612
|
+
except ZeroDivisionError:
|
|
613
|
+
formatted_exception = self._format_exception()
|
|
614
|
+
self.assertIn("2 / 0", formatted_exception)
|
|
615
|
+
|
|
616
|
+
def test_multiple_scripts_in_traceback(self):
|
|
617
|
+
from Products.PythonScripts.PythonScript import manage_addPythonScript
|
|
618
|
+
|
|
619
|
+
script1_body = "container.script2()"
|
|
620
|
+
manage_addPythonScript(
|
|
621
|
+
self.folder,
|
|
622
|
+
"script1",
|
|
623
|
+
file=script1_body,
|
|
624
|
+
)
|
|
625
|
+
script2_body = "1 / 0"
|
|
626
|
+
manage_addPythonScript(
|
|
627
|
+
self.folder,
|
|
628
|
+
"script2",
|
|
629
|
+
file=script2_body,
|
|
630
|
+
)
|
|
631
|
+
try:
|
|
632
|
+
self.folder.script1()
|
|
633
|
+
except ZeroDivisionError:
|
|
634
|
+
formatted_exception = self._format_exception()
|
|
635
|
+
self.assertIn(script1_body, formatted_exception)
|
|
636
|
+
self.assertIn(script2_body, formatted_exception)
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<div class="form-group row ">
|
|
17
17
|
<label for="params" class="form-label col-sm-3 col-md-2">Parameter List</label>
|
|
18
18
|
<div class="col-sm-9 col-md-10">
|
|
19
|
-
<input id="params" class="form-control" type="text" name="params" value="&dtml-params;" />
|
|
19
|
+
<input id="params" class="form-control code" type="text" name="params" value="&dtml-params;" />
|
|
20
20
|
</div>
|
|
21
21
|
</div>
|
|
22
22
|
</dtml-with>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: Products.PythonScripts
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.1
|
|
4
4
|
Summary: Provides support for restricted execution of Python scripts in Zope.
|
|
5
5
|
Home-page: https://github.com/zopefoundation/Products.PythonScripts
|
|
6
6
|
Author: Zope Foundation and Contributors
|
|
@@ -16,22 +16,23 @@ Classifier: License :: OSI Approved :: Zope Public License
|
|
|
16
16
|
Classifier: Operating System :: OS Independent
|
|
17
17
|
Classifier: Programming Language :: Python
|
|
18
18
|
Classifier: Programming Language :: Python :: 3
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.8
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.9
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
25
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
25
|
-
Requires-Python: >=3.
|
|
26
|
+
Requires-Python: >=3.8
|
|
26
27
|
License-File: LICENSE.txt
|
|
27
28
|
Requires-Dist: setuptools
|
|
28
29
|
Requires-Dist: AccessControl
|
|
29
30
|
Requires-Dist: Acquisition
|
|
30
31
|
Requires-Dist: DateTime
|
|
31
32
|
Requires-Dist: DocumentTemplate
|
|
32
|
-
Requires-Dist: RestrictedPython
|
|
33
|
+
Requires-Dist: RestrictedPython >=4.0b5
|
|
33
34
|
Requires-Dist: zExceptions
|
|
34
|
-
Requires-Dist: Zope
|
|
35
|
+
Requires-Dist: Zope >=4.1.2
|
|
35
36
|
|
|
36
37
|
.. image:: https://github.com/zopefoundation/Products.PythonScripts/actions/workflows/tests.yml/badge.svg
|
|
37
38
|
:target: https://github.com/zopefoundation/Products.PythonScripts/actions/workflows/tests.yml
|
|
@@ -125,6 +126,19 @@ in the Products directory.
|
|
|
125
126
|
Changelog
|
|
126
127
|
=========
|
|
127
128
|
|
|
129
|
+
5.1 (2024-10-16)
|
|
130
|
+
----------------
|
|
131
|
+
|
|
132
|
+
- Fix behavior when uploading no file in ``Zope >= 5.8.1``.
|
|
133
|
+
|
|
134
|
+
- Add support for Python 3.12 and 3.13
|
|
135
|
+
|
|
136
|
+
- Drop support for Python 3.7.
|
|
137
|
+
|
|
138
|
+
- Show Python Scripts source code in tracebacks.
|
|
139
|
+
`#64 <https://github.com/zopefoundation/Products.PythonScripts/issues/64>`_
|
|
140
|
+
|
|
141
|
+
|
|
128
142
|
5.0 (2023-02-01)
|
|
129
143
|
----------------
|
|
130
144
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
Products.PythonScripts-5.
|
|
2
|
-
Products/PythonScripts/PythonScript.py,sha256=
|
|
1
|
+
Products.PythonScripts-5.1-py3.11-nspkg.pth,sha256=nq2GLEDBKV9G0i4LEhkEEQT0gMqQlG1ToxVfs90lBMs,549
|
|
2
|
+
Products/PythonScripts/PythonScript.py,sha256=akLe6wdOQjpwy_AsTH9VPIerEBHV4hOaYCTAACrX3TQ,20940
|
|
3
3
|
Products/PythonScripts/Utility.py,sha256=o_v9f8K9Apmz7nuyO3sx5MszFCg573LEA_HbPepo6zQ,860
|
|
4
4
|
Products/PythonScripts/__init__.py,sha256=iJZv-69KQR73xMaN08IUeTR3Xua1Ga9CB1U_k8BE6YM,2210
|
|
5
5
|
Products/PythonScripts/configure.zcml,sha256=oEllo95Kz_TbT-o33fkM3K7eJekI9UtYq7VheP3TQ80,222
|
|
@@ -7,7 +7,7 @@ Products/PythonScripts/standard.py,sha256=q7Y9HmwoNeep9Ge2TZPIxOHeSJuum0Gws_Gky0
|
|
|
7
7
|
Products/PythonScripts/Extensions/RemotePS.py,sha256=GThnZEHNoyEYkeYySqEUk2mLZgaUYTYBimIIexc7edA,612
|
|
8
8
|
Products/PythonScripts/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
Products/PythonScripts/tests/testBindings.py,sha256=nd5yJl0SOpJVguSDgkzZG43j_wzs7yTXR5zf44BhScc,9454
|
|
10
|
-
Products/PythonScripts/tests/testPythonScript.py,sha256=
|
|
10
|
+
Products/PythonScripts/tests/testPythonScript.py,sha256=He8_FpTehy1wp8kBoXCHkcY4Wpimu6MUaPOThv8HO_4,23102
|
|
11
11
|
Products/PythonScripts/tests/tscripts/big_boolean.ps,sha256=pnSjggXHNB4p2HAGaoXrYdf9N-tVgISJdZkSxHevcOk,119
|
|
12
12
|
Products/PythonScripts/tests/tscripts/boolean_map.ps,sha256=Ct15mgZ_j9wquw1QsgPNq1xqUU--PpFK_7MK63GvPLw,296
|
|
13
13
|
Products/PythonScripts/tests/tscripts/class.__name__.ps,sha256=xYWFpxh8TWqSvJgEgCXBJysUeIIoLi9GOgvy1kG2jns,87
|
|
@@ -27,12 +27,12 @@ Products/PythonScripts/tests/tscripts/tuple_unpack_assignment.ps,sha256=ndiygHw2
|
|
|
27
27
|
Products/PythonScripts/tests/tscripts/while_loop.ps,sha256=oka5M0x1cdqkn5KAOctBl0hFOoNf-g5eaCE1m13APYA,43
|
|
28
28
|
Products/PythonScripts/www/default_content,sha256=zW3seGJBcptFXv3jecfcKEslpxCfq4leBSDzJwKtQ8w,465
|
|
29
29
|
Products/PythonScripts/www/pyScriptAdd.dtml,sha256=d4IwyyX3x7nj1McBEnXPSvcZT9JBdc6OkS6fXdKcq08,1620
|
|
30
|
-
Products/PythonScripts/www/pyScriptEdit.dtml,sha256=
|
|
30
|
+
Products/PythonScripts/www/pyScriptEdit.dtml,sha256=sCSnnxJlQmSo2G2464bvLgsmb5gLvWjHfNQw_BRhlMY,3348
|
|
31
31
|
Products/PythonScripts/www/pyScriptProxy.dtml,sha256=xV-hC9-ZEcGi-OVde2VVMt-2_OTJ1egN-cSwCr93dBQ,1147
|
|
32
|
-
Products.PythonScripts-5.
|
|
33
|
-
Products.PythonScripts-5.
|
|
34
|
-
Products.PythonScripts-5.
|
|
35
|
-
Products.PythonScripts-5.
|
|
36
|
-
Products.PythonScripts-5.
|
|
37
|
-
Products.PythonScripts-5.
|
|
38
|
-
Products.PythonScripts-5.
|
|
32
|
+
Products.PythonScripts-5.1.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
|
|
33
|
+
Products.PythonScripts-5.1.dist-info/METADATA,sha256=cuYMXW3W74vDQD3NZ23cedPOW09duiWEBx3ItL_OyuM,10688
|
|
34
|
+
Products.PythonScripts-5.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
35
|
+
Products.PythonScripts-5.1.dist-info/entry_points.txt,sha256=bYD9dZ1s4djQ3ga5W8tQz28uFzu1tOOA4knl5p6wNy0,76
|
|
36
|
+
Products.PythonScripts-5.1.dist-info/namespace_packages.txt,sha256=UgMr3LVXWHS9vjnxTk8VOZd7xxgBn5T02HOaMRXjjTM,9
|
|
37
|
+
Products.PythonScripts-5.1.dist-info/top_level.txt,sha256=UgMr3LVXWHS9vjnxTk8VOZd7xxgBn5T02HOaMRXjjTM,9
|
|
38
|
+
Products.PythonScripts-5.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
{Products.PythonScripts-5.0.dist-info → Products.PythonScripts-5.1.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{Products.PythonScripts-5.0.dist-info → Products.PythonScripts-5.1.dist-info}/namespace_packages.txt
RENAMED
|
File without changes
|
|
File without changes
|