annotate genshi/template/eval.py @ 917:bcaa91c42b97 experimental-py3k

add support for python 3 to genshi.template expression evaluator: * add support for python 3 AST: * AST for raise has changed in Python 3. * Python 3 adds AST nodes for individual arguments and Bytes. * use genshi.compat functions for dealing with code objects. * do not coerce byte strings to unicode in Python 3 ASTTransformer. * replace doctests that reply on exception names with uglier but more compatible try:.. except:.. doctest * handle filename preferences of Python 2 and 3 (2 prefers bytes, 3 prefers unicode). * ifilter is gone from itertools in Python 3 so use repeat for tests instead.
author hodgestar
date Sun, 24 Oct 2010 22:39:08 +0000
parents 85e4678337cf
children
rev   line source
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
2 #
897
85e4678337cf Update changelog and copyright years.
cmlenz
parents: 896
diff changeset
3 # Copyright (C) 2006-2010 Edgewall Software
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
4 # All rights reserved.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
5 #
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
8 # are also available at http://genshi.edgewall.org/wiki/License.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
9 #
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://genshi.edgewall.org/log/.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
13
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
14 """Support for "safe" evaluation of Python expressions."""
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
15
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
16 import __builtin__
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
17
601
9ae986bcba9a Simplify implementation of `py:with` directive by compiling to a `Suite`, instead of manually breaking up the statement and compiling each part to an `Expression`. Also, the first line of code in a `Suite` is now stored as the "function name" of the bytecode, so that it shows up in tracebacks.
cmlenz
parents: 586
diff changeset
18 from textwrap import dedent
793
7cf2407671c2 Get rid of a couple more -3 warnings.
cmlenz
parents: 750
diff changeset
19 from types import CodeType
357
c5684b65c9b7 Improve the way locals (in list comprehensions, lambdas and generator expressions) are handled in template expressions.
cmlenz
parents: 343
diff changeset
20
401
9582328f82e5 Make the `Markup` class available by default in template expressions. Closes #67.
cmlenz
parents: 396
diff changeset
21 from genshi.core import Markup
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
22 from genshi.template.astutil import ASTTransformer, ASTCodeGenerator, \
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
23 _ast, parse
418
878ffab274a6 Make expression error handling more strict. Closes #88.
cmlenz
parents: 408
diff changeset
24 from genshi.template.base import TemplateRuntimeError
357
c5684b65c9b7 Improve the way locals (in list comprehensions, lambdas and generator expressions) are handled in template expressions.
cmlenz
parents: 343
diff changeset
25 from genshi.util import flatten
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
26
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
27 from genshi.compat import get_code_params, build_code_chunk, IS_PYTHON2
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
28
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
29 __all__ = ['Code', 'Expression', 'Suite', 'LenientLookup', 'StrictLookup',
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
30 'Undefined', 'UndefinedError']
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 418
diff changeset
31 __docformat__ = 'restructuredtext en'
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
32
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
33
731
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
34 # Check for a Python 2.4 bug in the eval loop
739
b40efce75bcd Another Python 2.3 fix in the wake of #221.
cmlenz
parents: 736
diff changeset
35 has_star_import_bug = False
731
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
36 try:
736
62e816c3ced8 Yet another followup fix for #221.
cmlenz
parents: 733
diff changeset
37 class _FakeMapping(object):
731
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
38 __getitem__ = __setitem__ = lambda *a: None
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
39 exec 'from sys import *' in {}, _FakeMapping()
739
b40efce75bcd Another Python 2.3 fix in the wake of #221.
cmlenz
parents: 736
diff changeset
40 except SystemError:
731
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
41 has_star_import_bug = True
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
42 del _FakeMapping
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
43
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
44
731
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
45 def _star_import_patch(mapping, modname):
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
46 """This function is used as helper if a Python version with a broken
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
47 star-import opcode is in use.
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
48 """
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
49 module = __import__(modname, None, None, ['__all__'])
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
50 if hasattr(module, '__all__'):
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
51 members = module.__all__
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
52 else:
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
53 members = [x for x in module.__dict__ if not x.startswith('_')]
733
bc5d0850dfaf Update to r855 for Python 2.3 support. Fixes #221 (hopefully).
athomas
parents: 731
diff changeset
54 mapping.update([(name, getattr(module, name)) for name in members])
731
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
55
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
56
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
57 class Code(object):
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
58 """Abstract base class for the `Expression` and `Suite` classes."""
565
aa8e85a4085e * The I18n extractor now handles gettext function calls that use non-string parameters as well as keyword arguments.
cmlenz
parents: 564
diff changeset
59 __slots__ = ['source', 'code', 'ast', '_globals']
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
60
606
9ada030ad986 Changed the default error handling mode to "strict".
cmlenz
parents: 604
diff changeset
61 def __init__(self, source, filename=None, lineno=-1, lookup='strict',
604
6d1fa718794f Fix bug that slipped into [717]: the code of a `py:with` directive was not being compiled with AST transformations applied.
cmlenz
parents: 601
diff changeset
62 xform=None):
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
63 """Create the code object, either from a string, or from an AST node.
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
64
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 418
diff changeset
65 :param source: either a string containing the source code, or an AST
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 418
diff changeset
66 node
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 418
diff changeset
67 :param filename: the (preferably absolute) name of the file containing
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 418
diff changeset
68 the code
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 418
diff changeset
69 :param lineno: the number of the line on which the code was found
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
70 :param lookup: the lookup class that defines how variables are looked
606
9ada030ad986 Changed the default error handling mode to "strict".
cmlenz
parents: 604
diff changeset
71 up in the context; can be either "strict" (the default),
9ada030ad986 Changed the default error handling mode to "strict".
cmlenz
parents: 604
diff changeset
72 "lenient", or a custom lookup class
604
6d1fa718794f Fix bug that slipped into [717]: the code of a `py:with` directive was not being compiled with AST transformations applied.
cmlenz
parents: 601
diff changeset
73 :param xform: the AST transformer that should be applied to the code;
6d1fa718794f Fix bug that slipped into [717]: the code of a `py:with` directive was not being compiled with AST transformations applied.
cmlenz
parents: 601
diff changeset
74 if `None`, the appropriate transformation is chosen
6d1fa718794f Fix bug that slipped into [717]: the code of a `py:with` directive was not being compiled with AST transformations applied.
cmlenz
parents: 601
diff changeset
75 depending on the mode
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
76 """
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
77 if isinstance(source, basestring):
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
78 self.source = source
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
79 node = _parse(source, mode=self.mode)
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
80 else:
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
81 assert isinstance(source, _ast.AST), \
601
9ae986bcba9a Simplify implementation of `py:with` directive by compiling to a `Suite`, instead of manually breaking up the statement and compiling each part to an `Expression`. Also, the first line of code in a `Suite` is now stored as the "function name" of the bytecode, so that it shows up in tracebacks.
cmlenz
parents: 586
diff changeset
82 'Expected string or AST node, but got %r' % source
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
83 self.source = '?'
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
84 if self.mode == 'eval':
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
85 node = _ast.Expression()
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
86 node.body = source
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
87 else:
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
88 node = _ast.Module()
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
89 node.body = [source]
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
90
565
aa8e85a4085e * The I18n extractor now handles gettext function calls that use non-string parameters as well as keyword arguments.
cmlenz
parents: 564
diff changeset
91 self.ast = node
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
92 self.code = _compile(node, self.source, mode=self.mode,
604
6d1fa718794f Fix bug that slipped into [717]: the code of a `py:with` directive was not being compiled with AST transformations applied.
cmlenz
parents: 601
diff changeset
93 filename=filename, lineno=lineno, xform=xform)
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
94 if lookup is None:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
95 lookup = LenientLookup
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
96 elif isinstance(lookup, basestring):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
97 lookup = {'lenient': LenientLookup, 'strict': StrictLookup}[lookup]
654
12f3a60d5528 Fix thread-safety problem in template code evaluation. Closes #158. Thanks to Christian Boos for the patch.
cmlenz
parents: 606
diff changeset
98 self._globals = lookup.globals
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
99
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 702
diff changeset
100 def __getstate__(self):
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 702
diff changeset
101 state = {'source': self.source, 'ast': self.ast,
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 702
diff changeset
102 'lookup': self._globals.im_self}
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
103 state['code'] = get_code_params(self.code)
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 702
diff changeset
104 return state
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 702
diff changeset
105
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 702
diff changeset
106 def __setstate__(self, state):
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 702
diff changeset
107 self.source = state['source']
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 702
diff changeset
108 self.ast = state['ast']
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
109 self.code = CodeType(0, *state['code'])
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 702
diff changeset
110 self._globals = state['lookup'].globals
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 702
diff changeset
111
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
112 def __eq__(self, other):
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
113 return (type(other) == type(self)) and (self.code == other.code)
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
114
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
115 def __hash__(self):
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
116 return hash(self.code)
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
117
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
118 def __ne__(self, other):
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
119 return not self == other
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
120
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
121 def __repr__(self):
860
61d37796da98 A bit of cleanup of the `Markup` Python implementation.
cmlenz
parents: 854
diff changeset
122 return '%s(%r)' % (type(self).__name__, self.source)
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
123
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
124
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
125 class Expression(Code):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
126 """Evaluates Python expressions used in templates.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
127
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
128 >>> data = dict(test='Foo', items=[1, 2, 3], dict={'some': 'thing'})
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
129 >>> Expression('test').evaluate(data)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
130 'Foo'
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
131
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
132 >>> Expression('items[0]').evaluate(data)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
133 1
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
134 >>> Expression('items[-1]').evaluate(data)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
135 3
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
136 >>> Expression('dict["some"]').evaluate(data)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
137 'thing'
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
138
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
139 Similar to e.g. Javascript, expressions in templates can use the dot
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
140 notation for attribute access to access items in mappings:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
141
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
142 >>> Expression('dict.some').evaluate(data)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
143 'thing'
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
144
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
145 This also works the other way around: item access can be used to access
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 418
diff changeset
146 any object attribute:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
147
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
148 >>> class MyClass(object):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
149 ... myattr = 'Bar'
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
150 >>> data = dict(mine=MyClass(), key='myattr')
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
151 >>> Expression('mine.myattr').evaluate(data)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
152 'Bar'
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
153 >>> Expression('mine["myattr"]').evaluate(data)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
154 'Bar'
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
155 >>> Expression('mine[key]').evaluate(data)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
156 'Bar'
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
157
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
158 All of the standard Python operators are available to template expressions.
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 418
diff changeset
159 Built-in functions such as ``len()`` are also available in template
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
160 expressions:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
161
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
162 >>> data = dict(items=[1, 2, 3])
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
163 >>> Expression('len(items)').evaluate(data)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
164 3
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
165 """
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
166 __slots__ = []
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
167 mode = 'eval'
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
168
343
4ff2338e89cd Remove automatic calling of expression evaluation results if they are callable. See [http://groups.google.com/group/genshi/browse_thread/thread/f515986760918d41 this mailing list thread].
cmlenz
parents: 340
diff changeset
169 def evaluate(self, data):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
170 """Evaluate the expression against the given data dictionary.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
171
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 418
diff changeset
172 :param data: a mapping containing the data to evaluate against
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 418
diff changeset
173 :return: the result of the evaluation
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
174 """
418
878ffab274a6 Make expression error handling more strict. Closes #88.
cmlenz
parents: 408
diff changeset
175 __traceback_hide__ = 'before_and_this'
691
be6890ff84fe Minor cleanup in eval module.
cmlenz
parents: 684
diff changeset
176 _globals = self._globals(data)
682
75795aadf920 Assigning to a variable named `data` in a Python code block no longer breaks context lookup. We now use the name `__data__` for internal data, hoping that that name is not as commonly used in templates.
cmlenz
parents: 654
diff changeset
177 return eval(self.code, _globals, {'__data__': data})
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
178
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
179
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
180 class Suite(Code):
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
181 """Executes Python statements used in templates.
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
182
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
183 >>> data = dict(test='Foo', items=[1, 2, 3], dict={'some': 'thing'})
473
5870bdf03fca Apply patch from #113, also closing #114.
cmlenz
parents: 442
diff changeset
184 >>> Suite("foo = dict['some']").execute(data)
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
185 >>> data['foo']
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
186 'thing'
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
187 """
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
188 __slots__ = []
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
189 mode = 'exec'
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
190
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
191 def execute(self, data):
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
192 """Execute the suite in the given data dictionary.
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
193
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 418
diff changeset
194 :param data: a mapping containing the data to execute in
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
195 """
418
878ffab274a6 Make expression error handling more strict. Closes #88.
cmlenz
parents: 408
diff changeset
196 __traceback_hide__ = 'before_and_this'
691
be6890ff84fe Minor cleanup in eval module.
cmlenz
parents: 684
diff changeset
197 _globals = self._globals(data)
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
198 exec self.code in _globals, data
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
199
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
200
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
201 UNDEFINED = object()
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
202
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
203
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
204 class UndefinedError(TemplateRuntimeError):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
205 """Exception thrown when a template expression attempts to access a variable
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
206 not defined in the context.
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
207
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
208 :see: `LenientLookup`, `StrictLookup`
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
209 """
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
210 def __init__(self, name, owner=UNDEFINED):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
211 if owner is not UNDEFINED:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
212 message = '%s has no member named "%s"' % (repr(owner), name)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
213 else:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
214 message = '"%s" not defined' % name
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
215 TemplateRuntimeError.__init__(self, message)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
216
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
217
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
218 class Undefined(object):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
219 """Represents a reference to an undefined variable.
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
220
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
221 Unlike the Python runtime, template expressions can refer to an undefined
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
222 variable without causing a `NameError` to be raised. The result will be an
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
223 instance of the `Undefined` class, which is treated the same as ``False`` in
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
224 conditions, but raise an exception on any other operation:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
225
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
226 >>> foo = Undefined('foo')
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
227 >>> bool(foo)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
228 False
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
229 >>> list(foo)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
230 []
853
4376010bb97e Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents: 845
diff changeset
231 >>> print(foo)
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
232 undefined
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
233
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
234 However, calling an undefined variable, or trying to access an attribute
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
235 of that variable, will raise an exception that includes the name used to
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
236 reference that undefined variable.
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
237
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
238 >>> try:
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
239 ... foo('bar')
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
240 ... except UndefinedError, e:
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
241 ... print e.msg
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
242 "foo" not defined
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
243
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
244 >>> try:
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
245 ... foo.bar
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
246 ... except UndefinedError, e:
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
247 ... print e.msg
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
248 "foo" not defined
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
249
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
250 :see: `LenientLookup`
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
251 """
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
252 __slots__ = ['_name', '_owner']
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
253
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
254 def __init__(self, name, owner=UNDEFINED):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
255 """Initialize the object.
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
256
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
257 :param name: the name of the reference
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
258 :param owner: the owning object, if the variable is accessed as a member
418
878ffab274a6 Make expression error handling more strict. Closes #88.
cmlenz
parents: 408
diff changeset
259 """
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
260 self._name = name
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
261 self._owner = owner
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
262
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
263 def __iter__(self):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
264 return iter([])
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
265
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
266 def __nonzero__(self):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
267 return False
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
268
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
269 def __repr__(self):
860
61d37796da98 A bit of cleanup of the `Markup` Python implementation.
cmlenz
parents: 854
diff changeset
270 return '<%s %r>' % (type(self).__name__, self._name)
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
271
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
272 def __str__(self):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
273 return 'undefined'
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
274
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
275 def _die(self, *args, **kwargs):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
276 """Raise an `UndefinedError`."""
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
277 __traceback_hide__ = True
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
278 raise UndefinedError(self._name, self._owner)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
279 __call__ = __getattr__ = __getitem__ = _die
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
280
878
abfabaea906f Apply patch from #324 for Python 2.6.2 compatibility fix.
cmlenz
parents: 860
diff changeset
281 # Hack around some behavior introduced in Python 2.6.2
abfabaea906f Apply patch from #324 for Python 2.6.2 compatibility fix.
cmlenz
parents: 860
diff changeset
282 # http://genshi.edgewall.org/ticket/324
abfabaea906f Apply patch from #324 for Python 2.6.2 compatibility fix.
cmlenz
parents: 860
diff changeset
283 __length_hint__ = None
abfabaea906f Apply patch from #324 for Python 2.6.2 compatibility fix.
cmlenz
parents: 860
diff changeset
284
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
285
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
286 class LookupBase(object):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
287 """Abstract base class for variable lookup implementations."""
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
288
822
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 806
diff changeset
289 @classmethod
691
be6890ff84fe Minor cleanup in eval module.
cmlenz
parents: 684
diff changeset
290 def globals(cls, data):
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
291 """Construct the globals dictionary to use as the execution context for
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
292 the expression or suite.
418
878ffab274a6 Make expression error handling more strict. Closes #88.
cmlenz
parents: 408
diff changeset
293 """
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
294 return {
691
be6890ff84fe Minor cleanup in eval module.
cmlenz
parents: 684
diff changeset
295 '__data__': data,
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
296 '_lookup_name': cls.lookup_name,
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
297 '_lookup_attr': cls.lookup_attr,
579
71e3205925e6 Fix for augmented assignments to local variables. Thanks to Erik Bray for reporting the problem.
cmlenz
parents: 569
diff changeset
298 '_lookup_item': cls.lookup_item,
731
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 719
diff changeset
299 '_star_import_patch': _star_import_patch,
691
be6890ff84fe Minor cleanup in eval module.
cmlenz
parents: 684
diff changeset
300 'UndefinedError': UndefinedError,
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
301 }
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
302
822
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 806
diff changeset
303 @classmethod
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
304 def lookup_name(cls, data, name):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
305 __traceback_hide__ = True
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
306 val = data.get(name, UNDEFINED)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
307 if val is UNDEFINED:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
308 val = BUILTINS.get(name, val)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
309 if val is UNDEFINED:
569
4cbd8031ed76 Attribute access in template expressions no longer silently ignores exceptions other than `AttributeError` raised in the attribute accessor.
cmlenz
parents: 568
diff changeset
310 val = cls.undefined(name)
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
311 return val
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
312
822
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 806
diff changeset
313 @classmethod
691
be6890ff84fe Minor cleanup in eval module.
cmlenz
parents: 684
diff changeset
314 def lookup_attr(cls, obj, key):
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
315 __traceback_hide__ = True
702
ebae1774d188 Improve error reporting when accessing an attribute in a Python expression raises an `AttributeError`. Closes #191. Thanks to Michele Cella for the patch!
cmlenz
parents: 691
diff changeset
316 try:
ebae1774d188 Improve error reporting when accessing an attribute in a Python expression raises an `AttributeError`. Closes #191. Thanks to Michele Cella for the patch!
cmlenz
parents: 691
diff changeset
317 val = getattr(obj, key)
ebae1774d188 Improve error reporting when accessing an attribute in a Python expression raises an `AttributeError`. Closes #191. Thanks to Michele Cella for the patch!
cmlenz
parents: 691
diff changeset
318 except AttributeError:
ebae1774d188 Improve error reporting when accessing an attribute in a Python expression raises an `AttributeError`. Closes #191. Thanks to Michele Cella for the patch!
cmlenz
parents: 691
diff changeset
319 if hasattr(obj.__class__, key):
ebae1774d188 Improve error reporting when accessing an attribute in a Python expression raises an `AttributeError`. Closes #191. Thanks to Michele Cella for the patch!
cmlenz
parents: 691
diff changeset
320 raise
ebae1774d188 Improve error reporting when accessing an attribute in a Python expression raises an `AttributeError`. Closes #191. Thanks to Michele Cella for the patch!
cmlenz
parents: 691
diff changeset
321 else:
ebae1774d188 Improve error reporting when accessing an attribute in a Python expression raises an `AttributeError`. Closes #191. Thanks to Michele Cella for the patch!
cmlenz
parents: 691
diff changeset
322 try:
ebae1774d188 Improve error reporting when accessing an attribute in a Python expression raises an `AttributeError`. Closes #191. Thanks to Michele Cella for the patch!
cmlenz
parents: 691
diff changeset
323 val = obj[key]
ebae1774d188 Improve error reporting when accessing an attribute in a Python expression raises an `AttributeError`. Closes #191. Thanks to Michele Cella for the patch!
cmlenz
parents: 691
diff changeset
324 except (KeyError, TypeError):
ebae1774d188 Improve error reporting when accessing an attribute in a Python expression raises an `AttributeError`. Closes #191. Thanks to Michele Cella for the patch!
cmlenz
parents: 691
diff changeset
325 val = cls.undefined(key, owner=obj)
569
4cbd8031ed76 Attribute access in template expressions no longer silently ignores exceptions other than `AttributeError` raised in the attribute accessor.
cmlenz
parents: 568
diff changeset
326 return val
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
327
822
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 806
diff changeset
328 @classmethod
691
be6890ff84fe Minor cleanup in eval module.
cmlenz
parents: 684
diff changeset
329 def lookup_item(cls, obj, key):
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
330 __traceback_hide__ = True
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
331 if len(key) == 1:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
332 key = key[0]
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
333 try:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
334 return obj[key]
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
335 except (AttributeError, KeyError, IndexError, TypeError), e:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
336 if isinstance(key, basestring):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
337 val = getattr(obj, key, UNDEFINED)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
338 if val is UNDEFINED:
569
4cbd8031ed76 Attribute access in template expressions no longer silently ignores exceptions other than `AttributeError` raised in the attribute accessor.
cmlenz
parents: 568
diff changeset
339 val = cls.undefined(key, owner=obj)
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
340 return val
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
341 raise
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
342
822
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 806
diff changeset
343 @classmethod
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
344 def undefined(cls, key, owner=UNDEFINED):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
345 """Can be overridden by subclasses to specify behavior when undefined
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
346 variables are accessed.
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
347
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
348 :param key: the name of the variable
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
349 :param owner: the owning object, if the variable is accessed as a member
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
350 """
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
351 raise NotImplementedError
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
352
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
353
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
354 class LenientLookup(LookupBase):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
355 """Default variable lookup mechanism for expressions.
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
356
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
357 When an undefined variable is referenced using this lookup style, the
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
358 reference evaluates to an instance of the `Undefined` class:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
359
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
360 >>> expr = Expression('nothing', lookup='lenient')
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
361 >>> undef = expr.evaluate({})
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
362 >>> undef
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
363 <Undefined 'nothing'>
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
364
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
365 The same will happen when a non-existing attribute or item is accessed on
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
366 an existing object:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
367
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
368 >>> expr = Expression('something.nil', lookup='lenient')
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
369 >>> expr.evaluate({'something': dict()})
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
370 <Undefined 'nil'>
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
371
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
372 See the documentation of the `Undefined` class for details on the behavior
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
373 of such objects.
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
374
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
375 :see: `StrictLookup`
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
376 """
822
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 806
diff changeset
377
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 806
diff changeset
378 @classmethod
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
379 def undefined(cls, key, owner=UNDEFINED):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
380 """Return an ``Undefined`` object."""
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
381 __traceback_hide__ = True
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
382 return Undefined(key, owner=owner)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
383
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
384
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
385 class StrictLookup(LookupBase):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
386 """Strict variable lookup mechanism for expressions.
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
387
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
388 Referencing an undefined variable using this lookup style will immediately
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
389 raise an ``UndefinedError``:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
390
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
391 >>> expr = Expression('nothing', lookup='strict')
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
392 >>> try:
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
393 ... expr.evaluate({})
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
394 ... except UndefinedError, e:
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
395 ... print e.msg
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
396 "nothing" not defined
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
397
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
398 The same happens when a non-existing attribute or item is accessed on an
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
399 existing object:
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
400
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
401 >>> expr = Expression('something.nil', lookup='strict')
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
402 >>> try:
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
403 ... expr.evaluate({'something': dict()})
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
404 ... except UndefinedError, e:
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
405 ... print e.msg
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
406 {} has no member named "nil"
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
407 """
822
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 806
diff changeset
408
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 806
diff changeset
409 @classmethod
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
410 def undefined(cls, key, owner=UNDEFINED):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
411 """Raise an ``UndefinedError`` immediately."""
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
412 __traceback_hide__ = True
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
413 raise UndefinedError(key, owner=owner)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
414
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
415
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
416 def _parse(source, mode='eval'):
601
9ae986bcba9a Simplify implementation of `py:with` directive by compiling to a `Suite`, instead of manually breaking up the statement and compiling each part to an `Expression`. Also, the first line of code in a `Suite` is now stored as the "function name" of the bytecode, so that it shows up in tracebacks.
cmlenz
parents: 586
diff changeset
417 source = source.strip()
9ae986bcba9a Simplify implementation of `py:with` directive by compiling to a `Suite`, instead of manually breaking up the statement and compiling each part to an `Expression`. Also, the first line of code in a `Suite` is now stored as the "function name" of the bytecode, so that it shows up in tracebacks.
cmlenz
parents: 586
diff changeset
418 if mode == 'exec':
9ae986bcba9a Simplify implementation of `py:with` directive by compiling to a `Suite`, instead of manually breaking up the statement and compiling each part to an `Expression`. Also, the first line of code in a `Suite` is now stored as the "function name" of the bytecode, so that it shows up in tracebacks.
cmlenz
parents: 586
diff changeset
419 lines = [line.expandtabs() for line in source.splitlines()]
716
fe05ebf91775 fix ticket [209] - make sure py:with is valid, and add a test to make sure empty py:for is invalid
aflett
parents: 715
diff changeset
420 if lines:
fe05ebf91775 fix ticket [209] - make sure py:with is valid, and add a test to make sure empty py:for is invalid
aflett
parents: 715
diff changeset
421 first = lines[0]
fe05ebf91775 fix ticket [209] - make sure py:with is valid, and add a test to make sure empty py:for is invalid
aflett
parents: 715
diff changeset
422 rest = dedent('\n'.join(lines[1:])).rstrip()
fe05ebf91775 fix ticket [209] - make sure py:with is valid, and add a test to make sure empty py:for is invalid
aflett
parents: 715
diff changeset
423 if first.rstrip().endswith(':') and not rest[0].isspace():
fe05ebf91775 fix ticket [209] - make sure py:with is valid, and add a test to make sure empty py:for is invalid
aflett
parents: 715
diff changeset
424 rest = '\n'.join([' %s' % line for line in rest.splitlines()])
fe05ebf91775 fix ticket [209] - make sure py:with is valid, and add a test to make sure empty py:for is invalid
aflett
parents: 715
diff changeset
425 source = '\n'.join([first, rest])
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
426 if isinstance(source, unicode):
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
427 source = (u'\ufeff' + source).encode('utf-8')
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
428 return parse(source, mode)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
429
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
430
604
6d1fa718794f Fix bug that slipped into [717]: the code of a `py:with` directive was not being compiled with AST transformations applied.
cmlenz
parents: 601
diff changeset
431 def _compile(node, source=None, mode='eval', filename=None, lineno=-1,
6d1fa718794f Fix bug that slipped into [717]: the code of a `py:with` directive was not being compiled with AST transformations applied.
cmlenz
parents: 601
diff changeset
432 xform=None):
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
433 if not filename:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
434 filename = '<string>'
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
435 if IS_PYTHON2:
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
436 # Python 2 requires non-unicode filenames
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
437 if isinstance(filename, unicode):
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
438 filename = filename.encode('utf-8', 'replace')
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
439 else:
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
440 # Python 3 requires unicode filenames
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
441 if not isinstance(filename, unicode):
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
442 filename = filename.decode('utf-8', 'replace')
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
443 if lineno <= 0:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
444 lineno = 1
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
445
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
446 if xform is None:
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
447 xform = {
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
448 'eval': ExpressionASTTransformer
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
449 }.get(mode, TemplateASTTransformer)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
450 tree = xform().visit(node)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
451
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
452 if mode == 'eval':
601
9ae986bcba9a Simplify implementation of `py:with` directive by compiling to a `Suite`, instead of manually breaking up the statement and compiling each part to an `Expression`. Also, the first line of code in a `Suite` is now stored as the "function name" of the bytecode, so that it shows up in tracebacks.
cmlenz
parents: 586
diff changeset
453 name = '<Expression %r>' % (source or '?')
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
454 else:
601
9ae986bcba9a Simplify implementation of `py:with` directive by compiling to a `Suite`, instead of manually breaking up the statement and compiling each part to an `Expression`. Also, the first line of code in a `Suite` is now stored as the "function name" of the bytecode, so that it shows up in tracebacks.
cmlenz
parents: 586
diff changeset
455 lines = source.splitlines()
716
fe05ebf91775 fix ticket [209] - make sure py:with is valid, and add a test to make sure empty py:for is invalid
aflett
parents: 715
diff changeset
456 if not lines:
fe05ebf91775 fix ticket [209] - make sure py:with is valid, and add a test to make sure empty py:for is invalid
aflett
parents: 715
diff changeset
457 extract = ''
fe05ebf91775 fix ticket [209] - make sure py:with is valid, and add a test to make sure empty py:for is invalid
aflett
parents: 715
diff changeset
458 else:
fe05ebf91775 fix ticket [209] - make sure py:with is valid, and add a test to make sure empty py:for is invalid
aflett
parents: 715
diff changeset
459 extract = lines[0]
601
9ae986bcba9a Simplify implementation of `py:with` directive by compiling to a `Suite`, instead of manually breaking up the statement and compiling each part to an `Expression`. Also, the first line of code in a `Suite` is now stored as the "function name" of the bytecode, so that it shows up in tracebacks.
cmlenz
parents: 586
diff changeset
460 if len(lines) > 1:
9ae986bcba9a Simplify implementation of `py:with` directive by compiling to a `Suite`, instead of manually breaking up the statement and compiling each part to an `Expression`. Also, the first line of code in a `Suite` is now stored as the "function name" of the bytecode, so that it shows up in tracebacks.
cmlenz
parents: 586
diff changeset
461 extract += ' ...'
9ae986bcba9a Simplify implementation of `py:with` directive by compiling to a `Suite`, instead of manually breaking up the statement and compiling each part to an `Expression`. Also, the first line of code in a `Suite` is now stored as the "function name" of the bytecode, so that it shows up in tracebacks.
cmlenz
parents: 586
diff changeset
462 name = '<Suite %r>' % (extract)
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
463 new_source = ASTCodeGenerator(tree).code
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
464 code = compile(new_source, filename, mode)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
465
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
466 try:
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
467 # We'd like to just set co_firstlineno, but it's readonly. So we need
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
468 # to clone the code object while adjusting the line number
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
469 return build_code_chunk(code, filename, name, lineno)
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
470 except RuntimeError:
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
471 return code
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
472
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
473
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
474 def _new(class_, *args, **kwargs):
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
475 ret = class_()
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
476 for attr, value in zip(ret._fields, args):
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
477 if attr in kwargs:
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
478 raise ValueError('Field set both in args and kwargs')
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
479 setattr(ret, attr, value)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
480 for attr, value in kwargs:
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
481 setattr(ret, attr, value)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
482 return ret
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
483
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
484
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
485 BUILTINS = __builtin__.__dict__.copy()
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
486 BUILTINS.update({'Markup': Markup, 'Undefined': Undefined})
563
80fb59bd2342 Built-in Python constants (such as `None`) in expressions are used directly instead of being looked up from the context.
cmlenz
parents: 473
diff changeset
487 CONSTANTS = frozenset(['False', 'True', 'None', 'NotImplemented', 'Ellipsis'])
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
488
564
b3b07279b86c Alias `__contains__` to `has_key` in `Context` class for code outside of Genshi that may expect that for some wild reason.
cmlenz
parents: 563
diff changeset
489
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
490 class TemplateASTTransformer(ASTTransformer):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
491 """Concrete AST transformer that implements the AST transformations needed
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
492 for code embedded in templates.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
493 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
494
357
c5684b65c9b7 Improve the way locals (in list comprehensions, lambdas and generator expressions) are handled in template expressions.
cmlenz
parents: 343
diff changeset
495 def __init__(self):
586
5413c9d95db1 Fixes for nonlocal variable access in code blocks, as well as nested function and class definitions.
cmlenz
parents: 582
diff changeset
496 self.locals = [CONSTANTS]
357
c5684b65c9b7 Improve the way locals (in list comprehensions, lambdas and generator expressions) are handled in template expressions.
cmlenz
parents: 343
diff changeset
497
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
498 def _extract_names(self, node):
806
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
499 names = set()
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
500 def _process(node):
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
501 if not IS_PYTHON2 and isinstance(node, _ast.arg):
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
502 names.add(node.arg)
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
503 if isinstance(node, _ast.Name):
806
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
504 names.add(node.id)
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
505 elif isinstance(node, _ast.alias):
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
506 names.add(node.asname or node.name)
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
507 elif isinstance(node, _ast.Tuple):
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
508 for elt in node.elts:
896
248d6671a7e1 Fix for infinite recursion when parsing argument names from tuples. Closes #383.
cmlenz
parents: 878
diff changeset
509 _process(elt)
806
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
510 if hasattr(node, 'args'):
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
511 for arg in node.args:
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
512 _process(arg)
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
513 if hasattr(node, 'vararg'):
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
514 names.add(node.vararg)
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
515 if hasattr(node, 'kwarg'):
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
516 names.add(node.kwarg)
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
517 elif hasattr(node, 'names'):
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
518 for elt in node.names:
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
519 _process(elt)
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
520 return names
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
521
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
522 def visit_Str(self, node):
917
bcaa91c42b97 add support for python 3 to genshi.template expression evaluator:
hodgestar
parents: 897
diff changeset
523 if not isinstance(node.s, unicode):
357
c5684b65c9b7 Improve the way locals (in list comprehensions, lambdas and generator expressions) are handled in template expressions.
cmlenz
parents: 343
diff changeset
524 try: # If the string is ASCII, return a `str` object
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
525 node.s.decode('ascii')
357
c5684b65c9b7 Improve the way locals (in list comprehensions, lambdas and generator expressions) are handled in template expressions.
cmlenz
parents: 343
diff changeset
526 except ValueError: # Otherwise return a `unicode` object
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
527 return _new(_ast.Str, node.s.decode('utf-8'))
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
528 return node
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
529
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
530 def visit_ClassDef(self, node):
586
5413c9d95db1 Fixes for nonlocal variable access in code blocks, as well as nested function and class definitions.
cmlenz
parents: 582
diff changeset
531 if len(self.locals) > 1:
5413c9d95db1 Fixes for nonlocal variable access in code blocks, as well as nested function and class definitions.
cmlenz
parents: 582
diff changeset
532 self.locals[-1].add(node.name)
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 401
diff changeset
533 self.locals.append(set())
565
aa8e85a4085e * The I18n extractor now handles gettext function calls that use non-string parameters as well as keyword arguments.
cmlenz
parents: 564
diff changeset
534 try:
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
535 return ASTTransformer.visit_ClassDef(self, node)
565
aa8e85a4085e * The I18n extractor now handles gettext function calls that use non-string parameters as well as keyword arguments.
cmlenz
parents: 564
diff changeset
536 finally:
aa8e85a4085e * The I18n extractor now handles gettext function calls that use non-string parameters as well as keyword arguments.
cmlenz
parents: 564
diff changeset
537 self.locals.pop()
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
538
806
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
539 def visit_Import(self, node):
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
540 if len(self.locals) > 1:
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
541 self.locals[-1].update(self._extract_names(node))
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
542 return ASTTransformer.visit_Import(self, node)
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
543
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
544 def visit_ImportFrom(self, node):
806
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
545 if [a.name for a in node.names] == ['*']:
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
546 if has_star_import_bug:
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
547 # This is a Python 2.4 bug. Only if we have a broken Python
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
548 # version do we need to apply this hack
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
549 node = _new(_ast.Expr, _new(_ast.Call,
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
550 _new(_ast.Name, '_star_import_patch'), [
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
551 _new(_ast.Name, '__data__'),
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
552 _new(_ast.Str, node.module)
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
553 ], (), ()))
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
554 return node
806
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
555 if len(self.locals) > 1:
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
556 self.locals[-1].update(self._extract_names(node))
9871e6ca89b0 Fix for import statements in function defs in template code blocks (#276).
cmlenz
parents: 803
diff changeset
557 return ASTTransformer.visit_ImportFrom(self, node)
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
558
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
559 def visit_FunctionDef(self, node):
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
560 if len(self.locals) > 1:
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
561 self.locals[-1].add(node.name)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
562
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
563 self.locals.append(self._extract_names(node.args))
565
aa8e85a4085e * The I18n extractor now handles gettext function calls that use non-string parameters as well as keyword arguments.
cmlenz
parents: 564
diff changeset
564 try:
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
565 return ASTTransformer.visit_FunctionDef(self, node)
565
aa8e85a4085e * The I18n extractor now handles gettext function calls that use non-string parameters as well as keyword arguments.
cmlenz
parents: 564
diff changeset
566 finally:
aa8e85a4085e * The I18n extractor now handles gettext function calls that use non-string parameters as well as keyword arguments.
cmlenz
parents: 564
diff changeset
567 self.locals.pop()
357
c5684b65c9b7 Improve the way locals (in list comprehensions, lambdas and generator expressions) are handled in template expressions.
cmlenz
parents: 343
diff changeset
568
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
569 # GeneratorExp(expr elt, comprehension* generators)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
570 def visit_GeneratorExp(self, node):
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
571 gens = []
845
9cabfbc4ac5c Fix nested list comprehensions & generator expressions (fixes #327)
mgood
parents: 822
diff changeset
572 for generator in node.generators:
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
573 # comprehension = (expr target, expr iter, expr* ifs)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
574 self.locals.append(set())
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
575 gen = _new(_ast.comprehension, self.visit(generator.target),
845
9cabfbc4ac5c Fix nested list comprehensions & generator expressions (fixes #327)
mgood
parents: 822
diff changeset
576 self.visit(generator.iter),
9cabfbc4ac5c Fix nested list comprehensions & generator expressions (fixes #327)
mgood
parents: 822
diff changeset
577 [self.visit(if_) for if_ in generator.ifs])
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
578 gens.append(gen)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
579
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
580 # use node.__class__ to make it reusable as ListComp
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
581 ret = _new(node.__class__, self.visit(node.elt), gens)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
582 #delete inserted locals
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
583 del self.locals[-len(node.generators):]
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
584 return ret
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
585
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
586 # ListComp(expr elt, comprehension* generators)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
587 visit_ListComp = visit_GeneratorExp
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
588
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
589 def visit_Lambda(self, node):
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
590 self.locals.append(self._extract_names(node.args))
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
591 try:
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
592 return ASTTransformer.visit_Lambda(self, node)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
593 finally:
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
594 self.locals.pop()
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
595
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
596 def visit_Name(self, node):
357
c5684b65c9b7 Improve the way locals (in list comprehensions, lambdas and generator expressions) are handled in template expressions.
cmlenz
parents: 343
diff changeset
597 # If the name refers to a local inside a lambda, list comprehension, or
c5684b65c9b7 Improve the way locals (in list comprehensions, lambdas and generator expressions) are handled in template expressions.
cmlenz
parents: 343
diff changeset
598 # generator expression, leave it alone
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
599 if isinstance(node.ctx, _ast.Load) and \
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
600 node.id not in flatten(self.locals):
586
5413c9d95db1 Fixes for nonlocal variable access in code blocks, as well as nested function and class definitions.
cmlenz
parents: 582
diff changeset
601 # Otherwise, translate the name ref into a context lookup
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
602 name = _new(_ast.Name, '_lookup_name', _ast.Load())
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
603 namearg = _new(_ast.Name, '__data__', _ast.Load())
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
604 strarg = _new(_ast.Str, node.id)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
605 node = _new(_ast.Call, name, [namearg, strarg], [])
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
606 elif isinstance(node.ctx, _ast.Store):
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
607 if len(self.locals) > 1:
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
608 self.locals[-1].add(node.id)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
609
586
5413c9d95db1 Fixes for nonlocal variable access in code blocks, as well as nested function and class definitions.
cmlenz
parents: 582
diff changeset
610 return node
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
611
473
5870bdf03fca Apply patch from #113, also closing #114.
cmlenz
parents: 442
diff changeset
612
5870bdf03fca Apply patch from #113, also closing #114.
cmlenz
parents: 442
diff changeset
613 class ExpressionASTTransformer(TemplateASTTransformer):
5870bdf03fca Apply patch from #113, also closing #114.
cmlenz
parents: 442
diff changeset
614 """Concrete AST transformer that implements the AST transformations needed
5870bdf03fca Apply patch from #113, also closing #114.
cmlenz
parents: 442
diff changeset
615 for code embedded in templates.
5870bdf03fca Apply patch from #113, also closing #114.
cmlenz
parents: 442
diff changeset
616 """
5870bdf03fca Apply patch from #113, also closing #114.
cmlenz
parents: 442
diff changeset
617
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
618 def visit_Attribute(self, node):
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
619 if not isinstance(node.ctx, _ast.Load):
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
620 return ASTTransformer.visit_Attribute(self, node)
473
5870bdf03fca Apply patch from #113, also closing #114.
cmlenz
parents: 442
diff changeset
621
794
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
622 func = _new(_ast.Name, '_lookup_attr', _ast.Load())
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
623 args = [self.visit(node.value), _new(_ast.Str, node.attr)]
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
624 return _new(_ast.Call, func, args, [])
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
625
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
626 def visit_Subscript(self, node):
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
627 if not isinstance(node.ctx, _ast.Load) or \
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
628 not isinstance(node.slice, _ast.Index):
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
629 return ASTTransformer.visit_Subscript(self, node)
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
630
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
631 func = _new(_ast.Name, '_lookup_item', _ast.Load())
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
632 args = [
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
633 self.visit(node.value),
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
634 _new(_ast.Tuple, (self.visit(node.slice.value),), _ast.Load())
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
635 ]
ada9d53ea751 Merged AST branch back into trunk. Most of this code was written by Marcin Kurczych for his Google Summer of Code 2008 project. The merge of this branch means that Genshi now uses the native `_ast` module on Python >= 2.5, and an emulation thereof on Python 2.4. This replaces the usage of the `compiler` package, which was deprecated in Python 2.6 and removed in Python 3.0. Another effect is that Genshi now runs on Google AppEngine (although performance is bad due to the lack of template caching).
cmlenz
parents: 793
diff changeset
636 return _new(_ast.Call, func, args, [])
Copyright (C) 2012-2017 Edgewall Software