Ticket #88: strict_errors.diff
| File strict_errors.diff, 10.6 KB (added by cmlenz, 17 years ago) |
|---|
-
genshi/template/tests/text.py
37 37 #if foo 38 38 bar 39 39 #end 'if foo'""") 40 self.assertEqual('\n', str(tmpl.generate( )))40 self.assertEqual('\n', str(tmpl.generate(foo=False))) 41 41 42 42 def test_latin1_encoded(self): 43 43 text = u'$foo\xf6$bar'.encode('iso-8859-1') -
genshi/template/tests/eval.py
16 16 import unittest 17 17 18 18 from genshi.core import Markup 19 from genshi.template.eval import Expression, Suite, Undefined 19 from genshi.template.eval import Expression, Suite, UndefinedError 20 20 21 21 22 22 class ExpressionTestCase(unittest.TestCase): … … 40 40 def test_builtins(self): 41 41 expr = Expression('Markup') 42 42 self.assertEqual(expr.evaluate({}), Markup) 43 expr = Expression('Undefined')44 self.assertEqual(expr.evaluate({}), Undefined)45 43 46 44 def test_str_literal(self): 47 45 self.assertEqual('foo', Expression('"foo"').evaluate({})) … … 323 321 324 322 def test_error_access_undefined(self): 325 323 expr = Expression("nothing", filename='index.html', lineno=50) 326 self.assertEqual(Undefined, type(expr.evaluate({})))327 328 def test_error_call_undefined(self):329 expr = Expression("nothing()", filename='index.html', lineno=50)330 324 try: 331 325 expr.evaluate({}) 332 self.fail('Expected NameError')333 except NameError, e:326 self.fail('Expected UndefinedError') 327 except UndefinedError, e: 334 328 exc_type, exc_value, exc_traceback = sys.exc_info() 335 329 frame = exc_traceback.tb_next 336 330 frames = [] 337 331 while frame.tb_next: 338 332 frame = frame.tb_next 339 333 frames.append(frame) 340 self.assertEqual(' Variable "nothing" isnot defined', str(e))341 self.assertEqual("<Expression 'nothing ()'>",342 frames[- 3].tb_frame.f_code.co_name)334 self.assertEqual('"nothing" not defined', str(e)) 335 self.assertEqual("<Expression 'nothing'>", 336 frames[-2].tb_frame.f_code.co_name) 343 337 self.assertEqual('index.html', 344 frames[- 3].tb_frame.f_code.co_filename)345 self.assertEqual(50, frames[- 3].tb_lineno)338 frames[-2].tb_frame.f_code.co_filename) 339 self.assertEqual(50, frames[-2].tb_lineno) 346 340 347 341 def test_error_getattr_undefined(self): 348 expr = Expression("nothing.nil", filename='index.html', lineno=50) 342 class Something(object): 343 def __repr__(self): 344 return '<Something>' 345 expr = Expression('something.nil', filename='index.html', lineno=50) 349 346 try: 350 expr.evaluate({ })351 self.fail('Expected NameError')352 except NameError, e:347 expr.evaluate({'something': Something()}) 348 self.fail('Expected UndefinedError') 349 except UndefinedError, e: 353 350 exc_type, exc_value, exc_traceback = sys.exc_info() 354 351 frame = exc_traceback.tb_next 355 352 frames = [] 356 353 while frame.tb_next: 357 354 frame = frame.tb_next 358 355 frames.append(frame) 359 self.assertEqual(' Variable "nothing" is not defined', str(e))360 self.assertEqual("<Expression ' nothing.nil'>",361 frames[- 3].tb_frame.f_code.co_name)356 self.assertEqual('<Something> has no member named "nil"', str(e)) 357 self.assertEqual("<Expression 'something.nil'>", 358 frames[-2].tb_frame.f_code.co_name) 362 359 self.assertEqual('index.html', 363 frames[- 3].tb_frame.f_code.co_filename)364 self.assertEqual(50, frames[- 3].tb_lineno)360 frames[-2].tb_frame.f_code.co_filename) 361 self.assertEqual(50, frames[-2].tb_lineno) 365 362 366 def test_error_getitem_undefined(self): 367 expr = Expression("nothing[0]", filename='index.html', lineno=50) 363 def test_error_getitem_undefined_string(self): 364 class Something(object): 365 def __repr__(self): 366 return '<Something>' 367 expr = Expression('something["nil"]', filename='index.html', lineno=50) 368 368 try: 369 expr.evaluate({ })370 self.fail('Expected NameError')371 except NameError, e:369 expr.evaluate({'something': Something()}) 370 self.fail('Expected UndefinedError') 371 except UndefinedError, e: 372 372 exc_type, exc_value, exc_traceback = sys.exc_info() 373 373 frame = exc_traceback.tb_next 374 374 frames = [] 375 375 while frame.tb_next: 376 376 frame = frame.tb_next 377 377 frames.append(frame) 378 self.assertEqual(' Variable "nothing" is not defined', str(e))379 self.assertEqual( "<Expression 'nothing[0]'>",380 frames[- 3].tb_frame.f_code.co_name)378 self.assertEqual('<Something> has no member named "nil"', str(e)) 379 self.assertEqual('''<Expression 'something["nil"]'>''', 380 frames[-2].tb_frame.f_code.co_name) 381 381 self.assertEqual('index.html', 382 frames[- 3].tb_frame.f_code.co_filename)383 self.assertEqual(50, frames[- 3].tb_lineno)382 frames[-2].tb_frame.f_code.co_filename) 383 self.assertEqual(50, frames[-2].tb_lineno) 384 384 385 def test_error_getattr_nested_undefined(self):386 expr = Expression("nothing.nil", filename='index.html', lineno=50)387 val = expr.evaluate({'nothing': object()})388 assert isinstance(val, Undefined)389 self.assertEqual("nil", val._name)390 385 391 def test_error_getitem_nested_undefined_string(self):392 expr = Expression("nothing['bla']", filename='index.html', lineno=50)393 val = expr.evaluate({'nothing': object()})394 assert isinstance(val, Undefined)395 self.assertEqual("bla", val._name)396 397 def test_error_getitem_nested_undefined_int(self):398 expr = Expression("nothing[0]", filename='index.html', lineno=50)399 self.assertRaises(TypeError, expr.evaluate, {'nothing': object()})400 401 402 386 class SuiteTestCase(unittest.TestCase): 403 387 404 388 def test_assign(self): -
genshi/template/eval.py
24 24 import sys 25 25 26 26 from genshi.core import Markup 27 from genshi.template.base import TemplateRuntimeError 27 28 from genshi.util import flatten 28 29 29 __all__ = ['Expression', 'Suite' , 'Undefined']30 __all__ = ['Expression', 'Suite'] 30 31 31 32 32 33 class Code(object): … … 148 149 '_lookup_item': _lookup_item}, data 149 150 150 151 151 class Undefined(object): 152 """Represents a reference to an undefined variable. 153 154 Unlike the Python runtime, template expressions can refer to an undefined 155 variable without causing a `NameError` to be raised. The result will be an 156 instance of the `Undefined´ class, which is treated the same as `False` in 157 conditions, and acts as an empty collection in iterations: 158 159 >>> foo = Undefined('foo') 160 >>> bool(foo) 161 False 162 >>> list(foo) 163 [] 164 >>> print foo 165 undefined 166 167 However, calling an undefined variable, or trying to access an attribute 168 of that variable, will raise an exception that includes the name used to 169 reference that undefined variable. 170 171 >>> foo('bar') 172 Traceback (most recent call last): 173 ... 174 NameError: Variable "foo" is not defined 175 176 >>> foo.bar 177 Traceback (most recent call last): 178 ... 179 NameError: Variable "foo" is not defined 152 class UndefinedError(TemplateRuntimeError): 153 """Exception thrown when a template expression attempts to access a variable 154 not defined in the context. 180 155 """ 181 __slots__ = ['_name'] 156 def __init__(self, name, owner=None): 157 if owner is not None: 158 message = '%r has no member named "%s"' % (owner, name) 159 else: 160 message = '"%s" not defined' % name 161 TemplateRuntimeError.__init__(self, message) 182 162 183 def __init__(self, name):184 self._name = name185 163 186 def __call__(self, *args, **kwargs):187 __traceback_hide__ = True188 self.throw()189 190 def __getattr__(self, name):191 __traceback_hide__ = True192 self.throw()193 194 def __iter__(self):195 return iter([])196 197 def __nonzero__(self):198 return False199 200 def __repr__(self):201 return 'undefined'202 203 def throw(self):204 __traceback_hide__ = True205 raise NameError('Variable "%s" is not defined' % self._name)206 207 208 164 def _parse(source, mode='eval'): 209 165 if isinstance(source, unicode): 210 166 source = '\xef\xbb\xbf' + source.encode('utf-8') … … 238 194 code.co_lnotab, (), ()) 239 195 240 196 BUILTINS = __builtin__.__dict__.copy() 241 BUILTINS.update({'Markup': Markup , 'Undefined': Undefined})242 _UNDEF = Undefined(None)197 BUILTINS.update({'Markup': Markup}) 198 UNDEFINED = object() 243 199 244 200 def _lookup_name(data, name): 245 201 __traceback_hide__ = True 246 val = data.get(name, _UNDEF)247 if val is _UNDEF:202 val = data.get(name, UNDEFINED) 203 if val is UNDEFINED: 248 204 val = BUILTINS.get(name, val) 249 if val is _UNDEF:250 r eturn Undefined(name)205 if val is UNDEFINED: 206 raise UndefinedError(name) 251 207 return val 252 208 253 209 def _lookup_attr(data, obj, key): 254 210 __traceback_hide__ = True 255 if type(obj) is Undefined:256 obj.throw()257 211 if hasattr(obj, key): 258 212 return getattr(obj, key) 259 213 try: 260 214 return obj[key] 261 215 except (KeyError, TypeError): 262 r eturn Undefined(key)216 raise UndefinedError(key, owner=obj) 263 217 264 218 def _lookup_item(data, obj, key): 265 219 __traceback_hide__ = True 266 if type(obj) is Undefined:267 obj.throw()268 220 if len(key) == 1: 269 221 key = key[0] 270 222 try: 271 223 return obj[key] 272 224 except (AttributeError, KeyError, IndexError, TypeError), e: 273 225 if isinstance(key, basestring): 274 val = getattr(obj, key, _UNDEF)275 if val is _UNDEF:276 val = Undefined(key)226 val = getattr(obj, key, UNDEFINED) 227 if val is UNDEFINED: 228 raise UndefinedError(key, owner=obj) 277 229 return val 278 230 raise 279 231
