different namespaces in a python script by calling it by <dtml-var xxx> and <dtml-var "xxx()">?
Hi people there! I have a problem with namespace in python scripts. I found a lot namespace Q&A but I didn't find any pointers about the following in the list archive: I have a python Script 'xxx' and a DTML method 'xxxcaller' (code below). I discovered that namespaces depend on the method how the 'xxx' script is called by the 'xxxcaller' DTML method. It works as expected if I do a <dtml-var xxx> and magically unexpected if I do a <dtml-var "xxx()">. The output of 'xxxcaller' is: <dtml-var xxx> --> foo <dtml-var "xxx()"> --> sort_order not defined Why that? Greg ------------------------------------------------- xxx ## Script (Python) "xxx" ##bind container=container ##bind context=context ##bind namespace=_ ##bind script=script ##bind subpath=traverse_subpath ##parameters= ##title= ## if _.has_key('sort_order'): return _['sort_order'] else: return 'sort_order not defined' ------------------------------------------------- xxxcaller <dtml-var standard_html_header> <h2><dtml-var title_or_id> <dtml-var document_title></h2> <p> <dtml-let sort_order="'foo'"> <dtml-var xxx> --> <dtml-var xxx><br> <dtml-var "xxx()"> --> <dtml-var "xxx()"> </dtml-let> </p> <dtml-var standard_html_footer> _____________________________________ Grégoire Weber mailto:gregoire.weber@switzerland.org
Grégoire Weber wrote:
<dtml-var xxx> --> foo
This is the equivalent of: <dtml-var "xxx(_.None,_)">
<dtml-var "xxx()"> --> sort_order not defined
...so this is obviously wrong sicne you're not passing the namespace. This is confusing, isn't it? cheers, Chris
Thanks Chris, your answer helped me! But I am not really satisfied in general about the solution. I know it's not your fault!
<dtml-var xxx> --> foo
This is the equivalent of: <dtml-var "xxx(_.None,_)">
I have additional parameters so I replaced the '_.None' by the parameters like this (as I suppose, the _.None is only used if there are no parameters at all): <dtml-var "xxx(anypar='foo_par',_=_)"> without '_=_' it does not work as expected.
This is confusing, isn't it?
You're damn right! :-( Questions which turn up (just for interest): 1) Why isn't this done automagically by setting the 'Namespace' thing in the bindings tab to '_'? So that the caller does not have to grant access to '_' to the calles Python Script explicitly? 2) Isn't there really any possibility for the Script to access the '_' namespace of it's own? It seems that I have access to the '_' namespace version which is set up at the beginning of the request. 3) Why do DTML know about the actual namespace of the calling methods and Python Scripts not? It seems to me that Python Scripts do not at all have the same behaviour as DTML methods have. :-( Greg P.S.: Is there a documentation about thsi anywhere? -------------------------------------------------- xxx script ## Script (Python) "xxx" ##bind container=container ##bind context=context ##bind namespace=_ ##bind script=script ##bind subpath=traverse_subpath ##parameters=anypar='foo_default' ##title= ## if _.has_key('sort_order'): return (_['sort_order'],anypar) else: return ('sort_order not defined',anypar) ------------------------------- xxxcaller dtml method snippet <dtml-let sort_order="'foo_sort_order'"> <dtml-var xxx><br> <dtml-var "xxx(anypar='foo_par',_=_)"> </dtml-let> _____________________________________ Grégoire Weber mailto:gregoire.weber@switzerland.org
Grégoire Weber wrote:
This is the equivalent of: <dtml-var "xxx(_.None,_)">
I have additional parameters so I replaced the '_.None' by the parameters like this (as I suppose, the _.None is only used if there are no parameters at all):
<dtml-var "xxx(anypar='foo_par',_=_)">
Okay, given that I said you need to have _.None and _ as the first two parameters, why are you suprised that things don't work when you suddenly stop doing this? ;-) try: <dtml-var "xxx(_.None,_,anypar='foo_par')">
Questions which turn up (just for interest):
1) Why isn't this done automagically by setting the 'Namespace' thing in the bindings tab to '_'? So that the caller does not have to grant access to '_' to the calles Python Script explicitly?
Why should the function being called have influence over the parameters passed to it? By going into python (anything inside double quotes in DTML), you bypass the (bad) magic which usually does this.
2) Isn't there really any possibility for the Script to access the '_' namespace of it's own? It seems that I have access to the '_' namespace version which is set up at the beginning of the request.
What are you looking to achieve here?
3) Why do DTML know about the actual namespace of the calling methods and Python Scripts not?
They both know about exactly the same things. If you call a DTML method with: <dtml-var "my_dtml_method()"> ...you will experience exactly the same problems.
It seems to me that Python Scripts do not at all have the same behaviour as DTML methods have. :-(
Nah, they all behave the same way in this situation: badly. Viva la New Religion.
P.S.: Is there a documentation about thsi anywhere?
...the source :-S ...the mailing list archives... Old Skool Zope Style, Chris
Hi Chris, I think my explanations were a bit confusing, sorry for that! I think you wrote down the same much more adequat and in proper english in: http://www.zope.org//Wikis/DevSite/Proposals/NamespacePassingRevisited http://www.zope.org//Wikis/DevSite/Proposals/NamespacePassingRevisited http://www.zope.org/Wikis/DevSite/Proposals/NamespacePassingRevisitedDiscuss ion Sorry, I found it but now by searching for the right keyword ... Why is the proposal not listet in http://www.zope.org/Wikis/DevSite/Proposals/FrontPage ? I've also done further research (which contradict some of your comments in the above document). My Results (Zope 2.3.3, it seems there were some changes since 2.2.x): Python Script with one parameter: def xxx(anypar="foo_default"): <dtml-var xxx> --> ('foo_sort_on', 'foo_default') <dtml-var "xxx(anypar='foo_par',_=_)"> --> ('foo_sort_on', 'foo_par') <dtml-var "xxx(_=_)"> --> ('foo_sort_on', 'foo_default') <dtml-var "xxx()"> --> ('sort_order not defined', 'foo_default') <dtml-var "xxx(_.None,_=_)"> --> ('foo_sort_on', None) <dtml-var "xxx(_.None,_,anypar='foo_par')"> --> TypeError: too many arguments; expected 1, got 2 Python Script without parameters: def xxx(): <dtml-var zzz> --> foo_sort_on <dtml-var "zzz(_=_)"> --> foo_sort_on <dtml-var "zzz()"> --> sort_order not defined <dtml-var "zzz(_.None,_=_)"> --> TypeError: no arguments expected DTML-Method: <dtml-var yyy> --> ('foo_sort_on', 'foo_default') <dtml-var "yyy(_=_)"> --> NameError: REQUEST <dtml-var "yyy(anypar='foo_par',_=_)"> --> ('sort_order not defined', 'foo_par') My conclusions -------------- 1. <dtml-var pymethod> equals to <dtml-var "pymethod(_=_)"> 2. To pass the '_' namespace with other variables pass it the following way: <dtml-var "pymethod(anypar, _=_)"> 3. DTML-methods: do not pass parameters in parenthesis. If you do you get problems with the '_' namespace. Best would be to pass them by pushing them on the namespace before by a 'dtml-let'. Important comment! ------------------ Chris, I don't like to bore you about this. You absolutely do not have to answer to this e-mail if it consumes too much time to do so! See comments to your comments below.
Questions which turn up (just for interest):
1) Why isn't this done automagically by setting the 'Namespace' thing in the bindings tab to '_'? So that the caller does not have to grant access to '_' to the calles Python Script explicitly?
Why should the function being called have influence over the parameters passed to it? By going into python (anything inside double quotes in DTML), you bypass the (bad) magic which usually does this.
Ok, I understand. That was the design decision done by DC. So the <dtml-var xxx> and the <dtml-var "xxx()"> calls really have different behaviour. I think this should be known. I mean, I read a lot of docs over the last two years before I really begun programming and I didn't find any pointers about that.
2) Isn't there really any possibility for the Script to access the '_' namespace of it's own? It seems that I have access to the '_' namespace version which is set up at the beginning of the request.
What are you looking to achieve here? I couldn't reproduce this 'problem'. There wasn't probably one. :-)
3) Why do DTML know about the actual namespace of the calling methods and Python Scripts not?
They both know about exactly the same things. If you call a DTML method with:
<dtml-var "my_dtml_method()">
...you will experience exactly the same problems. You're damn right!
It seems to me that Python Scripts do not at all have the same behaviour as DTML methods have. :-(
Nah, they all behave the same way in this situation: badly. Viva la New Religion. Dito!
P.S.: Is there a documentation about thsi anywhere?
...the source :-S ...the mailing list archives...
Old Skool Zope Style, He, he, yes. I've done this but I didn't find any answers about why it is how it is! Never mind!
Greetings, Gregoire P.S.: The code for your convienience -------------------------------- xxxcaller <dtml-var standard_html_header> <h2><dtml-var title_or_id> <dtml-var document_title></h2> <pre> <dtml-let sort_order="'foo_sort_on'"> <b><dtml-var xxx></b> --> <dtml-var xxx> <b><dtml-var "xxx(anypar='foo_par',_=_)"></b> --> <dtml-var "xxx(anypar='foo_par',_=_)"> <b><dtml-var "xxx(_=_)"></b> --> <dtml-var "xxx(_=_)"> <b><dtml-var "xxx()"></b> --> <dtml-var "xxx()"> <b><dtml-var "xxx(_.None,_=_)"></b> --> <dtml-var "xxx(_.None,_=_)"> <b><dtml-var "xxx(_.None,_,anypar='foo_par')"></b> --> TypeError: too many arguments; expected 1, got 2 </dtml-let> </pre> <pre> <dtml-let sort_order="'foo_sort_on'"> <b><dtml-var zzz></b> --> <dtml-var zzz> <b><dtml-var "zzz(_=_)"></b> --> <dtml-var "zzz(_=_)"> <b><dtml-var "zzz()"></b> --> <dtml-var "zzz()"> <b><dtml-var "zzz(_.None,_=_)"></b> --> TypeError: no arguments expected </dtml-let> </pre> <pre> <dtml-let sort_order="'foo_sort_on'"> <b><dtml-var yyy></b> --> <dtml-var yyy> <b><dtml-var "yyy(_=_)"></b> --> NameError: REQUEST <b><dtml-var "yyy(anypar='foo_par',_=_)"></b> --> <dtml-var "yyy(anypar='foo_par',_=_)"> </dtml-let> </pre> <dtml-var standard_html_footer> -------------------------------- xxx ## Script (Python) "xxx" ##bind container=container ##bind context=context ##bind namespace=_ ##bind script=script ##bind subpath=traverse_subpath ##parameters=anypar='foo_default' ##title= ## if _.has_key('sort_order'): return (_['sort_order'],anypar) else: return ('sort_order not defined',anypar) -------------------------------- yyy <dtml-unless anypar><dtml-call "REQUEST.set('anypar', 'foo_default')"></dtml-unless> <dtml-if sort_order>('<dtml-var sort_order>', '<dtml-var anypar
')<dtml-else>('sort_order not defined', '<dtml-var anypar>')</dtml-if>
-------------------------------- zzz ## Script (Python) "zzz" ##bind container=container ##bind context=context ##bind namespace=_ ##bind script=script ##bind subpath=traverse_subpath ##parameters= ##title= ## if _.has_key('sort_order'): return _['sort_order'] else: return 'sort_order not defined' _____________________________________ Grégoire Weber mailto:gregoire.weber@switzerland.org
Sorry I wanted to add the following note to the previous e-mail but it took me longer than 10 minutes to find it so my e-mail client sent the queued e-mail before automatically :-) Zope Book pdf version page 137 Namespace The Namespace binding is left blank by default. This is an advanced variable that you will not need for any of the examples in this book. If your script is called from a DTML Method, and you have chosen a name for this binding, then the named variable contains the DTML namespace explained in Chapter 7, "Advanced DTML". Also, if this binding is set, the script will search for its parameters in the DTML ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ namespace when called from DTML without explicitly passing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ any arguments. ^^^^^^^^^^^^^^ But why do I have to do the '_=_' thing? Bug? Greg
<dtml-var xxx> --> foo
This is the equivalent of: <dtml-var "xxx(_.None,_)">
<dtml-var "xxx()"> --> sort_order not defined
...so this is obviously wrong sicne you're not passing the namespace.
This is confusing, isn't it?
_____________________________________ Grégoire Weber mailto:gregoire.weber@switzerland.org
participants (2)
-
Chris Withers -
Grégoire Weber