[Zope-Checkins] CVS: Zope2 - DT_In.py:1.50 DT_Let.py:1.8 DT_Return.py:1.3 DT_String.py:1.41 DT_Util.py:1.74 DT_Var.py:1.39 DT_With.py:1.12 DocumentTemplate.py:1.11 __init__.py:1.15 cDocumentTemplate.c:1.36 pDocumentTemplate.py:1.28
shane@digicool.com
shane@digicool.com
Fri, 27 Apr 2001 16:28:14 -0400 (EDT)
Update of /cvs-repository/Zope2/lib/python/DocumentTemplate
In directory korak:/tmp/cvs-serv17686/lib/python/DocumentTemplate
Modified Files:
DT_In.py DT_Let.py DT_Return.py DT_String.py DT_Util.py
DT_Var.py DT_With.py DocumentTemplate.py __init__.py
cDocumentTemplate.c pDocumentTemplate.py
Log Message:
Merged RestrictedPythonBranch!
--- Updated File DT_In.py in package Zope2 --
--- DT_In.py 2001/04/27 18:07:09 1.49
+++ DT_In.py 2001/04/27 20:27:39 1.50
@@ -405,8 +405,9 @@
__rcs_id__='$Id$'
__version__='$Revision$'[11:-2]
+import sys
from DT_Util import ParseError, parse_params, name_param, str
-from DT_Util import render_blocks, InstanceDict, ValidationError, VSEval, expr_globals
+from DT_Util import render_blocks, InstanceDict, ValidationError, Eval
from string import find, atoi, join, split, lower
import re
from DT_InSV import sequence_variables, opt
@@ -445,10 +446,10 @@
if sort=='sequence-item': self.sort=''
if has_key('sort_expr'):
- self.sort_expr=VSEval.Eval(args['sort_expr'], expr_globals)
+ self.sort_expr=Eval(args['sort_expr'])
if has_key('reverse_expr'):
- self.reverse_expr=VSEval.Eval(args['reverse_expr'], expr_globals)
+ self.reverse_expr=Eval(args['reverse_expr'])
if has_key('reverse'):
self.reverse=args['reverse']
@@ -596,7 +597,7 @@
else:
result = []
append=result.append
- validate=md.validate
+ read_guard = md.read_guard
for index in range(first,end):
# preset
kw['previous-sequence']= 0
@@ -625,18 +626,19 @@
except: pass
if index==last: kw['sequence-end']=1
-
- client=sequence[index]
- if validate is not None:
- try: vv=validate(sequence,sequence,None,client,md)
- except: vv=0
- if not vv:
+ if read_guard is not None:
+ try: client = read_guard(sequence)[index]
+ except ValidationError, vv:
if (params.has_key('skip_unauthorized') and
params['skip_unauthorized']):
if index==first: kw['sequence-start']=0
continue
- raise ValidationError, index
+ tb = sys.exc_info()[2]
+ raise ValidationError, '(item %s): %s' % (
+ index, vv), tb
+ else:
+ client = sequence[index]
kw['sequence-index']=index
if type(client)==TupleType and len(client)==2:
@@ -654,6 +656,7 @@
result=join(result, '')
finally:
+ tb = None
if cache: pop()
pop()
@@ -709,20 +712,21 @@
try:
result = []
append=result.append
- validate=md.validate
+ read_guard = md.read_guard
for index in range(l):
if index==last: kw['sequence-end']=1
- client=sequence[index]
-
- if validate is not None:
- try: vv=validate(sequence,sequence,None,client,md)
- except: vv=0
- if not vv:
+ if read_guard is not None:
+ try: client = read_guard(sequence)[index]
+ except ValidationError, vv:
if (self.args.has_key('skip_unauthorized') and
self.args['skip_unauthorized']):
if index==1: kw['sequence-start']=0
continue
- raise ValidationError, index
+ tb = sys.exc_info()[2]
+ raise ValidationError, '(item %s): %s' % (
+ index, vv), tb
+ else:
+ client = sequence[index]
kw['sequence-index']=index
if type(client)==TupleType and len(client)==2:
@@ -738,6 +742,7 @@
result=join(result, '')
finally:
+ tb = None
if cache: pop()
pop()
@@ -841,7 +846,6 @@
def nocase(str1, str2):
return cmp(lower(str1), lower(str2))
-import sys
if sys.modules.has_key("locale"): # only if locale is already imported
from locale import strcoll
--- Updated File DT_Let.py in package Zope2 --
--- DT_Let.py 2001/04/27 18:07:10 1.7
+++ DT_Let.py 2001/04/27 20:27:39 1.8
@@ -112,7 +112,7 @@
as desired.
'''
-from DT_Util import render_blocks, Eval, expr_globals, ParseError, strip
+from DT_Util import render_blocks, Eval, ParseError, strip
from DT_Util import str # Probably needed due to hysterical pickles.
import re
@@ -132,7 +132,7 @@
if expr[:1]=='"' and expr[-1:]=='"' and len(expr) > 1:
# expr shorthand
expr=expr[1:-1]
- try: args[i] = name, Eval(expr, expr_globals).eval
+ try: args[i] = name, Eval(expr).eval
except SyntaxError, v:
m,(huh,l,c,src) = v
raise ParseError, (
@@ -174,12 +174,12 @@
value='"%s"' % mo1.group(3)
l=len(mo1.group(1))
else:
- if not text or not strip(text): return result
+ if not text or not text.strip(): return result
raise ParseError, ('invalid parameter: "%s"' % text, tag)
result.append((name,value))
- text=strip(text[l:])
+ text=text[l:].strip()
if text: return apply(parse_let_params,(text,result,tag),parms)
else: return result
--- Updated File DT_Return.py in package Zope2 --
--- DT_Return.py 2001/04/27 18:07:10 1.2
+++ DT_Return.py 2001/04/27 20:27:39 1.3
@@ -84,8 +84,8 @@
##############################################################################
__version__='$Revision$'[11:-2]
-from DT_Util import parse_params, name_param, html_quote, str
-import string, sys
+from DT_Util import parse_params, name_param, str
+import string, sys
from string import find, split, join, atoi, rfind
class ReturnTag:
--- Updated File DT_String.py in package Zope2 --
--- DT_String.py 2001/04/27 18:07:10 1.40
+++ DT_String.py 2001/04/27 20:27:39 1.41
@@ -1,4 +1,3 @@
-
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
@@ -506,7 +505,7 @@
if globals: push(globals)
if mapping:
push(mapping)
- md.validate=self.validate
+ md.read_guard=self.read_guard
if client is not None:
if type(client)==type(()):
md.this=client[-1]
@@ -551,8 +550,8 @@
if pushed: md._pop(pushed) # Get rid of circular reference!
md.level=level # Restore previous level
- validate__roles__=()
- validate=None
+ read_guard__roles__=()
+ read_guard=None
def __str__(self):
return self.read()
--- Updated File DT_Util.py in package Zope2 --
--- DT_Util.py 2001/04/27 18:07:11 1.73
+++ DT_Util.py 2001/04/27 20:27:39 1.74
@@ -85,175 +85,79 @@
'''$Id$'''
__version__='$Revision$'[11:-2]
-import string, math, os
-import re
-from string import strip, join, atoi, lower, split, find
-import VSEval
+import re, os
+from string import lower
+from RestrictedPython.Guards import safe_builtins
+from RestrictedPython.Utilities import utility_builtins
+from RestrictedPython.Eval import RestrictionCapableEval
+LIMITED_BUILTINS = 1
+
str=__builtins__['str'] # Waaaaa, waaaaaaaa needed for pickling waaaaa
ParseError='Document Template Parse Error'
ValidationError='Unauthorized'
-
-def html_quote(v, name='(Unknown name)', md={},
- character_entities=(
- (('&'), '&'),
- (('<'), '<' ),
- (('>'), '>' ),
- (('"'), '"'))): #"
- text=str(v)
- for re,name in character_entities:
- if find(text, re) >= 0: text=join(split(text,re),name)
- return text
-
def int_param(params,md,name,default=0, st=type('')):
try: v=params[name]
except: v=default
if v:
- try: v=atoi(v)
+ try: v=int(v)
except:
v=md[v]
- if type(v) is st: v=atoi(v)
+ if type(v) is st: v=int(v)
return v or 0
-_marker=[]
-
-def careful_getattr(md, inst, name, default=_marker):
-
- if name[:1]!='_':
-
- # Try to get the attribute normally so that we don't
- # accidentally acquire when we shouldn't.
- try: v=getattr(inst, name)
- except:
- if default is not _marker:
- return default
- raise
-
- validate=md.validate
-
- if validate is None: return v
-
- if hasattr(inst,'aq_acquire'):
- return inst.aq_acquire(name, validate, md)
-
- if validate(inst,inst,name,v,md): return v
-
- raise ValidationError, name
-
-def careful_hasattr(md, inst, name):
- v=getattr(inst, name, _marker)
- if v is not _marker:
- try:
- if name[:1]!='_':
- validate=md.validate
- if validate is None: return 1
-
- if hasattr(inst,'aq_acquire'):
- inst.aq_acquire(name, validate, md)
- return 1
-
- if validate(inst,inst,name,v,md): return 1
- except: pass
- return 0
-
-def careful_getitem(md, mapping, key):
- v=mapping[key]
-
- if type(v) is type(''): return v # Short-circuit common case
-
- validate=md.validate
- if validate is None or validate(mapping,mapping,None,v,md): return v
- raise ValidationError, key
-
-def careful_getslice(md, seq, *indexes):
- v=len(indexes)
- if v==2:
- v=seq[indexes[0]:indexes[1]]
- elif v==1:
- v=seq[indexes[0]:]
- else: v=seq[:]
-
- if type(seq) is type(''): return v # Short-circuit common case
-
- validate=md.validate
- if validate is not None:
- for e in v:
- if not validate(seq,seq,None,e,md):
- raise ValidationError, 'unauthorized access to slice member'
-
- return v
-
-def careful_range(md, iFirst, *args):
- # limited range function from Martijn Pieters
- RANGELIMIT = 1000
- if not len(args):
- iStart, iEnd, iStep = 0, iFirst, 1
- elif len(args) == 1:
- iStart, iEnd, iStep = iFirst, args[0], 1
- elif len(args) == 2:
- iStart, iEnd, iStep = iFirst, args[0], args[1]
- else:
- raise AttributeError, 'range() requires 1-3 int arguments'
- if iStep == 0: raise ValueError, 'zero step for range()'
- iLen = int((iEnd - iStart) / iStep)
- if iLen < 0: iLen = 0
- if iLen >= RANGELIMIT: raise ValueError, 'range() too large'
- return range(iStart, iEnd, iStep)
-
-import string, math, whrandom
-
try:
import ExtensionClass
from cDocumentTemplate import InstanceDict, TemplateDict, render_blocks
except: from pDocumentTemplate import InstanceDict, TemplateDict, render_blocks
-
-d=TemplateDict.__dict__
-for name in ('None', 'abs', 'chr', 'divmod', 'float', 'hash', 'hex', 'int',
- 'len', 'max', 'min', 'oct', 'ord', 'round', 'str'):
- d[name]=__builtins__[name]
-d['string']=string
-d['math']=math
-d['whrandom']=whrandom
-
-def careful_pow(self, x, y, z):
- if not z: raise ValueError, 'pow(x, y, z) with z==0'
- return pow(x,y,z)
-d['pow']=careful_pow
-
-try:
- import random
- d['random']=random
-except: pass
+functype = type(int_param)
+class NotBindable:
+ # Used to prevent TemplateDict from trying to bind to functions.
+ def __init__(self, f):
+ self.__call__ = f
+
+d = TemplateDict.__dict__
+for name, f in safe_builtins.items() + utility_builtins.items():
+ if type(f) is functype:
+ d[name] = NotBindable(f)
+ else:
+ d[name] = f
-try:
- import DateTime
- d['DateTime']=DateTime.DateTime
-except: pass
+if LIMITED_BUILTINS:
+ # Replace certain builtins with limited versions.
+ from RestrictedPython.Limits import limited_builtins
+ for name, f in limited_builtins.items():
+ if type(f) is functype:
+ d[name] = NotBindable(f)
+ else:
+ d[name] = f
-def test(self, *args):
- l=len(args)
- for i in range(1, l, 2):
- if args[i-1]: return args[i]
+# The functions below are meant to bind to the TemplateDict.
- if l%2: return args[-1]
+_marker = [] # Create a new marker object.
-d['test']=test
+def careful_getattr(md, inst, name, default=_marker):
+ read_guard = md.read_guard
+ if read_guard is not None:
+ inst = read_guard(inst)
+ if default is _marker:
+ return getattr(inst, name)
+ else:
+ return getattr(inst, name, default)
-def obsolete_attr(self, inst, name, md):
- return careful_getattr(md, inst, name)
+def careful_hasattr(md, inst, name):
+ read_guard = md.read_guard
+ if read_guard is not None:
+ inst = read_guard(inst)
+ return hasattr(inst, name)
-d['attr']=obsolete_attr
d['getattr']=careful_getattr
d['hasattr']=careful_hasattr
-d['range']=careful_range
-#class namespace_:
-# __allow_access_to_unprotected_subobjects__=1
-
def namespace(self, **kw):
"""Create a tuple consisting of a single instance whose attributes are
provided as keyword arguments."""
@@ -273,66 +177,51 @@
else:
vbase = getattr(v, 'aq_base', v)
if callable(vbase):
- if getattr(vbase, 'isDocTemp', 0):
- v = v(None, self)
- else:
- v = v()
+ try:
+ if getattr(vbase, 'isDocTemp', 0):
+ v = v(None, self)
+ else:
+ v = v()
+ except AttributeError, n:
+ if n != '__call__':
+ raise
return v
d['render']=render
-def reorder(self, s, with=None, without=()):
- if with is None: with=s
- d={}
- tt=type(())
- for i in s:
- if type(i) is tt and len(i)==2: k, v = i
- else: k= v = i
- d[k]=v
- r=[]
- a=r.append
- h=d.has_key
-
- for i in without:
- if type(i) is tt and len(i)==2: k, v = i
- else: k= v = i
- if h(k): del d[k]
-
- for i in with:
- if type(i) is tt and len(i)==2: k, v = i
- else: k= v = i
- if h(k):
- a((k,d[k]))
- del d[k]
-
- return r
-
-d['reorder']=reorder
-
-
-expr_globals={
- '__builtins__':{},
- '__guarded_mul__': VSEval.careful_mul,
- '__guarded_getattr__': careful_getattr,
- '__guarded_getitem__': careful_getitem,
- '__guarded_getslice__': careful_getslice,
- }
-class Eval(VSEval.Eval):
-
- def eval(self, mapping):
- d={'_vars': mapping, '_': mapping}
- code=self.code
- globals=self.globals
+class Eval(RestrictionCapableEval):
+
+ def eval(self, md):
+ guard = getattr(md, 'read_guard', None)
+ if guard is not None:
+ self.prepRestrictedCode()
+ code = self.rcode
+ d = {'_': md, '_vars': md,
+ '_read_': guard, '__builtins__': None}
+ else:
+ self.prepUnrestrictedCode()
+ code = self.ucode
+ d = {'_': md, '_vars': md}
+ d.update(self.globals)
+ has_key = d.has_key
for name in self.used:
__traceback_info__ = name
- try: d[name]=mapping.getitem(name,0)
+ try:
+ if not has_key(name):
+ d[name] = md.getitem(name, 0)
except KeyError:
- if name=='_getattr':
- d['__builtins__']=globals
- exec compiled_getattr in d
-
- return eval(code,globals,d)
+ # Swallow KeyErrors since the expression
+ # might not actually need the name. If it
+ # does need the name, a NameError will occur.
+ pass
+ return eval(code, d)
+
+ def __call__(self, **kw):
+ # Never used?
+ md = TemplateDict()
+ md._push(kw)
+ return self.eval(md)
def name_param(params,tag='',expr=0, attr='name', default_unnamed=1):
@@ -354,7 +243,7 @@
if used('expr'):
raise ParseError, ('two exprs given', tag)
v=v[1:-1]
- try: expr=Eval(v, expr_globals)
+ try: expr=Eval(v)
except SyntaxError, v:
raise ParseError, (
'<strong>Expression (Python) Syntax error</strong>:'
@@ -384,7 +273,7 @@
return params[attr]
elif expr and used('expr'):
name=params['expr']
- expr=Eval(name, expr_globals)
+ expr=Eval(name)
return name, expr
raise ParseError, ('No %s given' % attr, tag)
@@ -521,7 +410,7 @@
else: result['']=name
return apply(parse_params,(text[l:],result),parms)
else:
- if not text or not strip(text): return result
+ if not text or not text.strip(): return result
raise ParseError, ('invalid parameter: "%s"' % text, tag)
if not parms.has_key(name):
@@ -536,6 +425,6 @@
result[name]=value
- text=strip(text[l:])
+ text=text[l:].strip()
if text: return apply(parse_params,(text,result),parms)
else: return result
--- Updated File DT_Var.py in package Zope2 --
--- DT_Var.py 2001/04/27 18:07:11 1.38
+++ DT_Var.py 2001/04/27 20:27:39 1.39
@@ -220,11 +220,15 @@
__rcs_id__='$Id$'
__version__='$Revision$'[11:-2]
-from DT_Util import parse_params, name_param, html_quote, str
+from DT_Util import parse_params, name_param, str
import re, string, sys
from string import find, split, join, atoi, rfind
from urllib import quote, quote_plus
+from cgi import escape
+def html_quote(v, name='(Unknown name)', md={}):
+ return escape(str(v), 1)
+
class Var:
name='var'
expr=None
@@ -322,7 +326,7 @@
if have_arg('size'):
size=args['size']
- try: size=atoi(size)
+ try: size=int(size)
except: raise 'Document Error',(
'''a <code>size</code> attribute was used in a <code>var</code>
tag with a non-integer value.''')
@@ -426,7 +430,7 @@
'collection-length': len_format,
'structured-text': structured_text,
- # The rest are depricated:
+ # The rest are deprecated:
'sql-quote': sql_quote,
'html-quote': html_quote,
'url-quote': url_quote,
--- Updated File DT_With.py in package Zope2 --
--- DT_With.py 2000/05/11 18:54:14 1.11
+++ DT_With.py 2001/04/27 20:27:39 1.12
@@ -139,8 +139,8 @@
if self.only:
_md=md
md=TemplateDict()
- if hasattr(_md, 'validate'):
- md.validate=_md.validate
+ if hasattr(_md, 'read_guard'):
+ md.read_guard = _md.read_guard
md._push(v)
try: return render_blocks(self.section, md)
--- Updated File DocumentTemplate.py in package Zope2 --
--- DocumentTemplate.py 1999/03/10 00:15:08 1.10
+++ DocumentTemplate.py 2001/04/27 20:27:39 1.11
@@ -145,32 +145,16 @@
Document templates provide a basic level of access control by
preventing access to names beginning with an underscore.
- Addational control may be provided by providing document templates
- with a 'validate' method. This would typically be done by
+ Additional control may be provided by providing document templates
+ with a 'read_guard' method. This would typically be done by
subclassing one or more of the DocumentTemplate classes.
- If provided, the the 'validate' method will be called when objects
+ If provided, the the 'read_guard' method will be called when objects
are accessed as accessed as instance attributes or when they are
- accessed through keyed access in an expression.. The 'validate'
- method will be called with five arguments:
+ accessed through keyed access in an expression.. The 'read_guard'
+ method will be called with the containing object. It can
+ return a wrapper object from which the attribute will be accessed.
- 1. The containing object that the object was accessed from,
-
- 2. The actual containing object that the object was found in,
- which may be different from the containing onject the object
- was accessed from, if the containing object supports
- acquisition,
-
- 3. The name used to acces the object,
-
- 4. The object, and
-
- 5. The namespace object used to render the document template.
-
- If a document template was called from Bobo, then the namespace
- object will have an attribute, AUTHENTICATED_USER that is the
- user object that was found if and when Bobo authenticated a user.
-
Document Templates may be created 4 ways:
DocumentTemplate.String -- Creates a document templated from a
@@ -201,4 +185,3 @@
from DT_String import String, File
from DT_HTML import HTML, HTMLFile, HTMLDefault
# import DT_UI # Install HTML editing
-from DT_Util import html_quote
--- Updated File __init__.py in package Zope2 --
--- __init__.py 1999/05/17 16:14:59 1.14
+++ __init__.py 2001/04/27 20:27:39 1.15
@@ -92,4 +92,3 @@
import ExtensionClass # work-around for import bug.
from DocumentTemplate import String, File, HTML, HTMLDefault, HTMLFile
-from DocumentTemplate import html_quote
--- Updated File cDocumentTemplate.c in package Zope2 --
--- cDocumentTemplate.c 2000/11/21 22:08:50 1.35
+++ cDocumentTemplate.c 2001/04/27 20:27:39 1.36
@@ -92,7 +92,7 @@
static PyObject *py_isDocTemp=0, *py_blocks=0, *py_=0, *join=0, *py_acquire;
static PyObject *py___call__, *py___roles__, *py_AUTHENTICATED_USER;
static PyObject *py_hasRole, *py__proxy_roles, *py_Unauthorized;
-static PyObject *py_Unauthorized_fmt, *py_validate;
+static PyObject *py_Unauthorized_fmt, *py_read_guard;
static PyObject *py__push, *py__pop, *py_aq_base, *py_renderNS;
/* ----------------------------------------------------- */
@@ -108,7 +108,7 @@
PyObject *inst;
PyObject *cache;
PyObject *namespace;
- PyObject *validate;
+ PyObject *read_guard;
} InstanceDictobject;
staticforward PyExtensionClass InstanceDictType;
@@ -116,18 +116,18 @@
static PyObject *
InstanceDict___init__(InstanceDictobject *self, PyObject *args)
{
- self->validate=NULL;
+ self->read_guard=NULL;
UNLESS(PyArg_ParseTuple(args, "OO|O",
&(self->inst),
&(self->namespace),
- &(self->validate)))
+ &(self->read_guard)))
return NULL;
Py_INCREF(self->inst);
Py_INCREF(self->namespace);
- if (self->validate)
- Py_INCREF(self->validate);
+ if (self->read_guard)
+ Py_INCREF(self->read_guard);
else
- UNLESS(self->validate=PyObject_GetAttr(self->namespace, py_validate))
+ UNLESS(self->read_guard=PyObject_GetAttr(self->namespace, py_read_guard))
return NULL;
UNLESS(self->cache=PyDict_New()) return NULL;
@@ -150,7 +150,7 @@
Py_XDECREF(self->inst);
Py_XDECREF(self->cache);
Py_XDECREF(self->namespace);
- Py_XDECREF(self->validate);
+ Py_XDECREF(self->read_guard);
Py_DECREF(self->ob_type);
PyMem_DEL(self);
}
@@ -182,7 +182,7 @@
char *name;
/* Try to get value from the cache */
- if (r=PyObject_GetItem(self->cache, key)) return r;
+ if ((r=PyObject_GetItem(self->cache, key))) return r;
PyErr_Clear();
/* Check for __str__ */
@@ -193,56 +193,31 @@
return PyObject_Str(self->inst);
}
- /* Do explicit acquisition with "roles" rule */
- if (r=PyObject_GetAttr(self->inst, py_acquire))
- {
- /* Sanity check in case of explicit Aq */
- if (v=PyObject_GetAttr(self->inst, key)) Py_DECREF(v);
- else
- {
- Py_DECREF(r);
- goto KeyError;
- }
-
- if (self->validate != Py_None)
- {
- UNLESS_ASSIGN(r,PyObject_CallFunction(
- r, "OOO", key, self->validate, self->namespace))
- {
- PyObject *tb;
-
- PyErr_Fetch(&r, &v, &tb);
- if (r != PyExc_AttributeError || PyObject_Compare(v,key))
- {
- PyErr_Restore(r,v,tb);
- return NULL;
- }
- Py_XDECREF(r);
- Py_XDECREF(v);
- Py_XDECREF(tb);
-
- goto KeyError;
- }
- }
- else
- UNLESS_ASSIGN(r, PyObject_GetAttr(self->inst, key)) goto KeyError;
- }
- else
- {
- PyErr_Clear();
+ if (self->read_guard != Py_None) {
+ r = PyObject_CallFunction(self->read_guard, "O", self->inst);
+ if (!r) return NULL;
+ }
+ else {
+ r = self->inst;
+ Py_INCREF(r);
+ }
- /* OK, use getattr */
- UNLESS(r=PyObject_GetAttr(self->inst, key)) goto KeyError;
+ ASSIGN(r, PyObject_GetAttr(r, key));
+ if (!r) {
+ PyObject *tb;
+
+ PyErr_Fetch(&r, &v, &tb);
+ if (r != PyExc_AttributeError) /* || PyObject_Compare(v,key)) */
+ {
+ PyErr_Restore(r,v,tb);
+ return NULL;
+ }
+ Py_XDECREF(r);
+ Py_XDECREF(v);
+ Py_XDECREF(tb);
- if (self->validate != Py_None)
- {
- UNLESS(v=PyObject_CallFunction(
- self->validate,"OOOOO",
- self->inst, self->inst, key, r, self->namespace))
- return NULL;
- Py_DECREF(v);
- }
- }
+ goto KeyError;
+ }
if (r && PyObject_SetItem(self->cache, key, r) < 0) PyErr_Clear();
@@ -312,9 +287,7 @@
staticforward PyExtensionClass MMtype;
static PyObject *
-MM_push(self, args)
- MM *self;
- PyObject *args;
+MM_push(MM *self, PyObject *args)
{
PyObject *src;
UNLESS(PyArg_Parse(args, "O", &src)) return NULL;
@@ -324,9 +297,7 @@
}
static PyObject *
-MM_pop(self, args)
- MM *self;
- PyObject *args;
+MM_pop(MM *self, PyObject *args)
{
int i=1, l;
PyObject *r;
@@ -343,9 +314,7 @@
}
static PyObject *
-MM__init__(self, args)
- MM *self;
- PyObject *args;
+MM__init__(MM *self, PyObject *args)
{
UNLESS(PyArg_Parse(args, "")) return NULL;
UNLESS(self->data=PyList_New(0)) return NULL;
@@ -385,7 +354,7 @@
Py_INCREF(base);
}
- if ( value = PyObject_GetAttr(base, py_isDocTemp) ) {
+ if ( (value = PyObject_GetAttr(base, py_isDocTemp)) ) {
if (PyObject_IsTrue(value)) {
result = 1;
}
@@ -408,12 +377,12 @@
while (--i >= 0)
{
e=PyList_GetItem(self->data,i);
- if (e=PyObject_GetItem(e,key))
+ if ((e=PyObject_GetItem(e,key)))
{
if (!call) return e;
/* Try calling __render_with_namespace__ */
- if (rr = PyObject_GetAttr(e, py_renderNS))
+ if ((rr = PyObject_GetAttr(e, py_renderNS)))
{
Py_DECREF(e);
UNLESS_ASSIGN(rr, PyObject_CallFunction(rr, "O", self))
@@ -516,8 +485,7 @@
};
static void
-MM_dealloc(self)
- MM *self;
+MM_dealloc(MM *self)
{
Py_XDECREF(self->data);
Py_XDECREF(self->dict);
@@ -538,7 +506,7 @@
{
PyObject *v;
- if (v=PyDict_GetItem(self->dict, name))
+ if ((v=PyDict_GetItem(self->dict, name)))
{
Py_INCREF(v);
return v;
@@ -568,8 +536,7 @@
}
static int
-MM_length(self)
- MM *self;
+MM_length(MM *self)
{
long l=0, el, i;
PyObject *e=0;
@@ -800,7 +767,7 @@
{
/* We have to be careful to handle key errors here */
n=cond;
- if (cond=PyObject_GetItem(md,cond))
+ if ((cond=PyObject_GetItem(md,cond)))
{
if (PyDict_SetItem(cache, n, cond) < 0)
{
@@ -912,7 +879,7 @@
};
void
-initcDocumentTemplate()
+initcDocumentTemplate(void)
{
PyObject *m, *d;
char *rev="$Revision$";
@@ -927,7 +894,7 @@
UNLESS(py___roles__=PyString_FromString("__roles__")) return;
UNLESS(py__proxy_roles=PyString_FromString("_proxy_roles")) return;
UNLESS(py_hasRole=PyString_FromString("hasRole")) return;
- UNLESS(py_validate=PyString_FromString("validate")) return;
+ UNLESS(py_read_guard=PyString_FromString("read_guard")) return;
UNLESS(py__push=PyString_FromString("_push")) return;
UNLESS(py__pop=PyString_FromString("_pop")) return;
UNLESS(py_aq_base=PyString_FromString("aq_base")) return;
--- Updated File pDocumentTemplate.py in package Zope2 --
--- pDocumentTemplate.py 2001/01/16 18:08:27 1.27
+++ pDocumentTemplate.py 2001/04/27 20:27:39 1.28
@@ -117,14 +117,14 @@
class InstanceDict:
- validate=None
+ read_guard=None
- def __init__(self,o,namespace,validate=None):
+ def __init__(self,o,namespace,read_guard=None):
self.self=o
self.cache={}
self.namespace=namespace
- if validate is None: self.validate=namespace.validate
- else: self.validate=validate
+ if read_guard is None: self.read_guard=namespace.read_guard
+ else: self.read_guard=read_guard
def has_key(self,key):
return hasattr(self.self,key)
@@ -144,14 +144,16 @@
if key[:1]=='_':
if key != '__str__':
raise KeyError, key # Don't divuldge private data
- r=str(inst)
- else:
- try: r=getattr(inst,key)
- except AttributeError: raise KeyError, key
+ else:
+ return str(inst)
- v=self.validate
- if v is not None: v(inst,inst,key,r,self.namespace)
+ read_guard = self.read_guard
+ if read_guard is not None:
+ inst = read_guard(inst)
+ try: r = getattr(inst, key)
+ except AttributeError: raise KeyError, key
+
self.cache[key]=r
return r
@@ -212,9 +214,14 @@
return v.__render_with_namespace__(self)
vbase = getattr(v, 'aq_base', v)
if callable(vbase):
- if getattr(vbase, 'isDocTemp', None):
- return v(None, self)
- return v()
+ try:
+ if getattr(vbase, 'isDocTemp', 0):
+ v = v(None, self)
+ else:
+ v = v()
+ except AttributeError, n:
+ if n != '__call__':
+ raise
return v
def has_key(self,key):