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.
@@ -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 = 4
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.meta_type,
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
- ps = makerequest(self._filePS('complete'))
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
- ps = makerequest(self._filePS('complete'))
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.0
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.7
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 (>=4.0b5)
33
+ Requires-Dist: RestrictedPython >=4.0b5
33
34
  Requires-Dist: zExceptions
34
- Requires-Dist: Zope (>=4.1.2)
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.0-py3.11-nspkg.pth,sha256=nq2GLEDBKV9G0i4LEhkEEQT0gMqQlG1ToxVfs90lBMs,549
2
- Products/PythonScripts/PythonScript.py,sha256=I9UNQfBjqM0LbNEVtkGzq5W5gZR_qNSsBVjNxw6pMzQ,20540
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=I2cTYSKC-u4iFBoiGAX8z3LP9Mqa4tq2MAjwRY4pw_k,21632
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=e4-KQaK-J-MIbFMAI4eXbvCc0YuJ1RvluT5jeT08cL4,3343
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.0.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
33
- Products.PythonScripts-5.0.dist-info/METADATA,sha256=DfI_63PWY1cKpvYBNQIxNm8gXpFKMWIzDbVpmPYmfAo,10343
34
- Products.PythonScripts-5.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
35
- Products.PythonScripts-5.0.dist-info/entry_points.txt,sha256=bYD9dZ1s4djQ3ga5W8tQz28uFzu1tOOA4knl5p6wNy0,76
36
- Products.PythonScripts-5.0.dist-info/namespace_packages.txt,sha256=UgMr3LVXWHS9vjnxTk8VOZd7xxgBn5T02HOaMRXjjTM,9
37
- Products.PythonScripts-5.0.dist-info/top_level.txt,sha256=UgMr3LVXWHS9vjnxTk8VOZd7xxgBn5T02HOaMRXjjTM,9
38
- Products.PythonScripts-5.0.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.38.4)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5