From 9adf937e4d1564bf27aebd03716d60f3ea823538 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 29 Nov 2010 14:29:00 +0100 Subject: [PATCH] Updated documentation for operator intercepting --- docs/sandbox.rst | 50 ++++++++++++++++++++++++++++++++++++++++++- jinja2/environment.py | 3 ++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/docs/sandbox.rst b/docs/sandbox.rst index bb0ca9f..1302f18 100644 --- a/docs/sandbox.rst +++ b/docs/sandbox.rst @@ -14,11 +14,15 @@ Traceback (most recent call last): ... SecurityError: access to attribute 'func_code' of 'function' object is unsafe. +API +--- .. module:: jinja2.sandbox .. autoclass:: SandboxedEnvironment([options]) - :members: is_safe_attribute, is_safe_callable + :members: is_safe_attribute, is_safe_callable, default_binop_table, + default_unop_table, intercepted_binops, intercepted_unops, + call_binop, call_unop .. autoclass:: ImmutableSandboxedEnvironment([options]) @@ -44,3 +48,47 @@ SecurityError: access to attribute 'func_code' of 'function' object is unsafe. Also keep in mind that templates may raise runtime or compile time errors, so make sure to catch them. + +Operator Intercepting +--------------------- + +.. versionadded:: 2.6 + +For maximum performace Jinja2 will let operators call directly the type +specific callback methods. This means that it's not possible to have this +intercepted by overriding :meth:`Environment.call`. Furthermore a +conversion from operator to special method is not always directly possible +due to how operators work. For instance for divisions more than one +special method exist. + +With Jinja 2.6 there is now support for explicit operator intercepting. +This can be used to customize specific operators as necessary. In order +to intercept an operator one has to override the +:attr:`SandboxedEnvironment.intercepted_binops` attribute. Once the +operator that needs to be intercepted is added to that set Jinja2 will +generate bytecode that calls the :meth:`SandboxedEnvironment.call_binop` +function. For unary operators the `unary` attributes and methods have to +be used instead. + +The default implementation of :attr:`SandboxedEnvironment.call_binop` +will use the :attr:`SandboxedEnvironment.binop_table` to translate +operator symbols into callbacks performing the default operator behavior. + +This example shows how the power (``**``) operator can be disabled in +Jinja2:: + + from jinja2.sandbox import SandboxedEnvironment + + + class MyEnvironment(SandboxedEnvironment): + intercepted_binops = frozenset(['**']) + + def call_binop(self, context, operator, left, right): + if operator == '**': + return self.undefined('the power operator is unavailable') + return SandboxedEnvironment.call_binop(self, context, + operator, left, right) + +Make sure to always call into the super method, even if you are not +intercepting the call. Jinja2 might internally call the method to +evaluate expressions. diff --git a/jinja2/environment.py b/jinja2/environment.py index 2dd38ef..095329e 100644 --- a/jinja2/environment.py +++ b/jinja2/environment.py @@ -196,7 +196,8 @@ class Environment(object): #: if this environment is sandboxed. Modifying this variable won't make #: the environment sandboxed though. For a real sandboxed environment - #: have a look at jinja2.sandbox + #: have a look at jinja2.sandbox. This flag alone controls the code + #: generation by the compiler. sandboxed = False #: True if the environment is just an overlay -- 2.26.2