Skip to content

Commit

Permalink
Updated documentation for operator intercepting
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Nov 29, 2010
1 parent a919538 commit 9adf937
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
50 changes: 49 additions & 1 deletion docs/sandbox.rst
Expand Up @@ -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])

Expand All @@ -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.
3 changes: 2 additions & 1 deletion jinja2/environment.py
Expand Up @@ -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
Expand Down

0 comments on commit 9adf937

Please sign in to comment.