[Zope] Modifying a Dictionaries in an Extenal Method

Edward Huixquic huixquic at gmail.com
Sun Jun 5 01:05:54 EDT 2005


Thanks Dieter for your kind reply,

Here is a complete (a bit long, sorry for that)   example of what is
happening, here are some  code pieces that  shows this behavior:

DTML:
--------------------------------------------------
 <HTML>
<BODY>
<dtml-if process >
   <dtml-in fields mapping>
      <dtml-call "pyUpdate(REQUEST)">
      <dtml-var balance>
   </dtml-in>
   <dtml-var REQUEST>
</dtml-if>
<form name="input_form" "./test1">
Name: <input type="text" name="fields.name:records" value="Mickey"><br>
Lastname:<input type="text" name="fields.lastname:records" value="Mouse"><br>
Account Balance:<input type="text" name="fields.balance:records"
value="1000"><br>
<br><br>
Name: <input type="text" name="fields.name:records" value="Donald"><br>
Lastname:<input type="text" name="fields.lastname:records" value="Duck"><br>
Account Balance:<input type="text" name="fields.balance:records"
value="2000"><br>
<input type="submit" value="process" name="process">
</form>
</BODY>
</HTML>
----------------------------------------------
Python External Method:
def pyUpdate(self,REQUEST):
    for item in range(len(self.REQUEST['fields'])):
        self.REQUEST['x']=self.REQUEST['fields'][0]
        self.REQUEST['y']=self.REQUEST['fields'][1]
#       self.REQUEST['fields'][0]['balance']=5000    <-----I will
refer to this as first line
#       self.REQUEST['y']['balance']=5000       <-------- this would
be the second line
    return self.REQUEST
-------------------------------------------
Output of form after pressing the "process" button WITH both lines
commented  out in the External method, as show above (cut from the
whole REQUEST output):

 1000 2000
form
process	'process'
fields	[{'balance': '1000', 'lastname': 'Mouse', 'name': 'Mickey'},
{'balance': '2000', 'lastname': 'Duck', 'name': 'Donald'}]
<cut stuff>
fields	[{'balance': '1000', 'lastname': 'Mouse', 'name': 'Mickey'},
{'balance': '2000', 'lastname': 'Duck', 'name': 'Donald'}]
y	{'balance': '2000', 'lastname': 'Duck', 'name': 'Donald'}
x	{'balance': '1000', 'lastname': 'Mouse', 'name': 'Mickey'}

So, fields behaves as a list and X and Y are dictionaries, right?
--------------------------------------------------------------------------------------
Output with first line the python external methods NOT commented out:

Traceback (innermost last):

    * Module ZPublisher.Publish, line 101, in publish
    * Module ZPublisher.mapply, line 88, in mapply
    * Module ZPublisher.Publish, line 39, in call_object
    * Module OFS.DTMLDocument, line 128, in __call__
      <DTMLDocument instance at b455ce00>
      URL: http://machineX:8080/mytestfolder/modules/test1/manage_main
      Physical Path:/mytestfolder/modules/test1
    * Module DocumentTemplate.DT_String, line 474, in __call__
    * Module DocumentTemplate.DT_In, line 703, in renderwob
    * Module DocumentTemplate.DT_Util, line 198, in eval
      __traceback_info__: pyUpdate
    * Module <string>, line 1, in <expression>
    * Module Products.ExternalMethod.ExternalMethod, line 232, in __call__
      __traceback_info__: ((<HTTPRequest,
URL=http://mo2:8080/mytestfolder/modules/test1>,), {}, None)
    * Module /usr/local/Zope-2.7.4/instance1/Extensions/generator.py,
line 577, in pyUpdate
    * Module ZPublisher.HTTPRequest, line 1502, in __getattr__

AttributeError: __setitem__
----------------------------------------------------------------------------------
Output with only the second line the python external methods NOT commented out:
Traceback (innermost last):

    * Module ZPublisher.Publish, line 101, in publish
    * Module ZPublisher.mapply, line 88, in mapply
    * Module ZPublisher.Publish, line 39, in call_object
    * Module OFS.DTMLDocument, line 128, in __call__
      <DTMLDocument instance at b455ce00>
      URL: http://machineX:8080/mytestfolder/modules/test1/manage_main
      Physical Path:/mytestfolder/modules/test1
    * Module DocumentTemplate.DT_String, line 474, in __call__
    * Module DocumentTemplate.DT_In, line 703, in renderwob
    * Module DocumentTemplate.DT_Util, line 198, in eval
      __traceback_info__: pyUpdate
    * Module <string>, line 1, in <expression>
    * Module Products.ExternalMethod.ExternalMethod, line 232, in __call__
      __traceback_info__: ((<HTTPRequest,
URL=http://mo2:8080/prova/modulos/pruebas/test1>,), {}, None)
    * Module /usr/local/Zope-2.7.4/instance1/Extensions/generator.py,
line 578, in pyUpdate
    * Module ZPublisher.HTTPRequest, line 1502, in __getattr__

AttributeError: __setitem__
-----------------------------------------------------------------------------------------

Nevertheless I can do an append to the fields list with this Extenal Method:
def pyUpdate(self,REQUEST):
    self.REQUEST['fields'].append({'dictnew':'dictnewdata'})
    return self.REQUEST

The only weird thing is that I get the new dictionary added a number
of times that equals the number of records on the form.  Like this cut
from the REQUEST, when I had three records in the form:

form
process	'process'
fields	[{'balance': '1000', 'lastname': 'Mouse', 'name': 'Mickey'},
{'balance': '2000', 'lastname': 'Duck', 'name': 'Donald'}, {'balance':
'2000', 'lastname': 'Smith', 'name': 'Goofy'}, {'dictnew':
'dictnewdata'}, {'dictnew': 'dictnewdata'}, {'dictnew':
'dictnewdata'}]

So, after all, are those elements in the "fields' list dictionaries
and hence of mutable type or, I am missing something here?  Why I
can't modify them ?

Why does the python script (in the append example) seems to be
executed several times ?

Any light on what is going on here would be very much appreciated,
thanks in advance.

Edward.

On 6/4/05, Dieter Maurer <dieter at handshake.de> wrote:
> Corporate Email Corp. wrote at 2005-6-3 17:30 -0500:
> >Does Zope allos an external method to modify a dictionary object that
> >is passed to the external method via the REQUEST object.
> 
> Zope does not restrict an External Method in any way.
> 
> > ...
> >items_list = [{'element1':'element1value',
> >'element2':'element2value','element3': element3value},{....},....]
> >
> >I am getting trouble with with this as  any time I try to modify any
> >dictionary  from items_list,  items_list[n]   I do get an error
> >similar to:
> >
> > line 120, in agregaItemDicts def agregaItemLista2(self,item,REQUEST):
> >File "/usr/local/Zope-2.7.4/lib/python/ZPublisher/HTTPRequest.py",
> >line 1502, in __getattr__ raise AttributeError, key AttributeError:
> >__setitem__
> 
> Usually, this means that the object looks like
> a dictionary but is in fact a different object.
> 
> However, your traceback is weird:
> 
>   It seems to indicate that
>   "HTTPRequest.HTTPRequest.__getattr__('__setitem__')
>   was called.
>   However, "HTTPRequest.HTTPRequest" does have a "__setitem__"
>   attribute. Therefore, Python will never call
>   "__getattr__" automatically to resolve "__setitem__".
> 
>   Something else must have called "__getattr__" inadequately.
> 
>   The upper part of traceback (which you dropped) should
>   tell you where this calls happens.
> 
> --
> Dieter
>


More information about the Zope mailing list