zopefoundation / Products.PythonScripts

Provides support for restricted execution of Python scripts in Zope.
Other
6 stars 10 forks source link

PythonScript writes on execution #54

Closed Nimo-19 closed 2 years ago

Nimo-19 commented 2 years ago

BUG/PROBLEM REPORT (OR OTHER COMMON ISSUE)

It seems to me the PythonScript writes something into the database on execution. I don't know if this is intended, but It makes it impossible to use a PythonScript to transform some data in a read-only zeo-client environment.

What I did:

What I expect to happen:

I would expect the script to return myparam and don't try to write something into the ZODB.

What actually happened:

The Instance raises an ZODB.POSException.ReadOnlyError Exception, because the execution of the script tires to write something into the ZODB

What version of Python and Zope/Addons I am using:

Plone 5.2.8 (5216)
CMF 2.5.4
Zope 4.8.1
Python 3.7.12 (default, Mar 14 2022, 07:11:45) [GCC 11.2.0]
PIL 6.2.2 (Pillow)
WSGI: On
Server: waitress 2.1.1
dataflake commented 2 years ago

Could you please add a full error traceback from the event log? Thanks.

Nimo-19 commented 2 years ago

This is the only traceback I get:

2022-05-19 10:25:31,404 ERROR   [Zope.SiteErrorLog:252][waitress-2] 1652948731.40358540.3952269507655112 http://localhost:8086/Plone/test-again/@@table
Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 168, in transaction_pubevents
  Module transaction._manager, line 257, in commit
  Module transaction._manager, line 134, in commit
  Module transaction._transaction, line 282, in commit
  Module transaction._compat, line 49, in reraise
  Module transaction._transaction, line 273, in commit
  Module transaction._transaction, line 456, in _commitResources
  Module transaction._compat, line 49, in reraise
  Module transaction._transaction, line 428, in _commitResources
  Module ZODB.Connection, line 480, in tpc_begin
  Module ZODB.mvccadapter, line 171, in tpc_begin
  Module ZEO.ClientStorage, line 801, in tpc_begin
ZODB.POSException.ReadOnlyError
dataflake commented 2 years ago

I cannot reproduce the issue in a simplified setup that doesn't use Plone. I use Zope 4 with Products.PythonScripts installed and set up a script like you have by visiting the ZMI and adding it there. I added a call to the script in a page template. Then I shut down the Zope process and changed the Zope configuration file to add read-only on to the ZODB FileStorage configuration. I can still visit the page template that renders the output of the Python script correctly. So the assertion that a Python Script writes to the ZODB when it executes appears to be incorrect.

The traceback you provided refers to a view called @@table and I don't know its code or whatever else happens inside Plone when you run it. You should try a simpler test setup without Plone and see what happens.

Nimo-19 commented 2 years ago

Just to be save, because I ran in this trap myself: As far as I know read-only does only work in a zeoserver <-> zeoclient setup.

dataflake commented 2 years ago

That's not correct, read-only is a valid configuration flag for a simple direct FileStorage as well, and it would have shown the problem.

Nimo-19 commented 2 years ago

Thanks for that clarification. Than plone.recipe.zope2instance must ignore the flag when zeo-client isn't set. I asumed it is because the client server architecture is required.So no Bug at the pythonscript side it seems. It seems I have to find my problem elsewhere.Any idea or hint where to look. I thought it was the execution, because commenting out it and hardcoding the return value worked.I sadly not very experienced with zope.

dataflake commented 2 years ago

I suggest you ask around in the Plone community. There are web-based discussions at https://community.plone.org/

icemac commented 2 years ago

PythonScripts write a compiled variant of the code into ZODB so this compilation step has not to be done every time. See https://github.com/zopefoundation/Products.PythonScripts/blob/1d6f8894d0ab0c0baeda6476efa412c187c9f35b/src/Products/PythonScripts/PythonScript.py#L242 Maybe it works if you run the PythonScript once on a read/write ZODB before switching to read-only.

d-maurer commented 1 year ago

Michael Howitz wrote at 2022-5-25 09:25 -0700:

PythonScripts write a compiled variant of the code into ZODB so this compilation step has not to be done every time. See https://github.com/zopefoundation/Products.PythonScripts/blob/1d6f8894d0ab0c0baeda6476efa412c187c9f35b/src/Products/PythonScripts/PythonScript.py#L242 Maybe it works if you run the PythonScript once on a read/write ZODB before switching to read-only.

When the script is created, the ZODB must be writable. As the OP's addon creates the script, it can call its _compile method to perform the compiling at the time of creation (or change).

d-maurer commented 1 year ago

Nimo wrote at 2022-5-19 02:57 -0700:

Any idea or hint where to look.

Those errors are rather difficult to analyze -- because they are reported non locally.

I approach them in the following way:

Often, it is enough to learn which object has been modified to know what went wrong. If this is not sufficient, you can copy the object's __dict__, invalidate the objects (--> obj._p_invalidate()) and then load it again (--> obj._p_activate()) (this restores the unmodified state from the ZODB). You can then compare your copy (with the modifications) with the current __dict__ to learn what has been changed.